]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arc/arc.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arc / arc.cc
1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2024 Free Software Foundation, Inc.
3
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
6
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)
11
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
14
15 This file is part of GCC.
16
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.
21
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.
26
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/>. */
30
31 #define IN_TARGET_CODE 1
32
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"
73
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;
77
78 typedef struct GTY (()) _arc_jli_section
79 {
80 const char *name;
81 struct _arc_jli_section *next;
82 } arc_jli_section;
83
84 static arc_jli_section *arc_jli_sections = NULL;
85
86 /* Track which regs are set fixed/call saved/call used from commnad line. */
87 HARD_REG_SET overrideregs;
88
89 /* Maximum size of a loop. */
90 #define ARC_MAX_LOOP_LENGTH 4095
91
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)))
100
101 /* Array of valid operand punctuation characters. */
102 char arc_punct_chars[256];
103
104 /* Status of the IRQ_CTRL_AUX register. */
105 typedef struct irq_ctrl_saved_t
106 {
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;
115
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))
121
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))
127
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)))
132
133 /* Number of registers in second bank for FIRQ support. */
134 static int rgf_banked_register_count;
135
136 /* Start enter/leave register range. */
137 #define ENTER_LEAVE_START_REG 13
138
139 /* End enter/leave register range. */
140 #define ENTER_LEAVE_END_REG 26
141
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
160
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
167 o
168 this to be no less than the 1/p */
169 #define MAX_INSNS_SKIPPED 3
170
171 /* ZOL control registers. */
172 #define AUX_LP_START 0x02
173 #define AUX_LP_END 0x03
174
175 /* FPX AUX registers. */
176 #define AUX_DPFP_START 0x301
177
178 /* ARC600 MULHI register. */
179 #define AUX_MULHI 0x12
180
181 static int get_arc_condition_code (rtx);
182
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 *);
189
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);
197
198 static void arc_init_builtins (void);
199 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
200
201 static int branch_dest (rtx);
202
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);
208
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);
212
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 *);
216
217 static void output_short_suffix (FILE *file);
218
219 static bool arc_frame_pointer_required (void);
220
221 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
222 unsigned int,
223 enum by_pieces_operation op,
224 bool);
225
226 /* Globally visible information about currently selected cpu. */
227 const arc_cpu_t *arc_selected_cpu;
228
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.
237
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.
246
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. */
261
262 /* ARCompact stack frames look like:
263
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 +-----------------------+
295 | |
296 | reg save area |
297 | |
298 +-----------------------+
299 | frame pointer |
300 | (if required) |
301 FP +-----------------------+
302 | |
303 | local/temp variables |
304 | |
305 +-----------------------+
306 | |
307 | arguments on stack |
308 low | |
309 mem SP +-----------------------+
310
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). */
315
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
319 {
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;
331 };
332
333 /* GMASK bit length -1. */
334 #define GMASK_LEN 63
335
336 /* Defining data structures for per-function information. */
337
338 typedef struct GTY (()) machine_function
339 {
340 unsigned int fn_type;
341 struct arc_frame_info frame_info;
342 char arc_reorg_started;
343 char prescan_initialized;
344 } machine_function;
345
346
347 /* Given a symbol RTX (const (symb <+ const_int>), returns its
348 alignment. */
349
350 static int
351 get_symbol_alignment (rtx x)
352 {
353 tree decl = NULL_TREE;
354 int align = 0;
355
356 switch (GET_CODE (x))
357 {
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;
368 }
369
370 if (decl)
371 align = DECL_ALIGN (decl);
372 align = align / BITS_PER_UNIT;
373 return align;
374 }
375
376 /* Return true if x is ok to be used as a small data address. */
377
378 static bool
379 legitimate_small_data_address_p (rtx x, machine_mode mode)
380 {
381 switch (GET_CODE (x))
382 {
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:
388 {
389 bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
390 && SYMBOL_REF_SMALL_P (XEXP (x, 0));
391
392 /* If no constant then we cannot do small data. */
393 if (!CONST_INT_P (XEXP (x, 1)))
394 return false;
395
396 /* Small data relocs works with scalled addresses, check if
397 the immediate fits the requirements. */
398 switch (GET_MODE_SIZE (mode))
399 {
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;
409 }
410 }
411 default:
412 return false;
413 }
414 }
415
416 /* TRUE if op is an scaled address. */
417 static bool
418 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
419 {
420 if (GET_CODE (op) != PLUS)
421 return false;
422
423 if (GET_CODE (XEXP (op, 0)) != MULT)
424 return false;
425
426 /* Check multiplication operands. */
427 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
428 return false;
429
430 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
431 return false;
432
433 switch (GET_MODE_SIZE (mode))
434 {
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;
449 }
450
451 /* Check the base. */
452 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
453 return true;
454
455 if (flag_pic)
456 {
457 if (CONST_INT_P (XEXP (op, 1)))
458 return true;
459 return false;
460 }
461
462 /* Scalled addresses for sdata is done other places. */
463 if (legitimate_small_data_address_p (op, mode))
464 return false;
465
466 if (CONSTANT_P (XEXP (op, 1)))
467 return true;
468
469 return false;
470 }
471
472 /* Check for constructions like REG + OFFS, where OFFS can be a
473 register, an immediate or an long immediate. */
474
475 static bool
476 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
477 {
478 if (GET_CODE (x) != PLUS)
479 return false;
480
481 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
482 return false;
483
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;
489
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;
499
500 return false;
501 }
502
503 /* Implements target hook vector_mode_supported_p. */
504
505 static bool
506 arc_vector_mode_supported_p (machine_mode mode)
507 {
508 switch (mode)
509 {
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;
518
519 default:
520 return false;
521 }
522 }
523
524 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
525
526 static machine_mode
527 arc_preferred_simd_mode (scalar_mode mode)
528 {
529 switch (mode)
530 {
531 case E_HImode:
532 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
533 case E_SImode:
534 return V2SImode;
535
536 default:
537 return word_mode;
538 }
539 }
540
541 /* Implements target hook
542 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
543
544 static unsigned int
545 arc_autovectorize_vector_modes (vector_modes *modes, bool)
546 {
547 if (TARGET_PLUS_QMACW)
548 {
549 modes->quick_push (V4HImode);
550 modes->quick_push (V2HImode);
551 }
552 return 0;
553 }
554
555
556 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
557 static int
558 arc_sched_issue_rate (void)
559 {
560 switch (arc_tune)
561 {
562 case ARC_TUNE_ARCHS4X:
563 case ARC_TUNE_ARCHS4XD:
564 return 3;
565 default:
566 break;
567 }
568 return 1;
569 }
570
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);
576
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);
581
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
595
596 #undef TARGET_ENCODE_SECTION_INFO
597 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
598
599 #undef TARGET_CANNOT_FORCE_CONST_MEM
600 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
601
602 #undef TARGET_INIT_BUILTINS
603 #define TARGET_INIT_BUILTINS arc_init_builtins
604
605 #undef TARGET_EXPAND_BUILTIN
606 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
607
608 #undef TARGET_FOLD_BUILTIN
609 #define TARGET_FOLD_BUILTIN arc_fold_builtin
610
611 #undef TARGET_BUILTIN_DECL
612 #define TARGET_BUILTIN_DECL arc_builtin_decl
613
614 #undef TARGET_ASM_OUTPUT_MI_THUNK
615 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
616
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
619
620 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
621 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
622
623 #undef TARGET_MACHINE_DEPENDENT_REORG
624 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
625
626 #undef TARGET_IN_SMALL_DATA_P
627 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
628
629 #undef TARGET_PROMOTE_FUNCTION_MODE
630 #define TARGET_PROMOTE_FUNCTION_MODE \
631 default_promote_function_mode_always_promote
632
633 #undef TARGET_PROMOTE_PROTOTYPES
634 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
635
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
640
641 #undef TARGET_SETUP_INCOMING_VARARGS
642 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
643
644 #undef TARGET_ARG_PARTIAL_BYTES
645 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
646
647 #undef TARGET_MUST_PASS_IN_STACK
648 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
649
650 #undef TARGET_FUNCTION_VALUE
651 #define TARGET_FUNCTION_VALUE arc_function_value
652
653 #undef TARGET_SCHED_ADJUST_PRIORITY
654 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
655
656 #undef TARGET_SCHED_ISSUE_RATE
657 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
658
659 #undef TARGET_VECTOR_MODE_SUPPORTED_P
660 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
661
662 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
663 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
664
665 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
666 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES arc_autovectorize_vector_modes
667
668 #undef TARGET_CAN_USE_DOLOOP_P
669 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
670
671 #undef TARGET_INVALID_WITHIN_DOLOOP
672 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
673
674 #undef TARGET_PRESERVE_RELOAD_P
675 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
676
677 #undef TARGET_CAN_FOLLOW_JUMP
678 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
679
680 #undef TARGET_DELEGITIMIZE_ADDRESS
681 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
682
683 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
684 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
685 arc_use_by_pieces_infrastructure_p
686
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)
693
694 #undef TARGET_SECONDARY_RELOAD
695 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
696
697 #define TARGET_OPTION_OVERRIDE arc_override_options
698
699 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
700
701 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
702
703 #define TARGET_CAN_ELIMINATE arc_can_eliminate
704
705 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
706
707 #define TARGET_FUNCTION_ARG arc_function_arg
708
709 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
710
711 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
712
713 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
714
715 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
716
717 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
718
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
722
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
729
730 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
731 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
732
733 #undef TARGET_WARN_FUNC_RETURN
734 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
735
736 #include "target-def.h"
737
738 TARGET_GNU_ATTRIBUTES (arc_attribute_table,
739 {
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 }
772 });
773
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"
778
779 #ifdef HAVE_AS_TLS
780 #undef TARGET_HAVE_TLS
781 #define TARGET_HAVE_TLS HAVE_AS_TLS
782 #endif
783
784 #undef TARGET_DWARF_REGISTER_SPAN
785 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
786
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
791
792 #undef TARGET_MODES_TIEABLE_P
793 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
794
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. */
798
799 static int
800 arc_sched_adjust_priority (rtx_insn *insn, int priority)
801 {
802 rtx set = single_set (insn);
803 if (set
804 && GET_MODE (SET_SRC(set)) == DFmode
805 && GET_CODE (SET_SRC(set)) == REG)
806 {
807 /* Incrementing priority by 20 (empirically derived). */
808 return priority + 20;
809 }
810
811 return priority;
812 }
813
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. */
824
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)
831 {
832 enum rtx_code code = GET_CODE (x);
833
834 if (cl == DOUBLE_REGS)
835 return GENERAL_REGS;
836
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)
841 {
842 rtx addr = NULL_RTX;
843 x = SUBREG_REG (x);
844
845 if (REG_P (x))
846 {
847 int regno = REGNO (x);
848 if (regno >= FIRST_PSEUDO_REGISTER)
849 regno = reg_renumber[regno];
850
851 if (regno != -1)
852 return NO_REGS;
853
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)))
857 {
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));
862 }
863 }
864 else
865 {
866 gcc_assert (MEM_P (x));
867 addr = XEXP (x, 0);
868 addr = simplify_rtx (addr);
869 }
870 if (addr && GET_CODE (addr) == PLUS
871 && CONST_INT_P (XEXP (addr, 1))
872 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
873 {
874 switch (mode)
875 {
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;
886 }
887 }
888 }
889 return NO_REGS;
890 }
891
892 /* Convert reloads using offsets that are too large to use indirect
893 addressing. */
894
895 void
896 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
897 {
898 rtx addr;
899
900 gcc_assert (GET_CODE (mem) == MEM);
901 addr = XEXP (mem, 0);
902
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);
907
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));
913
914 return;
915 }
916
917 static unsigned arc_predicate_delay_insns (void);
918
919 namespace {
920
921 const pass_data pass_data_arc_predicate_delay_insns =
922 {
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 */
932 };
933
934 class pass_arc_predicate_delay_insns : public rtl_opt_pass
935 {
936 public:
937 pass_arc_predicate_delay_insns(gcc::context *ctxt)
938 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
939 {}
940
941 /* opt_pass methods: */
942 virtual unsigned int execute (function *)
943 {
944 return arc_predicate_delay_insns ();
945 }
946 virtual bool gate (function *)
947 {
948 return flag_delayed_branch;
949 }
950 };
951
952 } // anon namespace
953
954 rtl_opt_pass *
955 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
956 {
957 return new pass_arc_predicate_delay_insns (ctxt);
958 }
959
960 /* Called by OVERRIDE_OPTIONS to initialize various things. */
961
962 static void
963 arc_init (void)
964 {
965 if (TARGET_V2)
966 {
967 /* I have the multiplier, then use it*/
968 if (TARGET_MPYW || TARGET_MULTI)
969 arc_multcost = COSTS_N_INSNS (1);
970 }
971 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
972 if (arc_multcost < 0)
973 switch (arc_tune)
974 {
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)
991 {
992 arc_multcost = COSTS_N_INSNS (4);
993 break;
994 }
995 /* Fall through. */
996 default:
997 arc_multcost = COSTS_N_INSNS (30);
998 break;
999 }
1000
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");
1004
1005 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
1006 error ("%<-mno-dpfp-lrsr%> supported only with %<-mdpfp%>");
1007
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");
1012
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");
1016
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");
1021
1022 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
1023 if (flag_pic && TARGET_ARC600_FAMILY)
1024 {
1025 warning (0, "PIC is not supported for %qs",
1026 arc_cpu_string);
1027 flag_pic = 0;
1028 }
1029
1030 arc_init_reg_tables ();
1031
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;
1039 }
1040
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. */
1045
1046 static void
1047 irq_range (const char *cstr)
1048 {
1049 int i, first, last, blink, lpcount, xreg;
1050 char *str, *dash, *comma;
1051
1052 i = strlen (cstr);
1053 str = (char *) alloca (i + 1);
1054 memcpy (str, cstr, i + 1);
1055 blink = -1;
1056 lpcount = -1;
1057
1058 dash = strchr (str, '-');
1059 if (!dash)
1060 {
1061 warning (OPT_mirq_ctrl_saved_, "missing dash");
1062 return;
1063 }
1064 *dash = '\0';
1065
1066 comma = strchr (dash + 1, ',');
1067 if (comma)
1068 *comma = '\0';
1069
1070 first = decode_reg_name (str);
1071 if (first != 0)
1072 {
1073 warning (OPT_mirq_ctrl_saved_, "first register must be R0");
1074 return;
1075 }
1076
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);
1083
1084 if (last < 0)
1085 {
1086 warning (OPT_mirq_ctrl_saved_, "unknown register name: %s", dash + 1);
1087 return;
1088 }
1089
1090 if (!(last & 0x01))
1091 {
1092 warning (OPT_mirq_ctrl_saved_,
1093 "last register name %s must be an odd register", dash + 1);
1094 return;
1095 }
1096
1097 *dash = '-';
1098
1099 if (first > last)
1100 {
1101 warning (OPT_mirq_ctrl_saved_,
1102 "%s-%s is an empty range", str, dash + 1);
1103 return;
1104 }
1105
1106 while (comma)
1107 {
1108 *comma = ',';
1109 str = comma + 1;
1110
1111 comma = strchr (str, ',');
1112 if (comma)
1113 *comma = '\0';
1114
1115 xreg = decode_reg_name (str);
1116 switch (xreg)
1117 {
1118 case 31:
1119 blink = 31;
1120 break;
1121
1122 case 60:
1123 lpcount = 60;
1124 break;
1125
1126 default:
1127 warning (OPT_mirq_ctrl_saved_,
1128 "unknown register name: %s", str);
1129 return;
1130 }
1131 }
1132
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);
1136 }
1137
1138 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1139 8, 16, or 32. */
1140
1141 static void
1142 parse_mrgf_banked_regs_option (const char *arg)
1143 {
1144 long int val;
1145 char *end_ptr;
1146
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))
1151 {
1152 error ("invalid number in %<-mrgf-banked-regs=%s%> "
1153 "valid values are 0, 4, 8, 16, or 32", arg);
1154 return;
1155 }
1156 rgf_banked_register_count = (int) val;
1157 }
1158
1159 /* Check ARC options, generate derived target attributes. */
1160
1161 static void
1162 arc_override_options (void)
1163 {
1164 unsigned int i;
1165 cl_deferred_option *opt;
1166 vec<cl_deferred_option> *vopt
1167 = (vec<cl_deferred_option> *) arc_deferred_options;
1168
1169 if (arc_cpu == PROCESSOR_NONE)
1170 arc_cpu = TARGET_CPU_DEFAULT;
1171
1172 /* Set the default cpu options. */
1173 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
1174
1175 /* Set the architectures. */
1176 switch (arc_selected_cpu->arch_info->arch_id)
1177 {
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 ();
1195 }
1196
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;
1200
1201 rgf_banked_register_count = 0;
1202
1203 /* Handle the deferred options. */
1204 if (vopt)
1205 FOR_EACH_VEC_ELT (*vopt, i, opt)
1206 {
1207 switch (opt->opt_index)
1208 {
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;
1217
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;
1226
1227 default:
1228 gcc_unreachable();
1229 }
1230 }
1231
1232 CLEAR_HARD_REG_SET (overrideregs);
1233 if (common_deferred_options)
1234 {
1235 vec<cl_deferred_option> v =
1236 *((vec<cl_deferred_option> *) common_deferred_options);
1237 int reg, nregs, j;
1238
1239 FOR_EACH_VEC_ELT (v, i, opt)
1240 {
1241 switch (opt->opt_index)
1242 {
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;
1252 }
1253 }
1254 }
1255
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);
1289
1290 #include "arc-options.def"
1291
1292 #undef ARC_OPTX
1293 #undef ARC_OPT
1294
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);
1316
1317 #include "arc-options.def"
1318
1319 #undef ARC_OPTX
1320 #undef ARC_OPT
1321
1322 /* Set extras. */
1323 switch (arc_selected_cpu->extra)
1324 {
1325 case HAS_LPCOUNT_16:
1326 arc_lpcwidth = 16;
1327 break;
1328 default:
1329 break;
1330 }
1331
1332 /* Set Tune option. */
1333 if (arc_tune == ARC_TUNE_NONE)
1334 arc_tune = (enum arc_tune_attr) arc_selected_cpu->tune;
1335
1336 if (arc_size_opt_level == 3)
1337 optimize_size = 1;
1338
1339 if (TARGET_V2 && optimize_size && (ATTRIBUTE_PCS == 2))
1340 TARGET_CODE_DENSITY_FRAME = 1;
1341
1342 if (flag_pic)
1343 target_flags |= MASK_NO_SDATA_SET;
1344
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;
1348
1349 /* A7 has an issue with delay slots. */
1350 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
1351 flag_delayed_branch = 0;
1352
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;
1358
1359 /* Set unaligned to all HS cpus. */
1360 if (!OPTION_SET_P (unaligned_access) && TARGET_HS)
1361 unaligned_access = 1;
1362
1363 if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
1364 {
1365 TARGET_CODE_DENSITY_FRAME = 0;
1366 flag_delayed_branch = 0;
1367 }
1368
1369 /* These need to be done at start up. It's convenient to do them here. */
1370 arc_init ();
1371 }
1372
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[] =
1377 {
1378 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1379 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1380 };
1381
1382 enum arc_cc_code_index
1383 {
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
1388 };
1389
1390 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1391
1392 /* Returns the index of the ARC condition code string in
1393 `arc_condition_codes'. COMPARISON should be an rtx like
1394 `(eq (...) (...))'. */
1395
1396 static int
1397 get_arc_condition_code (rtx comparison)
1398 {
1399 switch (GET_MODE (XEXP (comparison, 0)))
1400 {
1401 case E_CCmode:
1402 case E_SImode: /* For BRcc. */
1403 switch (GET_CODE (comparison))
1404 {
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 ();
1416 }
1417 case E_CC_ZNmode:
1418 switch (GET_CODE (comparison))
1419 {
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 ();
1426 }
1427 case E_CC_Zmode:
1428 switch (GET_CODE (comparison))
1429 {
1430 case EQ : return ARC_CC_EQ;
1431 case NE : return ARC_CC_NE;
1432 default : gcc_unreachable ();
1433 }
1434 case E_CC_Cmode:
1435 switch (GET_CODE (comparison))
1436 {
1437 case LTU : return ARC_CC_C;
1438 case GEU : return ARC_CC_NC;
1439 default : gcc_unreachable ();
1440 }
1441 case E_CC_FP_GTmode:
1442 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1443 switch (GET_CODE (comparison))
1444 {
1445 case GT : return ARC_CC_N;
1446 case UNLE: return ARC_CC_P;
1447 default : gcc_unreachable ();
1448 }
1449 else
1450 switch (GET_CODE (comparison))
1451 {
1452 case GT : return ARC_CC_HI;
1453 case UNLE : return ARC_CC_LS;
1454 default : gcc_unreachable ();
1455 }
1456 case E_CC_FP_GEmode:
1457 /* Same for FPX and non-FPX. */
1458 switch (GET_CODE (comparison))
1459 {
1460 case GE : return ARC_CC_HS;
1461 case UNLT : return ARC_CC_LO;
1462 default : gcc_unreachable ();
1463 }
1464 case E_CC_FP_UNEQmode:
1465 switch (GET_CODE (comparison))
1466 {
1467 case UNEQ : return ARC_CC_EQ;
1468 case LTGT : return ARC_CC_NE;
1469 default : gcc_unreachable ();
1470 }
1471 case E_CC_FP_ORDmode:
1472 switch (GET_CODE (comparison))
1473 {
1474 case UNORDERED : return ARC_CC_C;
1475 case ORDERED : return ARC_CC_NC;
1476 default : gcc_unreachable ();
1477 }
1478 case E_CC_FPXmode:
1479 switch (GET_CODE (comparison))
1480 {
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 ();
1488 }
1489 case E_CC_FPUmode:
1490 case E_CC_FPUEmode:
1491 switch (GET_CODE (comparison))
1492 {
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 ();
1509 }
1510 case E_CC_FPU_UNEQmode:
1511 switch (GET_CODE (comparison))
1512 {
1513 case LTGT : return ARC_CC_NE;
1514 case UNEQ : return ARC_CC_EQ;
1515 default : gcc_unreachable ();
1516 }
1517 default : gcc_unreachable ();
1518 }
1519 /*NOTREACHED*/
1520 return (42);
1521 }
1522
1523 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1524
1525 bool
1526 arc_short_comparison_p (rtx comparison, int offset)
1527 {
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))
1531 {
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;
1539 }
1540 }
1541
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. */
1544
1545 machine_mode
1546 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1547 {
1548 machine_mode mode = GET_MODE (x);
1549 rtx x1;
1550
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;
1562
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;
1568
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;
1574
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;
1582
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;
1587
1588 if (TARGET_ARGONAUT_SET
1589 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1590 switch (op)
1591 {
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 ();
1599 }
1600 else if (TARGET_HARD_FLOAT
1601 && ((mode == SFmode && TARGET_FP_SP_BASE)
1602 || (mode == DFmode && TARGET_FP_DP_BASE)))
1603 switch (op)
1604 {
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;
1614
1615 case LT:
1616 case LE:
1617 case GT:
1618 case GE:
1619 return CC_FPUEmode;
1620
1621 case LTGT:
1622 case UNEQ:
1623 return CC_FPU_UNEQmode;
1624
1625 default:
1626 gcc_unreachable ();
1627 }
1628 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1629 {
1630 switch (op)
1631 {
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 ();
1640 }
1641 }
1642 return CCmode;
1643 }
1644
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. */
1649
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. */
1653
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
1659 };
1660
1661 /* Modes for condition codes. */
1662 #define C_MODES (1 << (int) C_MODE)
1663
1664 /* Modes for single-word and smaller quantities. */
1665 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1666
1667 /* Modes for double-word and smaller quantities. */
1668 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1669
1670 /* Mode for 8-byte DF values only. */
1671 #define DF_MODES (1 << DF_MODE)
1672
1673 /* Modes for quad-word and smaller quantities. */
1674 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1675
1676 /* Modes for 128-bit vectors. */
1677 #define V_MODES (1 << (int) V_MODE)
1678
1679 /* Value is 1 if register/mode pair is acceptable on arc. */
1680
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,
1686
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,
1692
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,
1697
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,
1702
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
1706 };
1707
1708 static unsigned int arc_mode_class [NUM_MACHINE_MODES];
1709
1710 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1711
1712 enum reg_class
1713 arc_preferred_reload_class (rtx, enum reg_class cl)
1714 {
1715 return cl;
1716 }
1717
1718 /* Initialize the arc_mode_class array. */
1719
1720 static void
1721 arc_init_reg_tables (void)
1722 {
1723 int i;
1724
1725 for (i = 0; i < NUM_MACHINE_MODES; i++)
1726 {
1727 machine_mode m = (machine_mode) i;
1728
1729 switch (GET_MODE_CLASS (m))
1730 {
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;
1778 }
1779 }
1780 }
1781
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";
1798
1799 static void
1800 arc_conditional_register_usage (void)
1801 {
1802 int regno;
1803 int i;
1804 int fix_start = 60, fix_end = 55;
1805
1806 if (TARGET_V2)
1807 {
1808 /* For ARCv2 the core register set is changed. */
1809 strcpy (rname29, "ilink");
1810 strcpy (rname30, "r30");
1811
1812 if (!TEST_HARD_REG_BIT (overrideregs, R30_REG))
1813 {
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;
1818
1819 arc_regno_reg_class[R30_REG] = GENERAL_REGS;
1820 }
1821 }
1822
1823 if (TARGET_MUL64_SET)
1824 {
1825 fix_start = R57_REG;
1826 fix_end = R59_REG;
1827
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");
1838 }
1839
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;
1846
1847 if (TARGET_MULMAC_32BY16_SET)
1848 {
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");
1853 }
1854 for (regno = fix_start; regno <= fix_end; regno++)
1855 {
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;
1859 }
1860
1861 /* Reduced configuration: don't use r4-r9, r16-r25. */
1862 if (TARGET_RF16)
1863 {
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;
1868 }
1869
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;
1875
1876 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1877 if (i < ILINK1_REG)
1878 {
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;
1883 }
1884 else if (i < LP_COUNT)
1885 arc_regno_reg_class[i] = GENERAL_REGS;
1886 else
1887 arc_regno_reg_class[i] = NO_REGS;
1888
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;
1893
1894 if (TARGET_DPFP)
1895 for (i = R40_REG; i < R44_REG; ++i)
1896 {
1897 arc_regno_reg_class[i] = DOUBLE_REGS;
1898 if (!TARGET_ARGONAUT_SET)
1899 CLEAR_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i);
1900 }
1901 else
1902 {
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;
1909
1910 fixed_regs[R40_REG] = 1;
1911 fixed_regs[R41_REG] = 1;
1912 fixed_regs[R42_REG] = 1;
1913 fixed_regs[R43_REG] = 1;
1914
1915 arc_hard_regno_modes[R40_REG] = 0;
1916 arc_hard_regno_modes[R42_REG] = 0;
1917 }
1918
1919 if (TARGET_SIMD_SET)
1920 {
1921 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1922 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
1923
1924 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1925 arc_regno_reg_class [i] = SIMD_VR_REGS;
1926
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);
1931
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;
1935 }
1936
1937 /* pc : r63 */
1938 arc_regno_reg_class[PCL_REG] = NO_REGS;
1939
1940 /*ARCV2 Accumulator. */
1941 if ((TARGET_V2
1942 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
1943 || TARGET_PLUS_DMPY)
1944 {
1945 arc_regno_reg_class[ACCL_REGNO] = GENERAL_REGS;
1946 arc_regno_reg_class[ACCH_REGNO] = GENERAL_REGS;
1947
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;
1953
1954 if (!fixed_regs[ACCH_REGNO] && !fixed_regs[ACCL_REGNO])
1955 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES;
1956 }
1957 }
1958
1959 /* Implement TARGET_HARD_REGNO_NREGS. */
1960
1961 static unsigned int
1962 arc_hard_regno_nregs (unsigned int regno, machine_mode mode)
1963 {
1964 if (GET_MODE_SIZE (mode) == 16
1965 && regno >= ARC_FIRST_SIMD_VR_REG
1966 && regno <= ARC_LAST_SIMD_VR_REG)
1967 return 1;
1968
1969 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
1970 }
1971
1972 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1973
1974 static bool
1975 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
1976 {
1977 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0;
1978 }
1979
1980 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1981
1982 static bool
1983 arc_modes_tieable_p (machine_mode mode1, machine_mode mode2)
1984 {
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);
1989 }
1990
1991 /* Handle an "interrupt" attribute; arguments as in
1992 struct attribute_spec.handler. */
1993
1994 static tree
1995 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
1996 bool *no_add_attrs)
1997 {
1998 gcc_assert (args);
1999
2000 tree value = TREE_VALUE (args);
2001
2002 if (TREE_CODE (value) != STRING_CST)
2003 {
2004 warning (OPT_Wattributes,
2005 "argument of %qE attribute is not a string constant",
2006 name);
2007 *no_add_attrs = true;
2008 }
2009 else if (!TARGET_V2
2010 && strcmp (TREE_STRING_POINTER (value), "ilink1")
2011 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
2012 {
2013 warning (OPT_Wattributes,
2014 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2015 name);
2016 *no_add_attrs = true;
2017 }
2018 else if (TARGET_V2
2019 && strcmp (TREE_STRING_POINTER (value), "ilink")
2020 && strcmp (TREE_STRING_POINTER (value), "firq"))
2021 {
2022 warning (OPT_Wattributes,
2023 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2024 name);
2025 *no_add_attrs = true;
2026 }
2027
2028 return NULL_TREE;
2029 }
2030
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)
2034 {
2035 if (TREE_CODE (*node) != FUNCTION_DECL)
2036 {
2037 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2038 name);
2039 *no_add_attrs = true;
2040 }
2041
2042 return NULL_TREE;
2043 }
2044
2045 /* Type of function DECL.
2046
2047 The result is cached. To reset the cache at the end of a function,
2048 call with DECL = NULL_TREE. */
2049
2050 static unsigned int
2051 arc_compute_function_type (struct function *fun)
2052 {
2053 tree attr, decl = fun->decl;
2054 unsigned int fn_type = fun->machine->fn_type;
2055
2056 if (fn_type != ARC_FUNCTION_UNKNOWN)
2057 return fn_type;
2058
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;
2064
2065 /* Now see if this is an interrupt handler. */
2066 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2067 if (attr != NULL_TREE)
2068 {
2069 tree value, args = TREE_VALUE (attr);
2070
2071 gcc_assert (list_length (args) == 1);
2072 value = TREE_VALUE (args);
2073 gcc_assert (TREE_CODE (value) == STRING_CST);
2074
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 ();
2084 }
2085
2086 return fun->machine->fn_type = fn_type;
2087 }
2088
2089 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2090
2091 static bool
2092 arc_allocate_stack_slots_for_args (void)
2093 {
2094 /* Naked functions should not allocate stack slots for arguments. */
2095 unsigned int fn_type = arc_compute_function_type (cfun);
2096
2097 return !ARC_NAKED_P(fn_type);
2098 }
2099
2100 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2101
2102 static bool
2103 arc_warn_func_return (tree decl)
2104 {
2105 struct function *func = DECL_STRUCT_FUNCTION (decl);
2106 unsigned int fn_type = arc_compute_function_type (func);
2107
2108 return !ARC_NAKED_P (fn_type);
2109 }
2110
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). */
2114
2115 static int
2116 arc_comp_type_attributes (const_tree type1,
2117 const_tree type2)
2118 {
2119 int l1, l2, m1, m2, s1, s2;
2120
2121 /* Check for mismatch of non-default calling convention. */
2122 if (TREE_CODE (type1) != FUNCTION_TYPE)
2123 return 1;
2124
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;
2132
2133 /* Only bother to check if an attribute is defined. */
2134 if (l1 | l2 | m1 | m2 | s1 | s2)
2135 {
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;
2139
2140 /* Disallow mixed attributes. */
2141 if (l1 + m1 + s1 > 1)
2142 return 0;
2143 }
2144
2145
2146 return 1;
2147 }
2148
2149 /* Misc. utilities. */
2150
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. */
2153
2154 rtx
2155 gen_compare_reg (rtx comparison, machine_mode omode)
2156 {
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;
2162
2163
2164 cmode = GET_MODE (x);
2165 if (cmode == VOIDmode)
2166 cmode = GET_MODE (y);
2167
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;
2172
2173 if (cmode != SImode && cmode != SFmode && cmode != DFmode)
2174 return NULL_RTX;
2175 if (cmode == SImode)
2176 {
2177 if (!register_operand (x, SImode))
2178 {
2179 if (register_operand (y, SImode))
2180 {
2181 tmp = x;
2182 x = y;
2183 y = tmp;
2184 code = swap_condition (code);
2185 }
2186 else
2187 x = copy_to_mode_reg (SImode, x);
2188 }
2189 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
2190 y = copy_to_mode_reg (SImode, y);
2191 }
2192 else
2193 {
2194 x = force_reg (cmode, x);
2195 y = force_reg (cmode, y);
2196 }
2197 mode = SELECT_CC_MODE (code, x, y);
2198
2199 cc_reg = gen_rtx_REG (mode, CC_REG);
2200
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
2204 */
2205 if (TARGET_ARGONAUT_SET
2206 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2207 {
2208 switch (code)
2209 {
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 ();
2221 }
2222 if (cmode == SFmode)
2223 {
2224 emit_insn (gen_cmpsfpx_raw (x, y));
2225 }
2226 else /* DFmode */
2227 {
2228 /* Accepts Dx regs directly by insns. */
2229 emit_insn (gen_cmpdfpx_raw (x, y));
2230 }
2231
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)));
2237 }
2238 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2239 {
2240 switch (code)
2241 {
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 ();
2253 }
2254
2255 emit_insn (gen_cmp_quark (cc_reg,
2256 gen_rtx_COMPARE (mode, x, y)));
2257 }
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)
2263 {
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;
2267
2268 switch (code)
2269 {
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 ();
2279 }
2280 if (currently_expanding_to_rtl)
2281 {
2282 if (swap)
2283 {
2284 tmp = x;
2285 x = y;
2286 y = tmp;
2287 }
2288 emit_move_insn (op0, x);
2289 emit_move_insn (op1, y);
2290 }
2291 else
2292 {
2293 gcc_assert (rtx_equal_p (op0, x));
2294 gcc_assert (rtx_equal_p (op1, y));
2295 if (swap)
2296 {
2297 op0 = y;
2298 op1 = x;
2299 }
2300 }
2301 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2302 }
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);
2306 }
2307
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. */
2310
2311 bool
2312 arc_double_limm_p (rtx value)
2313 {
2314 HOST_WIDE_INT low, high;
2315
2316 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2317
2318 if (TARGET_DPFP)
2319 return true;
2320
2321 low = CONST_DOUBLE_LOW (value);
2322 high = CONST_DOUBLE_HIGH (value);
2323
2324 if (low & 0x80000000)
2325 {
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));
2330 }
2331 else
2332 {
2333 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2334 }
2335 }
2336
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.
2340
2341 CUM has not been updated for the last named argument (which is given
2342 by ARG), and we rely on this fact. */
2343
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)
2348 {
2349 int first_anon_arg;
2350 CUMULATIVE_ARGS next_cum;
2351
2352 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2353
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;
2358
2359 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2360 {
2361 /* First anonymous (unnamed) argument is in a reg. */
2362
2363 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2364 int first_reg_offset = first_anon_arg;
2365
2366 if (!no_rtl)
2367 {
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);
2373 }
2374
2375 *pretend_size
2376 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2377 }
2378 }
2379
2380 /* Return TRUE if reg is ok for short instrcutions. */
2381
2382 static bool
2383 arc_check_short_reg_p (rtx op)
2384 {
2385 if (!REG_P (op))
2386 return false;
2387
2388 if (IN_RANGE (REGNO (op) ^ 4, 4, 11))
2389 return true;
2390
2391 return false;
2392 }
2393
2394 /* Cost functions. */
2395
2396 /* Provide the costs of an addressing mode that contains ADDR.
2397 If ADDR is not a valid address, its cost is irrelevant. */
2398
2399 static int
2400 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2401 {
2402 switch (GET_CODE (addr))
2403 {
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;
2409
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);
2417
2418 case PLUS :
2419 {
2420 rtx plus0 = XEXP (addr, 0);
2421 rtx plus1 = XEXP (addr, 1);
2422
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;
2429
2430 switch (GET_CODE (plus1))
2431 {
2432 case CONST_INT :
2433 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2434 ? COSTS_N_INSNS (1)
2435 : speed
2436 ? 0
2437 : (arc_check_short_reg_p (plus0)
2438 && satisfies_constraint_O (plus1))
2439 ? 0
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;
2452 }
2453 break;
2454 }
2455 default:
2456 break;
2457 }
2458
2459 return 4;
2460 }
2461
2462 /* Emit instruction X with the frame related bit set. */
2463
2464 static rtx
2465 frame_insn (rtx x)
2466 {
2467 x = emit_insn (x);
2468 RTX_FRAME_RELATED_P (x) = 1;
2469 return x;
2470 }
2471
2472 /* Emit a frame insn to move SRC to DST. */
2473
2474 static rtx
2475 frame_move (rtx dst, rtx src)
2476 {
2477 rtx tmp = gen_rtx_SET (dst, src);
2478 RTX_FRAME_RELATED_P (tmp) = 1;
2479 return frame_insn (tmp);
2480 }
2481
2482 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2483 auto increment address, or is zero. */
2484
2485 static rtx
2486 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2487 {
2488 rtx insn = frame_move (dst, src);
2489
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;
2495 }
2496
2497 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2498
2499 static rtx
2500 frame_add (rtx reg, HOST_WIDE_INT offset)
2501 {
2502 gcc_assert ((offset & 0x3) == 0);
2503 if (!offset)
2504 return NULL_RTX;
2505 return frame_move (reg, plus_constant (Pmode, reg, offset));
2506 }
2507
2508 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2509
2510 static rtx
2511 frame_stack_add (HOST_WIDE_INT offset)
2512 {
2513 return frame_add (stack_pointer_rtx, offset);
2514 }
2515
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.
2520
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.
2524
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.
2529
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.
2537
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.
2545
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. */
2557
2558 static bool
2559 arc_frame_pointer_needed (void)
2560 {
2561 return (frame_pointer_needed || crtl->calls_eh_return);
2562 }
2563
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. */
2568
2569 static bool
2570 arc_must_save_register (int regno, struct function *func, bool special_p)
2571 {
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);
2576
2577 switch (rgf_banked_register_count)
2578 {
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;
2596 }
2597
2598 switch (regno)
2599 {
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;
2606
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;
2613
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. */
2624
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;
2655
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;
2669
2670 case 61:
2671 case 62:
2672 case 63:
2673 /* Fixed/control register, nothing to do. LP_COUNT is
2674 different. */
2675 return false;
2676
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;
2683
2684 default:
2685 break;
2686 }
2687
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;
2698 }
2699
2700 /* Return true if the return address must be saved in the current function,
2701 otherwise return false. */
2702
2703 static bool
2704 arc_must_save_return_addr (struct function *func)
2705 {
2706 if (func->machine->frame_info.save_return_addr)
2707 return true;
2708
2709 return false;
2710 }
2711
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. */
2718
2719 static int
2720 arc_compute_millicode_save_restore_regs (uint64_t gmask,
2721 struct arc_frame_info *frame)
2722 {
2723 int regno;
2724
2725 int start_reg = 13, end_reg = 25;
2726
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))
2734 {
2735 frame->millicode_start_reg = 13;
2736 frame->millicode_end_reg = regno - 1;
2737 return 1;
2738 }
2739 return 0;
2740 }
2741
2742 /* Return the bytes needed to compute the frame pointer from the
2743 current stack pointer. */
2744
2745 static unsigned int
2746 arc_compute_frame_size (void)
2747 {
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);
2757
2758 /* The answer might already be known. */
2759 if (cfun->machine->frame_info.initialized)
2760 return cfun->machine->frame_info.total_size;
2761
2762 frame_info = &cfun->machine->frame_info;
2763 size = ARC_STACK_ALIGN (get_frame_size ());
2764
2765 /* 1) Size of locals and temporaries. */
2766 var_size = size;
2767
2768 /* 2) Size of outgoing arguments. */
2769 args_size = crtl->outgoing_args_size;
2770
2771 /* 3) Calculate space needed for saved registers.
2772 ??? We ignore the extension registers for now. */
2773
2774 /* See if this is an interrupt handler. Call used registers must be saved
2775 for them too. */
2776
2777 reg_size = 0;
2778 gmask = 0;
2779
2780 /* The last 4 regs are special, avoid them. */
2781 for (regno = 0; regno <= (GMASK_LEN - 4); regno++)
2782 {
2783 if (arc_must_save_register (regno, cfun, false))
2784 {
2785 reg_size += UNITS_PER_WORD;
2786 gmask |= 1ULL << regno;
2787 }
2788 }
2789
2790 /* In a frame that calls __builtin_eh_return two data registers are
2791 used to pass values back to the exception handler.
2792
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++)
2799 {
2800 reg_size += UNITS_PER_WORD;
2801 gmask |= 1ULL << regno;
2802 }
2803
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);
2808
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)
2813 {
2814 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2815 frame_info->save_return_addr = true;
2816 }
2817
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;
2821
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;
2829
2830 /* Check if R58 is used. */
2831 if (arc_must_save_register (R58_REG, cfun, true))
2832 reg_size += UNITS_PER_WORD * 2;
2833
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;
2842
2843 /* 5) Space for variable arguments passed in registers */
2844 pretend_size = crtl->args.pretend_args_size;
2845
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;
2850
2851 /* Compute total frame size. */
2852 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2853
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));
2859
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;
2869
2870 /* Ok, we're done. */
2871 return total_size;
2872 }
2873
2874 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2875 mechanism. */
2876
2877 static void
2878 arc_dwarf_emit_irq_save_regs (void)
2879 {
2880 rtx tmp, par, insn, reg;
2881 int i, offset, j;
2882
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));
2888
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;
2898
2899 offset -= UNITS_PER_WORD;
2900
2901 /* 1st goes LP_COUNT. */
2902 if (irq_ctrl_saved.irq_save_lpcount)
2903 {
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;
2911 }
2912
2913 /* 2nd goes BLINK. */
2914 if (irq_ctrl_saved.irq_save_blink)
2915 {
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;
2923 }
2924
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--)
2928 {
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;
2936 }
2937
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;
2942 }
2943
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. */
2947
2948 static int
2949 frame_save_reg (rtx reg, HOST_WIDE_INT offset)
2950 {
2951 rtx addr;
2952
2953 if (offset)
2954 {
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));
2961 }
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);
2966
2967 return GET_MODE_SIZE (GET_MODE (reg)) - offset;
2968 }
2969
2970 /* Helper used when saving AUX regs during ISR. */
2971
2972 static int
2973 push_reg (rtx reg)
2974 {
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));
2984 }
2985
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. */
2989
2990 static int
2991 frame_restore_reg (rtx reg, HOST_WIDE_INT offset)
2992 {
2993 rtx addr, insn;
2994
2995 if (offset)
2996 {
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));
3003 }
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);
3009
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)));
3020
3021 return GET_MODE_SIZE (GET_MODE (reg)) + offset;
3022 }
3023
3024 /* Helper used when restoring AUX regs during ISR. */
3025
3026 static int
3027 pop_reg (rtx reg)
3028 {
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));
3038 }
3039
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. */
3043
3044 static bool
3045 arc_enter_leave_p (uint64_t gmask)
3046 {
3047 int regno;
3048 unsigned int rmask = 0;
3049
3050 if (!gmask)
3051 return false;
3052
3053 for (regno = ENTER_LEAVE_START_REG;
3054 regno <= ENTER_LEAVE_END_REG && (gmask & (1ULL << regno)); regno++)
3055 rmask |= 1ULL << regno;
3056
3057 if (rmask ^ gmask)
3058 return false;
3059
3060 return true;
3061 }
3062
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. */
3066
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)
3073 {
3074 rtx reg;
3075 int frame_allocated = 0;
3076 int i;
3077
3078 /* The home-grown ABI says link register is saved first. */
3079 if (save_blink)
3080 {
3081 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3082 frame_allocated += frame_save_reg (reg, offset);
3083 offset = 0;
3084 }
3085
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--)
3089 {
3090 machine_mode save_mode = SImode;
3091
3092 if (TARGET_LL64
3093 && ((i - 1) % 2 == 0)
3094 && ((gmask & (1ULL << i)) != 0)
3095 && ((gmask & (1ULL << (i - 1))) != 0))
3096 {
3097 save_mode = DImode;
3098 --i;
3099 }
3100 else if ((gmask & (1ULL << i)) == 0)
3101 continue;
3102
3103 reg = gen_rtx_REG (save_mode, i);
3104 frame_allocated += frame_save_reg (reg, offset);
3105 offset = 0;
3106 }
3107
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)
3113 {
3114 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3115 offset = 0;
3116 }
3117
3118 /* Emit mov fp,sp. */
3119 if (emit_move)
3120 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3121
3122 return frame_allocated;
3123 }
3124
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. */
3127
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)
3134 {
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;
3141
3142 /* Emit mov fp,sp. */
3143 if (arc_frame_pointer_needed () && offset)
3144 {
3145 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3146 frame_deallocated += offset;
3147 offset = 0;
3148 }
3149
3150 if (restore_fp)
3151 {
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);
3155 }
3156
3157 if (offset)
3158 {
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;
3164 }
3165
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)
3171 {
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;
3178 }
3179
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++)
3183 {
3184 machine_mode restore_mode = SImode;
3185
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;
3193
3194 reg = gen_rtx_REG (restore_mode, i);
3195 offs = 0;
3196 switch (restore_mode)
3197 {
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;
3210 }
3211 frame_deallocated += frame_restore_reg (reg, offs);
3212 offset = 0;
3213
3214 if (restore_mode == DImode)
3215 i++;
3216 }
3217
3218 if (restore_blink)
3219 {
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);
3227 }
3228
3229 return frame_deallocated;
3230 }
3231
3232 /* ARC prologue, save the registers using enter instruction. Leave
3233 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3234 register. */
3235
3236 static int
3237 arc_save_callee_enter (uint64_t gmask,
3238 bool save_blink,
3239 bool save_fp,
3240 HOST_WIDE_INT offset)
3241 {
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;
3247
3248 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3249 regno++;
3250
3251 end_reg = regno - 1;
3252 nregs = end_reg - start_reg + 1;
3253 nregs += save_blink ? 1 : 0;
3254 nregs += save_fp ? 1 : 0;
3255
3256 if (offset)
3257 frame_stack_add (offset);
3258
3259 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + (save_fp ? 1 : 0)
3260 + 1));
3261 indx = 0;
3262
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;
3270
3271 if (save_blink)
3272 {
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;
3281 }
3282
3283 for (regno = start_reg;
3284 regno <= end_reg;
3285 regno++, indx++, off -= UNITS_PER_WORD)
3286 {
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);
3294 }
3295
3296 if (save_fp)
3297 {
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;
3304
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;
3309 }
3310
3311 gcc_assert (off == 0);
3312 insn = frame_insn (insn);
3313
3314 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3315
3316 frame_allocated = nregs * UNITS_PER_WORD;
3317
3318 /* offset is a negative number, make sure we add it. */
3319 return frame_allocated - offset;
3320 }
3321
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). */
3326
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)
3333 {
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;
3339
3340 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3341 regno++;
3342
3343 end_reg = regno - 1;
3344 nregs = end_reg - start_reg + 1;
3345 nregs += restore_blink ? 1 : 0;
3346 nregs += restore_fp ? 1 : 0;
3347
3348 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1
3349 + (return_p ? 1 : 0)));
3350 indx = 0;
3351
3352 if (return_p)
3353 XVECEXP (insn, 0, indx++) = ret_rtx;
3354
3355 if (restore_fp)
3356 {
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;
3361 }
3362
3363 if (offset && !restore_fp)
3364 {
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;
3370 }
3371
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;
3379
3380 if (restore_blink)
3381 {
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;
3389 }
3390
3391 for (regno = start_reg;
3392 regno <= end_reg;
3393 regno++, indx++, off -= UNITS_PER_WORD)
3394 {
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);
3402 }
3403
3404 if (restore_fp)
3405 {
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;
3412 }
3413
3414 gcc_assert (off == 0);
3415 if (return_p)
3416 {
3417 insn = emit_jump_insn (insn);
3418 RTX_FRAME_RELATED_P (insn) = 1;
3419 }
3420 else
3421 insn = frame_insn (insn);
3422
3423 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3424
3425 /* Dwarf related info. */
3426 if (restore_fp)
3427 {
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));
3432 }
3433 else
3434 {
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)));
3439 }
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));
3445
3446 frame_allocated += nregs * UNITS_PER_WORD;
3447
3448 return frame_allocated;
3449 }
3450
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.
3459
3460 - Presently library only supports register ranges starting from r13.
3461 */
3462
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)
3469 {
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;
3475
3476 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3477 regno++;
3478
3479 end_reg = regno - 1;
3480 nregs = end_reg - start_reg + 1;
3481 gcc_assert (end_reg > 14);
3482
3483
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)
3488 {
3489 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3490 frame_allocated += frame_save_reg (reg, offset);
3491 offset = 0;
3492 }
3493
3494 if (reg_size || offset)
3495 {
3496 frame_stack_add (offset - reg_size);
3497 frame_allocated += nregs * UNITS_PER_WORD - offset;
3498 offset = 0;
3499 }
3500
3501 /* Start generate millicode call. */
3502 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
3503 indx = 0;
3504
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));
3508
3509 for (regno = start_reg, indx = 0, off = 0;
3510 regno <= end_reg;
3511 regno++, indx++, off += UNITS_PER_WORD)
3512 {
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);
3520 }
3521 insn = frame_insn (insn);
3522
3523 /* Add DWARF info. */
3524 for (regno = start_reg, off = 0;
3525 regno <= end_reg;
3526 regno++, off += UNITS_PER_WORD)
3527 {
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));
3532
3533 }
3534
3535 /* In the case of millicode thunk, we need to restore the
3536 clobbered blink register. */
3537 if (arc_must_save_return_addr (cfun))
3538 {
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))));
3544 }
3545
3546 /* Save remaining registers using st instructions. */
3547 for (regno = 0; regno <= GMASK_LEN; regno++)
3548 {
3549 if ((gmask & (1ULL << regno)) == 0)
3550 continue;
3551
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;
3559 }
3560
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);
3567
3568 /* Emit mov fp,sp. */
3569 if (arc_frame_pointer_needed ())
3570 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3571
3572 return frame_allocated;
3573 }
3574
3575 /* Like the previous function but restore. */
3576
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)
3583 {
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;
3589
3590 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3591 regno++;
3592
3593 end_reg = regno - 1;
3594 nregs = end_reg - start_reg + 1;
3595 gcc_assert (end_reg > 14);
3596
3597 /* Emit mov fp,sp. */
3598 if (arc_frame_pointer_needed () && offset)
3599 {
3600 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3601 frame_allocated = offset;
3602 offset = 0;
3603 }
3604
3605 if (restore_fp)
3606 frame_allocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3607
3608 if (offset)
3609 {
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;
3615 }
3616
3617 /* Start generate millicode call. */
3618 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc ((return_p ? 1 : 0)
3619 + nregs + 1));
3620 indx = 0;
3621
3622 if (return_p)
3623 {
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;
3632 }
3633 else
3634 {
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));
3638 }
3639
3640 for (regno = start_reg, off = 0;
3641 regno <= end_reg;
3642 regno++, indx++, off += UNITS_PER_WORD)
3643 {
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);
3651 }
3652
3653 /* Restore remaining registers using LD instructions. */
3654 for (regno = 0; regno <= GMASK_LEN; regno++)
3655 {
3656 if ((gmask & (1ULL << regno)) == 0)
3657 continue;
3658
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;
3666 }
3667
3668 /* Emit millicode call. */
3669 if (return_p)
3670 {
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;
3676 }
3677 else
3678 insn = frame_insn (insn);
3679
3680 /* Add DWARF info. */
3681 for (regno = start_reg; regno <= end_reg; regno++)
3682 {
3683 reg = gen_rtx_REG (SImode, regno);
3684 add_reg_note (insn, REG_CFA_RESTORE, reg);
3685
3686 }
3687
3688 if (restore_blink && !return_p)
3689 {
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);
3695 }
3696
3697 return frame_allocated;
3698 }
3699
3700 /* Set up the stack and frame pointer (if desired) for the function. */
3701
3702 void
3703 arc_expand_prologue (void)
3704 {
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;
3714
3715 /* Naked functions don't have prologue. */
3716 if (ARC_NAKED_P (fn_type))
3717 {
3718 if (flag_stack_usage_info)
3719 current_function_static_stack_size = 0;
3720 return;
3721 }
3722
3723 /* Compute total frame size. */
3724 size = arc_compute_frame_size ();
3725
3726 if (flag_stack_usage_info)
3727 current_function_static_stack_size = size;
3728
3729 /* Keep track of frame size to be allocated. */
3730 frame_size_to_allocate = size;
3731
3732 /* These cases shouldn't happen. Catch them now. */
3733 gcc_assert (!(size == 0 && gmask));
3734
3735 /* Allocate space for register arguments if this is a variadic function. */
3736 if (frame->pretend_size != 0)
3737 first_offset = -frame->pretend_size;
3738
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))
3743 {
3744 frame_stack_add (first_offset);
3745 first_offset = 0;
3746 arc_dwarf_emit_irq_save_regs ();
3747 }
3748
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);
3754
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);
3773
3774 /* Check if we need to save the ZOL machinery. */
3775 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
3776 {
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);
3790 }
3791
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))
3795 {
3796 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3797 int i;
3798
3799 for (i = 0; i < 4; i++)
3800 {
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);
3807 }
3808 }
3809
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);
3814
3815 if (arc_frame_pointer_needed () && ARC_INTERRUPT_P (fn_type))
3816 {
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);
3820 }
3821
3822 /* Allocate the stack frame. */
3823 if (frame_size_to_allocate > 0)
3824 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3825
3826 /* Emit a blockage to avoid delay slot scheduling. */
3827 emit_insn (gen_blockage ());
3828 }
3829
3830 /* Return the register number of the register holding the return address
3831 for a function of type TYPE. */
3832
3833 static int
3834 arc_return_address_register (unsigned int fn_type)
3835 {
3836 int regno = 0;
3837
3838 if (ARC_INTERRUPT_P (fn_type))
3839 {
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 ();
3846 }
3847 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
3848 regno = RETURN_ADDR_REGNUM;
3849
3850 gcc_assert (regno != 0);
3851 return regno;
3852 }
3853
3854 /* Do any necessary cleanup after a function to restore stack, frame,
3855 and regs. */
3856
3857 void
3858 arc_expand_epilogue (int sibcall_p)
3859 {
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;
3873
3874 /* Naked functions don't have epilogue. */
3875 if (ARC_NAKED_P (fn_type))
3876 return;
3877
3878 size = arc_compute_frame_size ();
3879 size_to_deallocate = size;
3880
3881 first_offset = size - (frame->pretend_size + frame->reg_size
3882 + frame->extra_size);
3883
3884 if (!can_trust_sp_p)
3885 gcc_assert (arc_frame_pointer_needed ());
3886
3887 /* Emit a blockage to avoid/flush all pending sp operations. */
3888 if (size)
3889 emit_insn (gen_blockage ());
3890
3891 if (ARC_INTERRUPT_P (fn_type))
3892 {
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;
3901 }
3902
3903 /* Restore accumulator registers. */
3904 if (arc_must_save_register (R58_REG, cfun, true))
3905 {
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);
3911
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;
3921 }
3922
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))
3926 {
3927 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3928 int i;
3929
3930 for (i = 0; i < 4; i++)
3931 {
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));
3937 }
3938 }
3939
3940 /* Check if we need to restore the ZOL machinery. */
3941 if (arc_lpcwidth !=0 && arc_must_save_register (LP_COUNT, cfun, true))
3942 {
3943 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3944
3945 size_to_deallocate -= pop_reg (reg0);
3946 emit_move_insn (gen_rtx_REG (SImode, LP_COUNT), reg0);
3947
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));
3952
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));
3957 }
3958
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))
3965 {
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)
3972 {
3973 gcc_assert (size_to_deallocate == 0);
3974 return;
3975 }
3976 }
3977 else if (frame->millicode_end_reg > 14)
3978 {
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)
3985 {
3986 gcc_assert (size_to_deallocate == 0);
3987 return;
3988 }
3989 }
3990 else
3991 size_to_deallocate -= arc_restore_callee_saves (gmask, restore_blink,
3992 restore_fp,
3993 first_offset,
3994 size_to_deallocate);
3995
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;
3999
4000 if (size > restored)
4001 frame_stack_add (size - restored);
4002
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.
4008
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));
4014
4015 /* Emit the return instruction. */
4016 if (ARC_INTERRUPT_P (fn_type))
4017 {
4018 rtx ra = gen_rtx_REG (Pmode, arc_return_address_register (fn_type));
4019
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));
4026 }
4027 else if (sibcall_p == FALSE)
4028 emit_jump_insn (gen_simple_return ());
4029 }
4030
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. */
4034
4035 bool
4036 arc_check_multi (rtx op, bool push_p)
4037 {
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;
4042
4043 if (len <= 1)
4044 return false;
4045
4046 start = 1;
4047 elt = XVECEXP (op, 0, 0);
4048 if (!push_p && GET_CODE (elt) == RETURN)
4049 start = 2;
4050
4051 for (i = start, regno = ENTER_LEAVE_START_REG; i < len; i++, regno++)
4052 {
4053 rtx elt = XVECEXP (op, 0, i);
4054 rtx reg, mem, addr;
4055
4056 if (GET_CODE (elt) != SET)
4057 return false;
4058 mem = XEXP (elt, memp);
4059 reg = XEXP (elt, 1 - memp);
4060
4061 if (!REG_P (reg)
4062 || !MEM_P (mem))
4063 return false;
4064
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;
4073
4074 addr = XEXP (mem, 0);
4075 if (GET_CODE (addr) == PLUS)
4076 {
4077 if (!rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
4078 || !CONST_INT_P (XEXP (addr, 1)))
4079 return false;
4080 }
4081 else
4082 {
4083 if (!rtx_equal_p (stack_pointer_rtx, addr))
4084 return false;
4085 }
4086 }
4087 return true;
4088 }
4089
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. */
4097
4098 void
4099 arc_eh_return_address_location (rtx source)
4100 {
4101 rtx mem;
4102 int offset;
4103 struct arc_frame_info *afi;
4104
4105 arc_compute_frame_size ();
4106 afi = &cfun->machine->frame_info;
4107
4108 gcc_assert (crtl->calls_eh_return);
4109 gcc_assert (afi->save_return_addr);
4110 gcc_assert (afi->extra_size >= 4);
4111
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));
4117
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);
4129 }
4130
4131 /* PIC */
4132
4133 /* Helper to generate unspec constant. */
4134
4135 static rtx
4136 arc_unspec_offset (rtx loc, int unspec)
4137 {
4138 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
4139 unspec));
4140 }
4141
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. */
4146
4147 bool
4148 arc_pre_reload_split (void)
4149 {
4150 return (can_create_pseudo_p ()
4151 && !(cfun->curr_properties & PROP_rtl_split_insns));
4152 }
4153
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]. */
4157
4158 const char *
4159 output_shift_loop (enum rtx_code code, rtx *operands)
4160 {
4161 bool twice_p = false;
4162 gcc_assert (GET_MODE (operands[0]) == SImode);
4163
4164 if (GET_CODE (operands[2]) != CONST_INT)
4165 {
4166 output_asm_insn ("and.f\tlp_count,%2,0x1f", operands);
4167 output_asm_insn ("lpnz\t2f", operands);
4168 }
4169 else
4170 {
4171 int n = INTVAL (operands[2]) & 31;
4172 if (!n)
4173 {
4174 output_asm_insn ("mov\t%0,%1",operands);
4175 return "";
4176 }
4177
4178 if ((n & 1) == 0 && code != ROTATE)
4179 {
4180 twice_p = true;
4181 n >>= 1;
4182 }
4183 operands[2] = GEN_INT (n);
4184 output_asm_insn ("mov\tlp_count,%2", operands);
4185 output_asm_insn ("lp\t2f", operands);
4186 }
4187
4188 switch (code)
4189 {
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 ();
4217 }
4218
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 "";
4223 }
4224
4225
4226 /* Split SImode left shift instruction. */
4227 void
4228 arc_split_ashl (rtx *operands)
4229 {
4230 if (CONST_INT_P (operands[2]))
4231 {
4232 int n = INTVAL (operands[2]) & 0x1f;
4233 if (n <= 9)
4234 {
4235 if (n == 0)
4236 emit_move_insn (operands[0], operands[1]);
4237 else if (n <= 2)
4238 {
4239 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
4240 if (n == 2)
4241 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
4242 }
4243 else
4244 {
4245 rtx zero = gen_reg_rtx (SImode);
4246 emit_move_insn (zero, const0_rtx);
4247 emit_insn (gen_add_shift (operands[0], operands[1],
4248 GEN_INT (3), zero));
4249 for (n -= 3; n >= 3; n -= 3)
4250 emit_insn (gen_add_shift (operands[0], operands[0],
4251 GEN_INT (3), zero));
4252 if (n == 2)
4253 emit_insn (gen_add_shift (operands[0], operands[0],
4254 const2_rtx, zero));
4255 else if (n)
4256 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
4257 }
4258 return;
4259 }
4260 else if (n >= 16 && n <= 22 && TARGET_SWAP && TARGET_V2)
4261 {
4262 emit_insn (gen_ashlsi2_cnt16 (operands[0], operands[1]));
4263 if (n > 16)
4264 {
4265 operands[1] = operands[0];
4266 operands[2] = GEN_INT (n - 16);
4267 arc_split_ashl (operands);
4268 }
4269 return;
4270 }
4271 else if (n >= 29)
4272 {
4273 if (n < 31)
4274 {
4275 if (n == 29)
4276 {
4277 emit_insn (gen_andsi3_i (operands[0], operands[1],
4278 GEN_INT (7)));
4279 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4280 }
4281 else
4282 emit_insn (gen_andsi3_i (operands[0], operands[1],
4283 GEN_INT (3)));
4284 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4285 }
4286 else
4287 emit_insn (gen_andsi3_i (operands[0], operands[1], const1_rtx));
4288 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4289 return;
4290 }
4291 }
4292
4293 emit_insn (gen_ashlsi3_loop (operands[0], operands[1], operands[2]));
4294 }
4295
4296 /* Split SImode arithmetic right shift instruction. */
4297 void
4298 arc_split_ashr (rtx *operands)
4299 {
4300 if (CONST_INT_P (operands[2]))
4301 {
4302 int n = INTVAL (operands[2]) & 0x1f;
4303 if (n <= 4)
4304 {
4305 if (n != 0)
4306 {
4307 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
4308 while (--n > 0)
4309 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
4310 }
4311 else
4312 emit_move_insn (operands[0], operands[1]);
4313 return;
4314 }
4315 else if (n >= 16 && n <= 18 && TARGET_SWAP)
4316 {
4317 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4318 emit_insn (gen_extendhisi2 (operands[0],
4319 gen_lowpart (HImode, operands[0])));
4320 while (--n >= 16)
4321 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
4322 return;
4323 }
4324 else if (n == 30)
4325 {
4326 rtx tmp = gen_reg_rtx (SImode);
4327 emit_insn (gen_add_f (tmp, operands[1], operands[1]));
4328 emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
4329 emit_insn (gen_addsi_compare_2 (tmp, tmp));
4330 emit_insn (gen_adc (operands[0], operands[0], operands[0]));
4331 return;
4332 }
4333 else if (n == 31)
4334 {
4335 emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
4336 emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
4337 return;
4338 }
4339 }
4340
4341 emit_insn (gen_ashrsi3_loop (operands[0], operands[1], operands[2]));
4342 }
4343
4344 /* Split SImode logical right shift instruction. */
4345 void
4346 arc_split_lshr (rtx *operands)
4347 {
4348 if (CONST_INT_P (operands[2]))
4349 {
4350 int n = INTVAL (operands[2]) & 0x1f;
4351 if (n <= 4)
4352 {
4353 if (n != 0)
4354 {
4355 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
4356 while (--n > 0)
4357 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
4358 }
4359 else
4360 emit_move_insn (operands[0], operands[1]);
4361 return;
4362 }
4363 else if (n >= 16 && n <= 19 && TARGET_SWAP && TARGET_V2)
4364 {
4365 emit_insn (gen_lshrsi2_cnt16 (operands[0], operands[1]));
4366 while (--n >= 16)
4367 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
4368 return;
4369 }
4370 else if (n == 30)
4371 {
4372 rtx tmp = gen_reg_rtx (SImode);
4373 emit_insn (gen_add_f (tmp, operands[1], operands[1]));
4374 emit_insn (gen_scc_ltu_cc_c (operands[0]));
4375 emit_insn (gen_addsi_compare_2 (tmp, tmp));
4376 emit_insn (gen_adc (operands[0], operands[0], operands[0]));
4377 return;
4378 }
4379 else if (n == 31)
4380 {
4381 emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
4382 emit_insn (gen_scc_ltu_cc_c (operands[0]));
4383 return;
4384 }
4385 }
4386
4387 emit_insn (gen_lshrsi3_loop (operands[0], operands[1], operands[2]));
4388 }
4389
4390 /* Split SImode rotate left instruction. */
4391 void
4392 arc_split_rotl (rtx *operands)
4393 {
4394 if (CONST_INT_P (operands[2]))
4395 {
4396 int n = INTVAL (operands[2]) & 0x1f;
4397 if (n <= 2)
4398 {
4399 if (n != 0)
4400 {
4401 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
4402 if (n == 2)
4403 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4404 }
4405 else
4406 emit_move_insn (operands[0], operands[1]);
4407 return;
4408 }
4409 else if (n >= 28)
4410 {
4411 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
4412 while (++n < 32)
4413 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4414 return;
4415 }
4416 else if (n >= 13 && n <= 16 && TARGET_SWAP)
4417 {
4418 emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
4419 while (++n <= 16)
4420 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4421 return;
4422 }
4423 else if (n == 17 && TARGET_SWAP)
4424 {
4425 emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
4426 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4427 return;
4428 }
4429 else if (n >= 16 || n == 12 || n == 14)
4430 {
4431 emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
4432 GEN_INT (32 - n)));
4433 return;
4434 }
4435 }
4436
4437 emit_insn (gen_rotlsi3_loop (operands[0], operands[1], operands[2]));
4438 }
4439
4440 /* Split SImode rotate right instruction. */
4441 void
4442 arc_split_rotr (rtx *operands)
4443 {
4444 if (CONST_INT_P (operands[2]))
4445 {
4446 int n = INTVAL (operands[2]) & 0x1f;
4447 if (n <= 4)
4448 {
4449 if (n != 0)
4450 {
4451 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
4452 while (--n > 0)
4453 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4454 }
4455 else
4456 emit_move_insn (operands[0], operands[1]);
4457 return;
4458 }
4459 else if (n == 15 && TARGET_SWAP)
4460 {
4461 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4462 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4463 return;
4464 }
4465 else if (n >= 16 && n <= 19 && TARGET_SWAP)
4466 {
4467 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4468 while (--n >= 16)
4469 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4470 return;
4471 }
4472 else if (n >= 30)
4473 {
4474 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
4475 if (n == 31)
4476 emit_insn (gen_rotlsi3_cnt1 (operands[1], operands[1]));
4477 return;
4478 }
4479 else if (n >= 21 || n == 17 || n == 19)
4480 {
4481 emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
4482 GEN_INT (32 - n)));
4483 return;
4484 }
4485 }
4486
4487 emit_insn (gen_rotrsi3_loop (operands[0], operands[1], operands[2]));
4488 }
4489 \f
4490 /* Nested function support. */
4491
4492 /* Output assembler code for a block containing the constant parts of
4493 a trampoline, leaving space for variable parts. A trampoline looks
4494 like this:
4495
4496 ld_s r12,[pcl,8]
4497 ld r11,[pcl,12]
4498 j_s [r12]
4499 .word function's address
4500 .word static chain value
4501
4502 */
4503
4504 static void
4505 arc_asm_trampoline_template (FILE *f)
4506 {
4507 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG);
4508 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]);
4509 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG);
4510 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4511 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4512 }
4513
4514 /* Emit RTL insns to initialize the variable parts of a trampoline.
4515 FNADDR is an RTX for the address of the function's pure code. CXT
4516 is an RTX for the static chain value for the function.
4517
4518 The fastest trampoline to execute for trampolines within +-8KB of CTX
4519 would be:
4520
4521 add2 r11,pcl,s12
4522 j [limm] 0x20200f80 limm
4523
4524 and that would also be faster to write to the stack by computing
4525 the offset from CTX to TRAMP at compile time. However, it would
4526 really be better to get rid of the high cost of cache invalidation
4527 when generating trampolines, which requires that the code part of
4528 trampolines stays constant, and additionally either making sure
4529 that no executable code but trampolines is on the stack, no icache
4530 entries linger for the area of the stack from when before the stack
4531 was allocated, and allocating trampolines in trampoline-only cache
4532 lines or allocate trampolines fram a special pool of pre-allocated
4533 trampolines. */
4534
4535 static void
4536 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
4537 {
4538 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
4539
4540 emit_block_move (tramp, assemble_trampoline_template (),
4541 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4542 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
4543 emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
4544 maybe_emit_call_builtin___clear_cache (XEXP (tramp, 0),
4545 plus_constant (Pmode,
4546 XEXP (tramp, 0),
4547 TRAMPOLINE_SIZE));
4548 }
4549
4550 /* Add the given function declaration to emit code in JLI section. */
4551
4552 static void
4553 arc_add_jli_section (rtx pat)
4554 {
4555 const char *name;
4556 tree attrs;
4557 arc_jli_section *sec = arc_jli_sections, *new_section;
4558 tree decl = SYMBOL_REF_DECL (pat);
4559
4560 if (!pat)
4561 return;
4562
4563 if (decl)
4564 {
4565 /* For fixed locations do not generate the jli table entry. It
4566 should be provided by the user as an asm file. */
4567 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
4568 if (lookup_attribute ("jli_fixed", attrs))
4569 return;
4570 }
4571
4572 name = XSTR (pat, 0);
4573
4574 /* Don't insert the same symbol twice. */
4575 while (sec != NULL)
4576 {
4577 if(strcmp (name, sec->name) == 0)
4578 return;
4579 sec = sec->next;
4580 }
4581
4582 /* New name, insert it. */
4583 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
4584 gcc_assert (new_section != NULL);
4585 new_section->name = name;
4586 new_section->next = arc_jli_sections;
4587 arc_jli_sections = new_section;
4588 }
4589
4590 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4591 reset when we output the scaled address. */
4592 static int output_scaled = 0;
4593
4594 /* Set when we force sdata output. */
4595 static int output_sdata = 0;
4596
4597 /* Print operand X (an rtx) in assembler syntax to file FILE.
4598 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4599 For `%' followed by punctuation, CODE is the punctuation and X is null.
4600 In final.cc:output_asm_insn:
4601 'l' : label
4602 'a' : address
4603 'c' : constant address if CONSTANT_ADDRESS_P
4604 'n' : negative
4605 Here:
4606 'Z': log2(x+1)-1
4607 'z': log2
4608 'M': log2(~x)
4609 'p': bit Position of lsb
4610 's': scalled immediate
4611 'S': Scalled immediate, to be used in pair with 's'.
4612 'N': Negative immediate, to be used in pair with 's'.
4613 'x': size of bit field
4614 '*': jump delay slot suffix
4615 '?' : nonjump-insn suffix for conditional execution or short instruction
4616 'd'
4617 'D'
4618 'R': Second word
4619 'J': JLI instruction
4620 'j': used by mov instruction to properly emit jli related labels.
4621 'B': Branch comparison operand - suppress sda reference
4622 'H': Most significant word
4623 'L': Least significant word
4624 'A': ASCII decimal representation of floating point value
4625 'U': Load/store update or scaling indicator
4626 'V': cache bypass indicator for volatile
4627 'P'
4628 'F'
4629 'O': Operator
4630 'o': original symbol - no @ prepending. */
4631
4632 void
4633 arc_print_operand (FILE *file, rtx x, int code)
4634 {
4635 HOST_WIDE_INT ival;
4636 unsigned scalled = 0;
4637 int sign = 1;
4638
4639 switch (code)
4640 {
4641 case 'Z':
4642 if (GET_CODE (x) == CONST_INT)
4643 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
4644 else
4645 output_operand_lossage ("invalid operand to %%Z code");
4646
4647 return;
4648
4649 case 'z':
4650 if (GET_CODE (x) == CONST_INT)
4651 fprintf (file, "%d",exact_log2 (INTVAL (x) & 0xffffffff));
4652 else
4653 output_operand_lossage ("invalid operand to %%z code");
4654
4655 return;
4656
4657 case 'c':
4658 if (GET_CODE (x) == CONST_INT)
4659 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) );
4660 else
4661 output_operand_lossage ("invalid operands to %%c code");
4662
4663 return;
4664
4665 case 'M':
4666 if (GET_CODE (x) == CONST_INT)
4667 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
4668 else
4669 output_operand_lossage ("invalid operand to %%M code");
4670
4671 return;
4672
4673 case 'p':
4674 if (GET_CODE (x) == CONST_INT)
4675 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
4676 else
4677 output_operand_lossage ("invalid operand to %%p code");
4678 return;
4679
4680 case 's':
4681 if (REG_P (x))
4682 return;
4683 if (!CONST_INT_P (x))
4684 {
4685 output_operand_lossage ("invalid operand for %%s code");
4686 return;
4687 }
4688 ival = INTVAL (x);
4689 if ((ival & 0x07) == 0)
4690 scalled = 3;
4691 else if ((ival & 0x03) == 0)
4692 scalled = 2;
4693 else if ((ival & 0x01) == 0)
4694 scalled = 1;
4695
4696 if (scalled)
4697 asm_fprintf (file, "%d", scalled);
4698 return;
4699
4700 case 'N':
4701 if (REG_P (x))
4702 {
4703 output_operand_lossage ("invalid operand for %%N code");
4704 return;
4705 }
4706 sign = -1;
4707 /* fall through */
4708 case 'S':
4709 if (REG_P (x))
4710 {
4711 asm_fprintf (file, "%s", reg_names [REGNO (x)]);
4712 return;
4713 }
4714 if (!CONST_INT_P (x))
4715 {
4716 output_operand_lossage ("invalid operand for %%N or %%S code");
4717 return;
4718 }
4719 ival = sign * INTVAL (x);
4720 if ((ival & 0x07) == 0)
4721 scalled = 3;
4722 else if ((ival & 0x03) == 0)
4723 scalled = 2;
4724 else if ((ival & 0x01) == 0)
4725 scalled = 1;
4726
4727 asm_fprintf (file, "%wd", (ival >> scalled));
4728 return;
4729
4730 case 'x':
4731 if (GET_CODE (x) == CONST_INT)
4732 {
4733 HOST_WIDE_INT i = INTVAL (x);
4734 HOST_WIDE_INT s = exact_log2 (i & -i);
4735 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
4736 }
4737 else
4738 output_operand_lossage ("invalid operand to %%s code");
4739 return;
4740
4741 case '*' :
4742 /* Unconditional branches / branches not depending on condition codes.
4743 This could also be a CALL_INSN.
4744 Output the appropriate delay slot suffix. */
4745 if (final_sequence && final_sequence->len () != 1)
4746 {
4747 rtx_insn *delay = final_sequence->insn (1);
4748
4749 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
4750 if (delay->deleted ())
4751 return;
4752 fputs (".d", file);
4753 }
4754 return;
4755
4756 case '?' : /* with leading "." */
4757 case '!' : /* without leading "." */
4758 if (current_insn_predicate)
4759 {
4760 int cc = get_arc_condition_code (current_insn_predicate);
4761 /* Is this insn in a delay slot sequence? */
4762 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
4763 || current_insn_predicate
4764 || CALL_P (final_sequence->insn (0))
4765 || simplejump_p (final_sequence->insn (0)))
4766 {
4767 /* This insn isn't in a delay slot sequence, or conditionalized
4768 independently of its position in a delay slot. */
4769 fprintf (file, "%s%s",
4770 code == '?' ? "." : "", arc_condition_codes[cc]);
4771 /* If this is a jump, there are still short variants. However,
4772 only beq_s / bne_s have the same offset range as b_s,
4773 and the only short conditional returns are jeq_s and jne_s. */
4774 if (code == '!'
4775 && (cc == ARC_CC_EQ || cc == ARC_CC_NE))
4776 output_short_suffix (file);
4777 }
4778 else if (code == '!') /* Jump with delay slot. */
4779 fputs (arc_condition_codes[cc], file);
4780 else /* An Instruction in a delay slot of a jump or call. */
4781 {
4782 rtx jump = XVECEXP (final_sequence, 0, 0);
4783 rtx insn = XVECEXP (final_sequence, 0, 1);
4784
4785 /* If the insn is annulled and is from the target path, we need
4786 to inverse the condition test. */
4787 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
4788 {
4789 if (INSN_FROM_TARGET_P (insn))
4790 fprintf (file, "%s%s",
4791 code == '?' ? "." : "",
4792 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (cc)]);
4793 else
4794 fprintf (file, "%s%s",
4795 code == '?' ? "." : "",
4796 arc_condition_codes[cc]);
4797 }
4798 else
4799 {
4800 /* This insn is executed for either path, so don't
4801 conditionalize it at all. */
4802 output_short_suffix (file);
4803 }
4804 }
4805 }
4806 else
4807 output_short_suffix (file);
4808 return;
4809
4810 case 'd' :
4811 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
4812 return;
4813 case 'D' :
4814 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
4815 (get_arc_condition_code (x))],
4816 file);
4817 return;
4818 case 'R' :
4819 /* Write second word of DImode or DFmode reference,
4820 register or memory. */
4821 if (GET_CODE (x) == REG)
4822 fputs (reg_names[REGNO (x)+1], file);
4823 else if (GET_CODE (x) == MEM)
4824 {
4825 fputc ('[', file);
4826
4827 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4828 PRE_MODIFY, we will have handled the first word already;
4829 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4830 first word will be done later. In either case, the access
4831 to the first word will do the modify, and we only have
4832 to add an offset of four here. */
4833 if (GET_CODE (XEXP (x, 0)) == PRE_INC
4834 || GET_CODE (XEXP (x, 0)) == PRE_DEC
4835 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
4836 || GET_CODE (XEXP (x, 0)) == POST_INC
4837 || GET_CODE (XEXP (x, 0)) == POST_DEC
4838 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
4839 output_address (VOIDmode,
4840 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
4841 else if (output_scaled)
4842 {
4843 rtx addr = XEXP (x, 0);
4844 int size = GET_MODE_SIZE (GET_MODE (x));
4845
4846 output_address (VOIDmode,
4847 plus_constant (Pmode, XEXP (addr, 0),
4848 ((INTVAL (XEXP (addr, 1)) + 4)
4849 >> (size == 2 ? 1 : 2))));
4850 output_scaled = 0;
4851 }
4852 else
4853 output_address (VOIDmode,
4854 plus_constant (Pmode, XEXP (x, 0), 4));
4855 fputc (']', file);
4856 }
4857 else
4858 output_operand_lossage ("invalid operand to %%R code");
4859 return;
4860 case 'j':
4861 case 'J' :
4862 if (GET_CODE (x) == SYMBOL_REF
4863 && arc_is_jli_call_p (x))
4864 {
4865 if (SYMBOL_REF_DECL (x))
4866 {
4867 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4868 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4869 : NULL_TREE);
4870 if (lookup_attribute ("jli_fixed", attrs))
4871 {
4872 /* No special treatment for jli_fixed functions. */
4873 if (code == 'j')
4874 break;
4875 fprintf (file, HOST_WIDE_INT_PRINT_DEC "\t; @",
4876 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4877 assemble_name (file, XSTR (x, 0));
4878 return;
4879 }
4880 }
4881 fprintf (file, "@__jli.");
4882 assemble_name (file, XSTR (x, 0));
4883 if (code == 'j')
4884 arc_add_jli_section (x);
4885 return;
4886 }
4887 if (GET_CODE (x) == SYMBOL_REF
4888 && arc_is_secure_call_p (x))
4889 {
4890 /* No special treatment for secure functions. */
4891 if (code == 'j' )
4892 break;
4893 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4894 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4895 : NULL_TREE);
4896 fprintf (file, HOST_WIDE_INT_PRINT_DEC "\t; @",
4897 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4898 assemble_name (file, XSTR (x, 0));
4899 return;
4900 }
4901 break;
4902 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4903 if (CONSTANT_P (x))
4904 {
4905 output_addr_const (file, x);
4906 return;
4907 }
4908 break;
4909 case 'H' :
4910 case 'L' :
4911 if (GET_CODE (x) == REG)
4912 {
4913 /* L = least significant word, H = most significant word. */
4914 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
4915 fputs (reg_names[REGNO (x)], file);
4916 else
4917 fputs (reg_names[REGNO (x)+1], file);
4918 }
4919 else if (GET_CODE (x) == CONST_INT
4920 || GET_CODE (x) == CONST_DOUBLE)
4921 {
4922 rtx first, second, word;
4923
4924 split_double (x, &first, &second);
4925
4926 if((WORDS_BIG_ENDIAN) == 0)
4927 word = (code == 'L' ? first : second);
4928 else
4929 word = (code == 'L' ? second : first);
4930
4931 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
4932 }
4933 else
4934 output_operand_lossage ("invalid operand to %%H/%%L code");
4935 return;
4936 case 'A' :
4937 {
4938 char str[30];
4939
4940 gcc_assert (GET_CODE (x) == CONST_DOUBLE
4941 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
4942
4943 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
4944 fprintf (file, "%s", str);
4945 return;
4946 }
4947 case 'U' :
4948 /* Output a load/store with update indicator if appropriate. */
4949 if (GET_CODE (x) == MEM)
4950 {
4951 rtx addr = XEXP (x, 0);
4952 switch (GET_CODE (addr))
4953 {
4954 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
4955 fputs (".a", file); break;
4956 case POST_INC: case POST_DEC: case POST_MODIFY:
4957 fputs (".ab", file); break;
4958 case PLUS:
4959 /* Are we using a scaled index? */
4960 if (GET_CODE (XEXP (addr, 0)) == MULT)
4961 fputs (".as", file);
4962 /* Can we use a scaled offset? */
4963 else if (CONST_INT_P (XEXP (addr, 1))
4964 && GET_MODE_SIZE (GET_MODE (x)) > 1
4965 && (!(INTVAL (XEXP (addr, 1))
4966 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
4967 /* Does it make a difference? */
4968 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
4969 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
4970 {
4971 fputs (".as", file);
4972 output_scaled = 1;
4973 }
4974 break;
4975 case SYMBOL_REF:
4976 case CONST:
4977 if (legitimate_small_data_address_p (addr, GET_MODE (x))
4978 && GET_MODE_SIZE (GET_MODE (x)) > 1)
4979 {
4980 int align = get_symbol_alignment (addr);
4981 int mask = 0;
4982 switch (GET_MODE (x))
4983 {
4984 case E_HImode:
4985 mask = 1;
4986 break;
4987 default:
4988 mask = 3;
4989 break;
4990 }
4991 if (align && ((align & mask) == 0))
4992 fputs (".as", file);
4993 }
4994 break;
4995 case REG:
4996 break;
4997 default:
4998 gcc_assert (CONSTANT_P (addr)); break;
4999 }
5000 }
5001 else
5002 output_operand_lossage ("invalid operand to %%U code");
5003 return;
5004 case 'V' :
5005 /* Output cache bypass indicator for a load/store insn. Volatile memory
5006 refs are defined to use the cache bypass mechanism. */
5007 if (GET_CODE (x) == MEM)
5008 {
5009 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
5010 || arc_is_uncached_mem_p (x))
5011 fputs (".di", file);
5012 }
5013 else
5014 output_operand_lossage ("invalid operand to %%V code");
5015 return;
5016 /* plt code. */
5017 case 'P':
5018 case 0 :
5019 /* Do nothing special. */
5020 break;
5021 case 'F':
5022 fputs (reg_names[REGNO (x)]+1, file);
5023 return;
5024
5025 case 'O':
5026 /* Output an operator. */
5027 switch (GET_CODE (x))
5028 {
5029 case PLUS: fputs ("add", file); return;
5030 case SS_PLUS: fputs ("adds", file); return;
5031 case AND: fputs ("and", file); return;
5032 case IOR: fputs ("or", file); return;
5033 case XOR: fputs ("xor", file); return;
5034 case MINUS: fputs ("sub", file); return;
5035 case SS_MINUS: fputs ("subs", file); return;
5036 case ASHIFT: fputs ("asl", file); return;
5037 case ASHIFTRT: fputs ("asr", file); return;
5038 case LSHIFTRT: fputs ("lsr", file); return;
5039 case ROTATERT: fputs ("ror", file); return;
5040 case MULT: fputs ("mpy", file); return;
5041 case ABS: fputs ("abs", file); return; /* Unconditional. */
5042 case NEG: fputs ("neg", file); return;
5043 case SS_NEG: fputs ("negs", file); return;
5044 case NOT: fputs ("not", file); return; /* Unconditional. */
5045 case ZERO_EXTEND:
5046 fputs ("ext", file); /* bmsk allows predication. */
5047 goto size_suffix;
5048 case SIGN_EXTEND: /* Unconditional. */
5049 fputs ("sex", file);
5050 size_suffix:
5051 switch (GET_MODE (XEXP (x, 0)))
5052 {
5053 case E_QImode: fputs ("b", file); return;
5054 case E_HImode: fputs ("w", file); return;
5055 default: break;
5056 }
5057 break;
5058 case SS_TRUNCATE:
5059 if (GET_MODE (x) != HImode)
5060 break;
5061 fputs ("sat16", file);
5062 default: break;
5063 }
5064 output_operand_lossage ("invalid operand to %%O code"); return;
5065 case 'o':
5066 if (GET_CODE (x) == SYMBOL_REF)
5067 {
5068 assemble_name (file, XSTR (x, 0));
5069 return;
5070 }
5071 break;
5072
5073 case '+':
5074 if (TARGET_V2)
5075 fputs ("m", file);
5076 else
5077 fputs ("h", file);
5078 return;
5079 case '_':
5080 if (TARGET_V2)
5081 fputs ("h", file);
5082 else
5083 fputs ("w", file);
5084 return;
5085 default :
5086 /* Unknown flag. */
5087 output_operand_lossage ("invalid operand output code");
5088 }
5089
5090 switch (GET_CODE (x))
5091 {
5092 case REG :
5093 fputs (reg_names[REGNO (x)], file);
5094 break;
5095 case MEM :
5096 {
5097 rtx addr = XEXP (x, 0);
5098 int size = GET_MODE_SIZE (GET_MODE (x));
5099
5100 if (legitimate_small_data_address_p (addr, GET_MODE (x)))
5101 output_sdata = 1;
5102
5103 fputc ('[', file);
5104
5105 switch (GET_CODE (addr))
5106 {
5107 case PRE_INC: case POST_INC:
5108 output_address (VOIDmode,
5109 plus_constant (Pmode, XEXP (addr, 0), size)); break;
5110 case PRE_DEC: case POST_DEC:
5111 output_address (VOIDmode,
5112 plus_constant (Pmode, XEXP (addr, 0), -size));
5113 break;
5114 case PRE_MODIFY: case POST_MODIFY:
5115 output_address (VOIDmode, XEXP (addr, 1)); break;
5116 case PLUS:
5117 if (output_scaled)
5118 {
5119 output_address (VOIDmode,
5120 plus_constant (Pmode, XEXP (addr, 0),
5121 (INTVAL (XEXP (addr, 1))
5122 >> (size == 2 ? 1 : 2))));
5123 output_scaled = 0;
5124 }
5125 else
5126 output_address (VOIDmode, addr);
5127 break;
5128 default:
5129 if (flag_pic && CONSTANT_ADDRESS_P (addr))
5130 arc_output_pic_addr_const (file, addr, code);
5131 else
5132 output_address (VOIDmode, addr);
5133 break;
5134 }
5135 fputc (']', file);
5136 break;
5137 }
5138 case CONST_DOUBLE :
5139 /* We handle SFmode constants here as output_addr_const doesn't. */
5140 if (GET_MODE (x) == SFmode)
5141 {
5142 long l;
5143
5144 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
5145 fprintf (file, "0x%08lx", l);
5146 break;
5147 }
5148 /* FALLTHRU */
5149 /* Let output_addr_const deal with it. */
5150 default :
5151 if (flag_pic
5152 || (GET_CODE (x) == CONST
5153 && GET_CODE (XEXP (x, 0)) == UNSPEC
5154 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
5155 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
5156 || (GET_CODE (x) == CONST
5157 && GET_CODE (XEXP (x, 0)) == PLUS
5158 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
5159 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
5160 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
5161 arc_output_pic_addr_const (file, x, code);
5162 else
5163 output_addr_const (file, x);
5164 break;
5165 }
5166 }
5167
5168 /* Print a memory address as an operand to reference that memory location. */
5169
5170 void
5171 arc_print_operand_address (FILE *file , rtx addr)
5172 {
5173 rtx base, index = 0;
5174
5175 switch (GET_CODE (addr))
5176 {
5177 case REG :
5178 fputs (reg_names[REGNO (addr)], file);
5179 break;
5180 case SYMBOL_REF:
5181 if (output_sdata)
5182 fputs ("gp,", file);
5183 output_addr_const (file, addr);
5184 if (output_sdata)
5185 fputs ("@sda", file);
5186 output_sdata = 0;
5187 break;
5188 case PLUS :
5189 if (GET_CODE (XEXP (addr, 0)) == MULT)
5190 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
5191 else if (CONST_INT_P (XEXP (addr, 0)))
5192 index = XEXP (addr, 0), base = XEXP (addr, 1);
5193 else
5194 base = XEXP (addr, 0), index = XEXP (addr, 1);
5195
5196 gcc_assert (OBJECT_P (base));
5197 arc_print_operand_address (file, base);
5198 if (CONSTANT_P (base) && CONST_INT_P (index))
5199 fputc ('+', file);
5200 else
5201 fputc (',', file);
5202 gcc_assert (OBJECT_P (index));
5203 arc_print_operand_address (file, index);
5204 break;
5205 case CONST:
5206 {
5207 rtx c = XEXP (addr, 0);
5208
5209 if ((GET_CODE (c) == UNSPEC
5210 && (XINT (c, 1) == UNSPEC_TLS_OFF
5211 || XINT (c, 1) == UNSPEC_TLS_IE))
5212 || (GET_CODE (c) == PLUS
5213 && GET_CODE (XEXP (c, 0)) == UNSPEC
5214 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
5215 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
5216 {
5217 arc_output_pic_addr_const (file, c, 0);
5218 break;
5219 }
5220 gcc_assert (GET_CODE (c) == PLUS);
5221 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
5222 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
5223
5224 output_address (VOIDmode, XEXP (addr, 0));
5225
5226 break;
5227 }
5228 case PRE_INC :
5229 case PRE_DEC :
5230 /* We shouldn't get here as we've lost the mode of the memory object
5231 (which says how much to inc/dec by. */
5232 gcc_unreachable ();
5233 break;
5234 default :
5235 if (flag_pic)
5236 arc_output_pic_addr_const (file, addr, 0);
5237 else
5238 output_addr_const (file, addr);
5239 break;
5240 }
5241 }
5242
5243 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5244 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5245 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5246
5247 static int
5248 arc_verify_short (rtx_insn *insn, int check_attr)
5249 {
5250 enum attr_iscompact iscompact;
5251
5252 if (check_attr > 0)
5253 {
5254 iscompact = get_attr_iscompact (insn);
5255 if (iscompact == ISCOMPACT_FALSE)
5256 return 0;
5257 }
5258
5259 return (get_attr_length (insn) & 2) != 0;
5260 }
5261
5262 /* When outputting an instruction (alternative) that can potentially be short,
5263 output the short suffix if the insn is in fact short. */
5264
5265 static void
5266 output_short_suffix (FILE *file)
5267 {
5268 rtx_insn *insn = current_output_insn;
5269 if (!insn)
5270 return;
5271
5272 if (arc_verify_short (insn, 1))
5273 {
5274 fprintf (file, "_s");
5275 }
5276 /* Restore recog_operand. */
5277 extract_insn_cached (insn);
5278 }
5279
5280 /* Implement FINAL_PRESCAN_INSN. */
5281
5282 void
5283 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
5284 int noperands ATTRIBUTE_UNUSED)
5285 {
5286 if (TARGET_DUMPISIZE)
5287 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
5288 }
5289
5290 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5291 Frame pointer elimination is automatically handled.
5292
5293 All eliminations are permissible. If we need a frame
5294 pointer, we must eliminate ARG_POINTER_REGNUM into
5295 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5296
5297 static bool
5298 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
5299 {
5300 return ((to == HARD_FRAME_POINTER_REGNUM) || (to == STACK_POINTER_REGNUM));
5301 }
5302
5303 /* Define the offset between two registers, one to be eliminated, and
5304 the other its replacement, at the start of a routine. */
5305
5306 int
5307 arc_initial_elimination_offset (int from, int to)
5308 {
5309 if (!cfun->machine->frame_info.initialized)
5310 arc_compute_frame_size ();
5311
5312 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
5313 {
5314 return (cfun->machine->frame_info.extra_size
5315 + cfun->machine->frame_info.reg_size);
5316 }
5317
5318 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
5319 {
5320 return (cfun->machine->frame_info.total_size
5321 - cfun->machine->frame_info.pretend_size);
5322 }
5323
5324 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
5325 {
5326 return (cfun->machine->frame_info.total_size
5327 - (cfun->machine->frame_info.pretend_size
5328 + cfun->machine->frame_info.extra_size
5329 + cfun->machine->frame_info.reg_size));
5330 }
5331 if ((from == FRAME_POINTER_REGNUM) && (to == HARD_FRAME_POINTER_REGNUM))
5332 return 0;
5333
5334 gcc_unreachable ();
5335 }
5336
5337 static bool
5338 arc_frame_pointer_required (void)
5339 {
5340 return cfun->calls_alloca || crtl->calls_eh_return;
5341 }
5342
5343
5344 /* Return the destination address of a branch. */
5345
5346 static int
5347 branch_dest (rtx branch)
5348 {
5349 rtx pat = PATTERN (branch);
5350 rtx dest = (GET_CODE (pat) == PARALLEL
5351 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
5352 int dest_uid;
5353
5354 if (GET_CODE (dest) == IF_THEN_ELSE)
5355 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
5356
5357 dest = XEXP (dest, 0);
5358 dest_uid = INSN_UID (dest);
5359
5360 return INSN_ADDRESSES (dest_uid);
5361 }
5362
5363
5364 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5365
5366 static void
5367 arc_encode_section_info (tree decl, rtx rtl, int first)
5368 {
5369 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5370 This clears machine specific flags, so has to come first. */
5371 default_encode_section_info (decl, rtl, first);
5372
5373 /* Check if it is a function, and whether it has the
5374 [long/medium/short]_call attribute specified. */
5375 if (TREE_CODE (decl) == FUNCTION_DECL)
5376 {
5377 rtx symbol = XEXP (rtl, 0);
5378 int flags = SYMBOL_REF_FLAGS (symbol);
5379
5380 tree attr = (TREE_TYPE (decl) != error_mark_node
5381 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
5382 tree long_call_attr = lookup_attribute ("long_call", attr);
5383 tree medium_call_attr = lookup_attribute ("medium_call", attr);
5384 tree short_call_attr = lookup_attribute ("short_call", attr);
5385
5386 if (long_call_attr != NULL_TREE)
5387 flags |= SYMBOL_FLAG_LONG_CALL;
5388 else if (medium_call_attr != NULL_TREE)
5389 flags |= SYMBOL_FLAG_MEDIUM_CALL;
5390 else if (short_call_attr != NULL_TREE)
5391 flags |= SYMBOL_FLAG_SHORT_CALL;
5392
5393 SYMBOL_REF_FLAGS (symbol) = flags;
5394 }
5395 else if (VAR_P (decl))
5396 {
5397 rtx symbol = XEXP (rtl, 0);
5398
5399 tree attr = (TREE_TYPE (decl) != error_mark_node
5400 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
5401
5402 tree sec_attr = lookup_attribute ("section", attr);
5403 if (sec_attr)
5404 {
5405 const char *sec_name
5406 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
5407 if (strcmp (sec_name, ".cmem") == 0
5408 || strcmp (sec_name, ".cmem_shared") == 0
5409 || strcmp (sec_name, ".cmem_private") == 0)
5410 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
5411 }
5412 }
5413 }
5414
5415 /* This is how to output a definition of an internal numbered label where
5416 PREFIX is the class of label and NUM is the number within the class. */
5417
5418 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
5419 {
5420 default_internal_label (stream, prefix, labelno);
5421 }
5422
5423 /* Set the cpu type and print out other fancy things,
5424 at the top of the file. */
5425
5426 static void arc_file_start (void)
5427 {
5428 default_file_start ();
5429 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
5430
5431 /* Set some want to have build attributes. */
5432 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5433 ATTRIBUTE_PCS);
5434 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5435 TARGET_RF16 ? 1 : 0);
5436 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5437 flag_pic ? 2 : 0);
5438 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5439 (arc_tp_regno != -1) ? 1 : 0);
5440 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5441 TARGET_NO_SDATA_SET ? 0 : 2);
5442 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5443 TARGET_OPTFPE ? 1 : 0);
5444 if (TARGET_V2)
5445 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5446 (arc_tune < ARC_TUNE_CORE_3) ? 2 :
5447 (arc_tune == ARC_TUNE_CORE_3 ? 3 : 4));
5448 }
5449
5450 /* Implement `TARGET_ASM_FILE_END'. */
5451 /* Outputs to the stdio stream FILE jli related text. */
5452
5453 void arc_file_end (void)
5454 {
5455 arc_jli_section *sec = arc_jli_sections;
5456
5457 while (sec != NULL)
5458 {
5459 fprintf (asm_out_file, "\n");
5460 fprintf (asm_out_file, "# JLI entry for function ");
5461 assemble_name (asm_out_file, sec->name);
5462 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
5463 ".jlitab.");
5464 assemble_name (asm_out_file, sec->name);
5465 fprintf (asm_out_file,", comdat\n");
5466
5467 fprintf (asm_out_file, "\t.align\t4\n");
5468 fprintf (asm_out_file, "__jli.");
5469 assemble_name (asm_out_file, sec->name);
5470 fprintf (asm_out_file, ":\n\t.weak __jli.");
5471 assemble_name (asm_out_file, sec->name);
5472 fprintf (asm_out_file, "\n\tb\t@");
5473 assemble_name (asm_out_file, sec->name);
5474 fprintf (asm_out_file, "\n");
5475 sec = sec->next;
5476 }
5477 file_end_indicate_exec_stack ();
5478 }
5479
5480 /* Cost functions. */
5481
5482 /* Compute a (partial) cost for rtx X. Return true if the complete
5483 cost has been computed, and false if subexpressions should be
5484 scanned. In either case, *TOTAL contains the cost result. */
5485
5486 static bool
5487 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
5488 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5489 {
5490 int code = GET_CODE (x);
5491
5492 switch (code)
5493 {
5494 /* Small integers are as cheap as registers. */
5495 case CONST_INT:
5496 {
5497 bool nolimm = false; /* Can we do without long immediate? */
5498
5499 nolimm = false;
5500 if (UNSIGNED_INT6 (INTVAL (x)))
5501 nolimm = true;
5502 else
5503 {
5504 switch (outer_code)
5505 {
5506 case AND: /* bclr, bmsk, ext[bw] */
5507 if (satisfies_constraint_Ccp (x) /* bclr */
5508 || satisfies_constraint_C1p (x) /* bmsk */)
5509 nolimm = true;
5510 break;
5511 case IOR: /* bset */
5512 if (satisfies_constraint_C0p (x)) /* bset */
5513 nolimm = true;
5514 break;
5515 case XOR:
5516 if (satisfies_constraint_C0p (x)) /* bxor */
5517 nolimm = true;
5518 break;
5519 case SET:
5520 if (UNSIGNED_INT8 (INTVAL (x)))
5521 nolimm = true;
5522 if (satisfies_constraint_Chi (x))
5523 nolimm = true;
5524 if (satisfies_constraint_Clo (x))
5525 nolimm = true;
5526 break;
5527 case MULT:
5528 if (TARGET_MUL64_SET)
5529 if (SIGNED_INT12 (INTVAL (x)))
5530 nolimm = true;
5531 break;
5532 default:
5533 break;
5534 }
5535 }
5536 if (nolimm)
5537 {
5538 *total = 0;
5539 return true;
5540 }
5541 }
5542 /* FALLTHRU */
5543
5544 /* 4 byte values can be fetched as immediate constants -
5545 let's give that the cost of an extra insn. */
5546 case CONST:
5547 case LABEL_REF:
5548 case SYMBOL_REF:
5549 *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
5550 return true;
5551
5552 case CONST_DOUBLE:
5553 {
5554 rtx first, second;
5555
5556 if (TARGET_DPFP)
5557 {
5558 *total = COSTS_N_INSNS (1);
5559 return true;
5560 }
5561 split_double (x, &first, &second);
5562 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
5563 + !SMALL_INT (INTVAL (second)));
5564 return true;
5565 }
5566
5567 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5568 If we need more than 12 insns to do a multiply, then go out-of-line,
5569 since the call overhead will be < 10% of the cost of the multiply. */
5570 case ASHIFT:
5571 case ASHIFTRT:
5572 case LSHIFTRT:
5573 case ROTATE:
5574 case ROTATERT:
5575 if (mode == DImode)
5576 return false;
5577 if (TARGET_BARREL_SHIFTER)
5578 {
5579 *total = COSTS_N_INSNS (1);
5580 if (CONSTANT_P (XEXP (x, 1)))
5581 {
5582 *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
5583 0, speed);
5584 return true;
5585 }
5586 }
5587 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5588 *total = speed ? COSTS_N_INSNS (16) : COSTS_N_INSNS (4);
5589 else
5590 {
5591 int n = INTVAL (XEXP (x, 1)) & 31;
5592 if (n < 4)
5593 *total = COSTS_N_INSNS (n);
5594 else
5595 *total = speed ? COSTS_N_INSNS (n + 2) : COSTS_N_INSNS (4);
5596 *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
5597 0, speed);
5598 return true;
5599 }
5600 return false;
5601
5602 case DIV:
5603 case UDIV:
5604 if (GET_MODE_CLASS (mode) == MODE_FLOAT
5605 && (TARGET_FP_SP_SQRT || TARGET_FP_DP_SQRT))
5606 *total = COSTS_N_INSNS(1);
5607 else if (GET_MODE_CLASS (mode) == MODE_INT
5608 && TARGET_DIVREM)
5609 *total = COSTS_N_INSNS(1);
5610 else if (speed)
5611 *total = COSTS_N_INSNS(30);
5612 else
5613 *total = COSTS_N_INSNS(1);
5614 return false;
5615
5616 case MULT:
5617 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5618 *total = COSTS_N_INSNS (1);
5619 else if (speed)
5620 *total= arc_multcost;
5621 /* We do not want synth_mult sequences when optimizing
5622 for size. */
5623 else if (TARGET_ANY_MPY)
5624 *total = COSTS_N_INSNS (1);
5625 else
5626 *total = COSTS_N_INSNS (2);
5627 return false;
5628
5629 case PLUS:
5630 if (mode == DImode)
5631 return false;
5632 if (outer_code == MEM && CONST_INT_P (XEXP (x, 1))
5633 && RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))
5634 {
5635 *total = 0;
5636 return true;
5637 }
5638
5639 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5640 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5641 || (GET_CODE (XEXP (x, 0)) == MULT
5642 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5643 {
5644 if (CONSTANT_P (XEXP (x, 1)) && !speed)
5645 *total += COSTS_N_INSNS (4);
5646 *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed);
5647 return true;
5648 }
5649 return false;
5650 case MINUS:
5651 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5652 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5653 || (GET_CODE (XEXP (x, 1)) == MULT
5654 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5655 {
5656 if (CONSTANT_P (XEXP (x, 0)) && !speed)
5657 *total += COSTS_N_INSNS (4);
5658 *total += rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed);
5659 return true;
5660 }
5661 return false;
5662
5663 case COMPARE:
5664 {
5665 rtx op0 = XEXP (x, 0);
5666 rtx op1 = XEXP (x, 1);
5667
5668 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5669 && XEXP (op0, 1) == const1_rtx)
5670 {
5671 /* btst / bbit0 / bbit1:
5672 Small integers and registers are free; everything else can
5673 be put in a register. */
5674 mode = GET_MODE (XEXP (op0, 0));
5675 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5676 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5677 return true;
5678 }
5679 if (GET_CODE (op0) == AND && op1 == const0_rtx
5680 && satisfies_constraint_C1p (XEXP (op0, 1)))
5681 {
5682 /* bmsk.f */
5683 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5684 return true;
5685 }
5686 /* add.f */
5687 if (GET_CODE (op1) == NEG)
5688 {
5689 /* op0 might be constant, the inside of op1 is rather
5690 unlikely to be so. So swapping the operands might lower
5691 the cost. */
5692 mode = GET_MODE (op0);
5693 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5694 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5695 }
5696 return false;
5697 }
5698 case EQ: case NE:
5699 if (outer_code == IF_THEN_ELSE
5700 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5701 && XEXP (x, 1) == const0_rtx
5702 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5703 {
5704 /* btst / bbit0 / bbit1:
5705 Small integers and registers are free; everything else can
5706 be put in a register. */
5707 rtx op0 = XEXP (x, 0);
5708
5709 mode = GET_MODE (XEXP (op0, 0));
5710 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5711 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5712 return true;
5713 }
5714 /* Fall through. */
5715 /* scc_insn expands into two insns. */
5716 case GTU: case GEU: case LEU:
5717 if (mode == SImode)
5718 *total += COSTS_N_INSNS (1);
5719 return false;
5720 case LTU: /* might use adc. */
5721 if (mode == SImode)
5722 *total += COSTS_N_INSNS (1) - 1;
5723 return false;
5724 default:
5725 return false;
5726 }
5727 }
5728
5729 /* Return true if ADDR is a valid pic address.
5730 A valid pic address on arc should look like
5731 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5732
5733 bool
5734 arc_legitimate_pic_addr_p (rtx addr)
5735 {
5736 if (GET_CODE (addr) != CONST)
5737 return false;
5738
5739 addr = XEXP (addr, 0);
5740
5741
5742 if (GET_CODE (addr) == PLUS)
5743 {
5744 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
5745 return false;
5746 addr = XEXP (addr, 0);
5747 }
5748
5749 if (GET_CODE (addr) != UNSPEC
5750 || XVECLEN (addr, 0) != 1)
5751 return false;
5752
5753 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5754 if (XINT (addr, 1) != ARC_UNSPEC_GOT
5755 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
5756 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
5757 && XINT (addr, 1) != UNSPEC_TLS_GD
5758 && XINT (addr, 1) != UNSPEC_TLS_IE)
5759 return false;
5760
5761 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
5762 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
5763 return false;
5764
5765 return true;
5766 }
5767
5768
5769
5770 /* Return true if OP contains a symbol reference. */
5771
5772 static bool
5773 symbolic_reference_mentioned_p (rtx op)
5774 {
5775 const char *fmt;
5776 int i;
5777
5778 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5779 return true;
5780
5781 fmt = GET_RTX_FORMAT (GET_CODE (op));
5782 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5783 {
5784 if (fmt[i] == 'E')
5785 {
5786 int j;
5787
5788 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5789 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5790 return true;
5791 }
5792
5793 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5794 return true;
5795 }
5796
5797 return false;
5798 }
5799
5800 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5801 If SKIP_LOCAL is true, skip symbols that bind locally.
5802 This is used further down in this file, and, without SKIP_LOCAL,
5803 in the addsi3 / subsi3 expanders when generating PIC code. */
5804
5805 bool
5806 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
5807 {
5808 const char *fmt;
5809 int i;
5810
5811 if (GET_CODE(op) == UNSPEC)
5812 return false;
5813
5814 if (GET_CODE (op) == SYMBOL_REF)
5815 {
5816 if (SYMBOL_REF_TLS_MODEL (op))
5817 return true;
5818 if (!flag_pic)
5819 return false;
5820 tree decl = SYMBOL_REF_DECL (op);
5821 return !skip_local || !decl || !default_binds_local_p (decl);
5822 }
5823
5824 fmt = GET_RTX_FORMAT (GET_CODE (op));
5825 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5826 {
5827 if (fmt[i] == 'E')
5828 {
5829 int j;
5830
5831 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5832 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
5833 skip_local))
5834 return true;
5835 }
5836
5837 else if (fmt[i] == 'e'
5838 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
5839 skip_local))
5840 return true;
5841 }
5842
5843 return false;
5844 }
5845
5846 /* The __tls_get_attr symbol. */
5847 static GTY(()) rtx arc_tls_symbol;
5848
5849 /* Emit a call to __tls_get_addr. TI is the argument to this function.
5850 RET is an RTX for the return value location. The entire insn sequence
5851 is returned. */
5852
5853 static rtx
5854 arc_call_tls_get_addr (rtx ti)
5855 {
5856 rtx arg = gen_rtx_REG (Pmode, R0_REG);
5857 rtx ret = gen_rtx_REG (Pmode, R0_REG);
5858 rtx fn;
5859 rtx_insn *insn;
5860
5861 if (!arc_tls_symbol)
5862 arc_tls_symbol = init_one_libfunc ("__tls_get_addr");
5863
5864 emit_move_insn (arg, ti);
5865 fn = gen_rtx_MEM (SImode, arc_tls_symbol);
5866 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
5867 RTL_CONST_CALL_P (insn) = 1;
5868 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
5869 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
5870
5871 return ret;
5872 }
5873
5874 /* Return a legitimized address for ADDR,
5875 which is a SYMBOL_REF with tls_model MODEL. */
5876
5877 static rtx
5878 arc_legitimize_tls_address (rtx addr, enum tls_model model)
5879 {
5880 rtx tmp;
5881
5882 /* The TP pointer needs to be set. */
5883 gcc_assert (arc_tp_regno != -1);
5884
5885 switch (model)
5886 {
5887 case TLS_MODEL_GLOBAL_DYNAMIC:
5888 case TLS_MODEL_LOCAL_DYNAMIC:
5889 tmp = gen_reg_rtx (Pmode);
5890 emit_move_insn (tmp, arc_unspec_offset (addr, UNSPEC_TLS_GD));
5891 return arc_call_tls_get_addr (tmp);
5892
5893 case TLS_MODEL_INITIAL_EXEC:
5894 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
5895 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
5896 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
5897
5898 case TLS_MODEL_LOCAL_EXEC:
5899 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
5900 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
5901
5902 default:
5903 gcc_unreachable ();
5904 }
5905 }
5906
5907 /* Return true if SYMBOL_REF X binds locally. */
5908
5909 static bool
5910 arc_symbol_binds_local_p (const_rtx x)
5911 {
5912 return (SYMBOL_REF_DECL (x)
5913 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
5914 : SYMBOL_REF_LOCAL_P (x));
5915 }
5916
5917 /* Legitimize a pic address reference in ADDR. The return value is
5918 the legitimated address. */
5919
5920 static rtx
5921 arc_legitimize_pic_address (rtx addr)
5922 {
5923 if (!flag_pic)
5924 return addr;
5925
5926 switch (GET_CODE (addr))
5927 {
5928 case UNSPEC:
5929 /* Can be one or our GOT or GOTOFFPC unspecs. This situation
5930 happens when an address is not a legitimate constant and we
5931 need the resolve it via force_reg in
5932 prepare_move_operands. */
5933 switch (XINT (addr, 1))
5934 {
5935 case ARC_UNSPEC_GOT:
5936 case ARC_UNSPEC_GOTOFFPC:
5937 /* Recover the symbol ref. */
5938 addr = XVECEXP (addr, 0, 0);
5939 break;
5940 default:
5941 return addr;
5942 }
5943 /* Fall through. */
5944 case SYMBOL_REF:
5945 /* TLS symbols are handled in different place. */
5946 if (SYMBOL_REF_TLS_MODEL (addr))
5947 return addr;
5948
5949 /* This symbol must be referenced via a load from the Global
5950 Offset Table (@GOTPC). */
5951 if (!arc_symbol_binds_local_p (addr))
5952 return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT));
5953
5954 /* Local symb: use @pcl to access it. */
5955 /* Fall through. */
5956 case LABEL_REF:
5957 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
5958
5959 default:
5960 break;
5961 }
5962
5963 return addr;
5964 }
5965
5966 /* Output address constant X to FILE, taking PIC into account. */
5967
5968 static void
5969 arc_output_pic_addr_const (FILE * file, rtx x, int code)
5970 {
5971 char buf[256];
5972
5973 restart:
5974 switch (GET_CODE (x))
5975 {
5976 case PC:
5977 if (flag_pic)
5978 putc ('.', file);
5979 else
5980 gcc_unreachable ();
5981 break;
5982
5983 case SYMBOL_REF:
5984 output_addr_const (file, x);
5985
5986 /* Local functions do not get references through the PLT. */
5987 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
5988 fputs ("@plt", file);
5989 break;
5990
5991 case LABEL_REF:
5992 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
5993 assemble_name (file, buf);
5994 break;
5995
5996 case CODE_LABEL:
5997 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
5998 assemble_name (file, buf);
5999 break;
6000
6001 case CONST_INT:
6002 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
6003 break;
6004
6005 case CONST:
6006 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6007 break;
6008
6009 case CONST_DOUBLE:
6010 if (GET_MODE (x) == VOIDmode)
6011 {
6012 /* We can use %d if the number is one word and positive. */
6013 if (CONST_DOUBLE_HIGH (x))
6014 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
6015 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
6016 else if (CONST_DOUBLE_LOW (x) < 0)
6017 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
6018 else
6019 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
6020 }
6021 else
6022 /* We can't handle floating point constants;
6023 PRINT_OPERAND must handle them. */
6024 output_operand_lossage ("floating constant misused");
6025 break;
6026
6027 case PLUS:
6028 /* FIXME: Not needed here. */
6029 /* Some assemblers need integer constants to appear last (eg masm). */
6030 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
6031 {
6032 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6033 fprintf (file, "+");
6034 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6035 }
6036 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
6037 {
6038 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6039 if (INTVAL (XEXP (x, 1)) >= 0)
6040 fprintf (file, "+");
6041 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6042 }
6043 else
6044 gcc_unreachable();
6045 break;
6046
6047 case MINUS:
6048 /* Avoid outputting things like x-x or x+5-x,
6049 since some assemblers can't handle that. */
6050 x = simplify_subtraction (x);
6051 if (GET_CODE (x) != MINUS)
6052 goto restart;
6053
6054 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6055 fprintf (file, "-");
6056 if (GET_CODE (XEXP (x, 1)) == CONST_INT
6057 && INTVAL (XEXP (x, 1)) < 0)
6058 {
6059 fprintf (file, "(");
6060 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6061 fprintf (file, ")");
6062 }
6063 else
6064 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6065 break;
6066
6067 case ZERO_EXTEND:
6068 case SIGN_EXTEND:
6069 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6070 break;
6071
6072
6073 case UNSPEC:
6074 const char *suffix;
6075 bool pcrel; pcrel = false;
6076 rtx base; base = NULL;
6077 gcc_assert (XVECLEN (x, 0) >= 1);
6078 switch (XINT (x, 1))
6079 {
6080 case ARC_UNSPEC_GOT:
6081 suffix = "@gotpc", pcrel = true;
6082 break;
6083 case ARC_UNSPEC_GOTOFF:
6084 suffix = "@gotoff";
6085 break;
6086 case ARC_UNSPEC_GOTOFFPC:
6087 suffix = "@pcl", pcrel = true;
6088 break;
6089 case ARC_UNSPEC_PLT:
6090 suffix = "@plt";
6091 break;
6092 case UNSPEC_TLS_GD:
6093 suffix = "@tlsgd", pcrel = true;
6094 break;
6095 case UNSPEC_TLS_IE:
6096 suffix = "@tlsie", pcrel = true;
6097 break;
6098 case UNSPEC_TLS_OFF:
6099 if (XVECLEN (x, 0) == 2)
6100 base = XVECEXP (x, 0, 1);
6101 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6102 || (!flag_pic && !base))
6103 suffix = "@tpoff";
6104 else
6105 suffix = "@dtpoff";
6106 break;
6107 default:
6108 suffix = "@invalid";
6109 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
6110 break;
6111 }
6112 if (pcrel)
6113 fputs ("pcl,", file);
6114 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
6115 fputs (suffix, file);
6116 if (base)
6117 arc_output_pic_addr_const (file, base, code);
6118 break;
6119
6120 default:
6121 output_operand_lossage ("invalid expression as operand");
6122 }
6123 }
6124
6125 /* The function returning the number of words, at the beginning of an
6126 argument, must be put in registers. The returned value must be
6127 zero for arguments that are passed entirely in registers or that
6128 are entirely pushed on the stack.
6129
6130 On some machines, certain arguments must be passed partially in
6131 registers and partially in memory. On these machines, typically
6132 the first N words of arguments are passed in registers, and the
6133 rest on the stack. If a multi-word argument (a `double' or a
6134 structure) crosses that boundary, its first few words must be
6135 passed in registers and the rest must be pushed. This function
6136 tells the compiler when this occurs, and how many of the words
6137 should go in registers.
6138
6139 `FUNCTION_ARG' for these arguments should return the first register
6140 to be used by the caller for this argument; likewise
6141 `FUNCTION_INCOMING_ARG', for the called function.
6142
6143 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6144
6145 /* If REGNO is the least arg reg available then what is the total number of arg
6146 regs available. */
6147 #define GPR_REST_ARG_REGS(REGNO) \
6148 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6149
6150 /* Since arc parm regs are contiguous. */
6151 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6152
6153 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6154
6155 static int
6156 arc_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
6157 {
6158 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6159 int bytes = arg.promoted_size_in_bytes ();
6160 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6161 int arg_num = *cum;
6162 int ret;
6163
6164 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6165 ret = GPR_REST_ARG_REGS (arg_num);
6166
6167 /* ICEd at function.cc:2361, and ret is copied to data->partial */
6168 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
6169
6170 return ret;
6171 }
6172
6173 /* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
6174 args are normally in registers and the rest are pushed. */
6175
6176 static rtx
6177 arc_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
6178 {
6179 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6180 int arg_num = *cum;
6181 rtx ret;
6182 const char *debstr ATTRIBUTE_UNUSED;
6183
6184 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6185 /* Return a marker for use in the call instruction. */
6186 if (arg.end_marker_p ())
6187 {
6188 ret = const0_rtx;
6189 debstr = "<0>";
6190 }
6191 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6192 {
6193 ret = gen_rtx_REG (arg.mode, arg_num);
6194 debstr = reg_names [arg_num];
6195 }
6196 else
6197 {
6198 ret = NULL_RTX;
6199 debstr = "memory";
6200 }
6201 return ret;
6202 }
6203
6204 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6205 /* For the ARC: the cum set here is passed on to function_arg where we
6206 look at its value and say which reg to use. Strategy: advance the
6207 regnumber here till we run out of arg regs, then set *cum to last
6208 reg. In function_arg, since *cum > last arg reg we would return 0
6209 and thus the arg will end up on the stack. For straddling args of
6210 course function_arg_partial_nregs will come into play. */
6211
6212 static void
6213 arc_function_arg_advance (cumulative_args_t cum_v,
6214 const function_arg_info &arg)
6215 {
6216 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6217 int bytes = arg.promoted_size_in_bytes ();
6218 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6219 int i;
6220
6221 if (words)
6222 *cum = ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type);
6223 for (i = 0; i < words; i++)
6224 *cum = ARC_NEXT_ARG_REG (*cum);
6225
6226 }
6227
6228 /* Define how to find the value returned by a function.
6229 VALTYPE is the data type of the value (as a tree).
6230 If the precise function being called is known, FN_DECL_OR_TYPE is its
6231 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6232
6233 static rtx
6234 arc_function_value (const_tree valtype,
6235 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6236 bool outgoing ATTRIBUTE_UNUSED)
6237 {
6238 machine_mode mode = TYPE_MODE (valtype);
6239 int unsignedp ATTRIBUTE_UNUSED;
6240
6241 unsignedp = TYPE_UNSIGNED (valtype);
6242 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6243 PROMOTE_MODE (mode, unsignedp, valtype);
6244 return gen_rtx_REG (mode, 0);
6245 }
6246
6247 /* Returns the return address that is used by builtin_return_address. */
6248
6249 rtx
6250 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6251 {
6252 if (count != 0)
6253 return const0_rtx;
6254
6255 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6256 }
6257
6258 /* Determine if a given RTX is a valid constant. We already know this
6259 satisfies CONSTANT_P. */
6260
6261 bool
6262 arc_legitimate_constant_p (machine_mode mode, rtx x)
6263 {
6264 switch (GET_CODE (x))
6265 {
6266 case CONST:
6267 if (flag_pic)
6268 {
6269 if (arc_legitimate_pic_addr_p (x))
6270 return true;
6271 }
6272 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6273
6274 case SYMBOL_REF:
6275 if (SYMBOL_REF_TLS_MODEL (x))
6276 return false;
6277 /* Fall through. */
6278 case LABEL_REF:
6279 if (flag_pic)
6280 return false;
6281 /* Fall through. */
6282 case CONST_INT:
6283 case CONST_DOUBLE:
6284 return true;
6285
6286 case NEG:
6287 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6288
6289 case PLUS:
6290 case MINUS:
6291 {
6292 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6293 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6294
6295 return (t1 && t2);
6296 }
6297
6298 case CONST_VECTOR:
6299 switch (mode)
6300 {
6301 case E_V2HImode:
6302 return TARGET_PLUS_DMPY;
6303 case E_V2SImode:
6304 case E_V4HImode:
6305 return TARGET_PLUS_QMACW;
6306 default:
6307 return false;
6308 }
6309
6310 case UNSPEC:
6311 switch (XINT (x, 1))
6312 {
6313 case UNSPEC_TLS_GD:
6314 case UNSPEC_TLS_OFF:
6315 case UNSPEC_TLS_IE:
6316 return true;
6317 default:
6318 /* Any other unspec ending here are pic related, hence the above
6319 constant pic address checking returned false. */
6320 return false;
6321 }
6322 /* Fall through. */
6323
6324 default:
6325 fatal_insn ("unrecognized supposed constant", x);
6326 }
6327
6328 gcc_unreachable ();
6329 }
6330
6331 static bool
6332 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict,
6333 code_helper = ERROR_MARK)
6334 {
6335 if (RTX_OK_FOR_BASE_P (x, strict))
6336 return true;
6337 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
6338 return true;
6339 if (legitimate_scaled_address_p (mode, x, strict))
6340 return true;
6341 if (legitimate_small_data_address_p (x, mode))
6342 return true;
6343 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6344 return true;
6345
6346 /* When we compile for size avoid const (@sym + offset)
6347 addresses. */
6348 if (!flag_pic && optimize_size && !reload_completed
6349 && (GET_CODE (x) == CONST)
6350 && (GET_CODE (XEXP (x, 0)) == PLUS)
6351 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6352 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6353 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
6354 {
6355 rtx addend = XEXP (XEXP (x, 0), 1);
6356 gcc_assert (CONST_INT_P (addend));
6357 HOST_WIDE_INT offset = INTVAL (addend);
6358
6359 /* Allow addresses having a large offset to pass. Anyhow they
6360 will end in a limm. */
6361 return !(offset > -1024 && offset < 1020);
6362 }
6363
6364 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6365 {
6366 return arc_legitimate_constant_p (mode, x);
6367 }
6368 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6369 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6370 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6371 return true;
6372 /* We're restricted here by the `st' insn. */
6373 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6374 && GET_CODE (XEXP ((x), 1)) == PLUS
6375 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
6376 && legitimate_offset_address_p (QImode, XEXP (x, 1),
6377 TARGET_AUTO_MODIFY_REG, strict))
6378 return true;
6379 return false;
6380 }
6381
6382 /* Return true iff ADDR (a legitimate address expression)
6383 has an effect that depends on the machine mode it is used for. */
6384
6385 static bool
6386 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6387 {
6388 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6389 which is valid for loads and stores, or a limm offset, which is valid for
6390 loads. Scaled indices are scaled by the access mode. */
6391 if (GET_CODE (addr) == PLUS
6392 && GET_CODE (XEXP ((addr), 0)) == MULT)
6393 return true;
6394 return false;
6395 }
6396
6397 /* Determine if it's legal to put X into the constant pool. */
6398
6399 static bool
6400 arc_cannot_force_const_mem (machine_mode mode, rtx x)
6401 {
6402 return !arc_legitimate_constant_p (mode, x);
6403 }
6404
6405 /* IDs for all the ARC builtins. */
6406
6407 enum arc_builtin_id
6408 {
6409 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6410 ARC_BUILTIN_ ## NAME,
6411 #include "builtins.def"
6412 #undef DEF_BUILTIN
6413
6414 ARC_BUILTIN_COUNT
6415 };
6416
6417 struct GTY(()) arc_builtin_description
6418 {
6419 enum insn_code icode;
6420 int n_args;
6421 tree fndecl;
6422 };
6423
6424 static GTY(()) struct arc_builtin_description
6425 arc_bdesc[ARC_BUILTIN_COUNT] =
6426 {
6427 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6428 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6429 #include "builtins.def"
6430 #undef DEF_BUILTIN
6431 };
6432
6433 /* Transform UP into lowercase and write the result to LO.
6434 You must provide enough space for LO. Return LO. */
6435
6436 static char*
6437 arc_tolower (char *lo, const char *up)
6438 {
6439 char *lo0 = lo;
6440
6441 for (; *up; up++, lo++)
6442 *lo = TOLOWER (*up);
6443
6444 *lo = '\0';
6445
6446 return lo0;
6447 }
6448
6449 /* Implement `TARGET_BUILTIN_DECL'. */
6450
6451 static tree
6452 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6453 {
6454 if (id < ARC_BUILTIN_COUNT)
6455 return arc_bdesc[id].fndecl;
6456
6457 return error_mark_node;
6458 }
6459
6460 static void
6461 arc_init_builtins (void)
6462 {
6463 tree V4HI_type_node;
6464 tree V2SI_type_node;
6465 tree V2HI_type_node;
6466
6467 /* Vector types based on HS SIMD elements. */
6468 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6469 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6470 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6471
6472 tree pcvoid_type_node
6473 = build_pointer_type (build_qualified_type (void_type_node,
6474 TYPE_QUAL_CONST));
6475 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6476 V8HImode);
6477
6478 tree void_ftype_void
6479 = build_function_type_list (void_type_node, NULL_TREE);
6480 tree int_ftype_int
6481 = build_function_type_list (integer_type_node, integer_type_node,
6482 NULL_TREE);
6483 tree int_ftype_pcvoid_int
6484 = build_function_type_list (integer_type_node, pcvoid_type_node,
6485 integer_type_node, NULL_TREE);
6486 tree void_ftype_usint_usint
6487 = build_function_type_list (void_type_node, long_unsigned_type_node,
6488 long_unsigned_type_node, NULL_TREE);
6489 tree int_ftype_int_int
6490 = build_function_type_list (integer_type_node, integer_type_node,
6491 integer_type_node, NULL_TREE);
6492 tree usint_ftype_usint
6493 = build_function_type_list (long_unsigned_type_node,
6494 long_unsigned_type_node, NULL_TREE);
6495 tree void_ftype_usint
6496 = build_function_type_list (void_type_node, long_unsigned_type_node,
6497 NULL_TREE);
6498 tree int_ftype_void
6499 = build_function_type_list (integer_type_node, void_type_node,
6500 NULL_TREE);
6501 tree void_ftype_int
6502 = build_function_type_list (void_type_node, integer_type_node,
6503 NULL_TREE);
6504 tree int_ftype_short
6505 = build_function_type_list (integer_type_node, short_integer_type_node,
6506 NULL_TREE);
6507
6508 /* Old ARC SIMD types. */
6509 tree v8hi_ftype_v8hi_v8hi
6510 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6511 V8HI_type_node, NULL_TREE);
6512 tree v8hi_ftype_v8hi_int
6513 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6514 integer_type_node, NULL_TREE);
6515 tree v8hi_ftype_v8hi_int_int
6516 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6517 integer_type_node, integer_type_node,
6518 NULL_TREE);
6519 tree void_ftype_v8hi_int_int
6520 = build_function_type_list (void_type_node, V8HI_type_node,
6521 integer_type_node, integer_type_node,
6522 NULL_TREE);
6523 tree void_ftype_v8hi_int_int_int
6524 = build_function_type_list (void_type_node, V8HI_type_node,
6525 integer_type_node, integer_type_node,
6526 integer_type_node, NULL_TREE);
6527 tree v8hi_ftype_int_int
6528 = build_function_type_list (V8HI_type_node, integer_type_node,
6529 integer_type_node, NULL_TREE);
6530 tree void_ftype_int_int
6531 = build_function_type_list (void_type_node, integer_type_node,
6532 integer_type_node, NULL_TREE);
6533 tree v8hi_ftype_v8hi
6534 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6535 NULL_TREE);
6536 /* ARCv2 SIMD types. */
6537 tree long_ftype_v4hi_v4hi
6538 = build_function_type_list (long_long_integer_type_node,
6539 V4HI_type_node, V4HI_type_node, NULL_TREE);
6540 tree int_ftype_v2hi_v2hi
6541 = build_function_type_list (integer_type_node,
6542 V2HI_type_node, V2HI_type_node, NULL_TREE);
6543 tree v2si_ftype_v2hi_v2hi
6544 = build_function_type_list (V2SI_type_node,
6545 V2HI_type_node, V2HI_type_node, NULL_TREE);
6546 tree v2hi_ftype_v2hi_v2hi
6547 = build_function_type_list (V2HI_type_node,
6548 V2HI_type_node, V2HI_type_node, NULL_TREE);
6549 tree v2si_ftype_v2si_v2si
6550 = build_function_type_list (V2SI_type_node,
6551 V2SI_type_node, V2SI_type_node, NULL_TREE);
6552 tree v4hi_ftype_v4hi_v4hi
6553 = build_function_type_list (V4HI_type_node,
6554 V4HI_type_node, V4HI_type_node, NULL_TREE);
6555 tree long_ftype_v2si_v2hi
6556 = build_function_type_list (long_long_integer_type_node,
6557 V2SI_type_node, V2HI_type_node, NULL_TREE);
6558
6559 /* Add the builtins. */
6560 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6561 { \
6562 int id = ARC_BUILTIN_ ## NAME; \
6563 const char *Name = "__builtin_arc_" #NAME; \
6564 char *name = (char*) alloca (1 + strlen (Name)); \
6565 \
6566 gcc_assert (id < ARC_BUILTIN_COUNT); \
6567 if (MASK) \
6568 arc_bdesc[id].fndecl \
6569 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6570 BUILT_IN_MD, NULL, NULL_TREE); \
6571 }
6572 #include "builtins.def"
6573 #undef DEF_BUILTIN
6574 }
6575
6576 /* Helper to expand __builtin_arc_aligned (void* val, int
6577 alignval). */
6578
6579 static rtx
6580 arc_expand_builtin_aligned (tree exp)
6581 {
6582 tree arg0 = CALL_EXPR_ARG (exp, 0);
6583 tree arg1 = CALL_EXPR_ARG (exp, 1);
6584 fold (arg1);
6585 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6586 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6587
6588 if (!CONST_INT_P (op1))
6589 {
6590 /* If we can't fold the alignment to a constant integer
6591 whilst optimizing, this is probably a user error. */
6592 if (optimize)
6593 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
6594 }
6595 else
6596 {
6597 HOST_WIDE_INT alignTest = INTVAL (op1);
6598 /* Check alignTest is positive, and a power of two. */
6599 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6600 {
6601 error ("invalid alignment value for %<__builtin_arc_aligned%>");
6602 return NULL_RTX;
6603 }
6604
6605 if (CONST_INT_P (op0))
6606 {
6607 HOST_WIDE_INT pnt = INTVAL (op0);
6608
6609 if ((pnt & (alignTest - 1)) == 0)
6610 return const1_rtx;
6611 }
6612 else
6613 {
6614 unsigned align = get_pointer_alignment (arg0);
6615 unsigned numBits = alignTest * BITS_PER_UNIT;
6616
6617 if (align && align >= numBits)
6618 return const1_rtx;
6619 /* Another attempt to ascertain alignment. Check the type
6620 we are pointing to. */
6621 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6622 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6623 return const1_rtx;
6624 }
6625 }
6626
6627 /* Default to false. */
6628 return const0_rtx;
6629 }
6630
6631 /* Helper arc_expand_builtin, generates a pattern for the given icode
6632 and arguments. */
6633
6634 static rtx_insn *
6635 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6636 {
6637 switch (insn_data[icode].n_generator_args)
6638 {
6639 case 0:
6640 return GEN_FCN (icode) ();
6641 case 1:
6642 return GEN_FCN (icode) (arg[0]);
6643 case 2:
6644 return GEN_FCN (icode) (arg[0], arg[1]);
6645 case 3:
6646 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6647 case 4:
6648 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6649 case 5:
6650 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6651 default:
6652 gcc_unreachable ();
6653 }
6654 }
6655
6656 /* Expand an expression EXP that calls a built-in function,
6657 with result going to TARGET if that's convenient
6658 (and in mode MODE if that's convenient).
6659 SUBTARGET may be used as the target for computing one of EXP's operands.
6660 IGNORE is nonzero if the value is to be ignored. */
6661
6662 static rtx
6663 arc_expand_builtin (tree exp,
6664 rtx target,
6665 rtx subtarget ATTRIBUTE_UNUSED,
6666 machine_mode mode ATTRIBUTE_UNUSED,
6667 int ignore ATTRIBUTE_UNUSED)
6668 {
6669 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6670 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
6671 const struct arc_builtin_description *d = &arc_bdesc[id];
6672 int i, j, n_args = call_expr_nargs (exp);
6673 rtx pat = NULL_RTX;
6674 rtx xop[5];
6675 enum insn_code icode = d->icode;
6676 machine_mode tmode = insn_data[icode].operand[0].mode;
6677 int nonvoid;
6678 tree arg0;
6679 tree arg1;
6680 tree arg2;
6681 tree arg3;
6682 rtx op0;
6683 rtx op1;
6684 rtx op2;
6685 rtx op3;
6686 rtx op4;
6687 machine_mode mode0;
6688 machine_mode mode1;
6689 machine_mode mode2;
6690 machine_mode mode3;
6691 machine_mode mode4;
6692
6693 if (id >= ARC_BUILTIN_COUNT)
6694 internal_error ("bad builtin fcode");
6695
6696 /* 1st part: Expand special builtins. */
6697 switch (id)
6698 {
6699 case ARC_BUILTIN_NOP:
6700 emit_insn (gen_nopv ());
6701 return NULL_RTX;
6702
6703 case ARC_BUILTIN_RTIE:
6704 case ARC_BUILTIN_SYNC:
6705 case ARC_BUILTIN_BRK:
6706 case ARC_BUILTIN_SWI:
6707 case ARC_BUILTIN_UNIMP_S:
6708 gcc_assert (icode != 0);
6709 emit_insn (GEN_FCN (icode) (const1_rtx));
6710 return NULL_RTX;
6711
6712 case ARC_BUILTIN_ALIGNED:
6713 return arc_expand_builtin_aligned (exp);
6714
6715 case ARC_BUILTIN_CLRI:
6716 target = gen_reg_rtx (SImode);
6717 emit_insn (gen_clri (target, const1_rtx));
6718 return target;
6719
6720 case ARC_BUILTIN_TRAP_S:
6721 case ARC_BUILTIN_SLEEP:
6722 arg0 = CALL_EXPR_ARG (exp, 0);
6723 fold (arg0);
6724 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6725
6726 gcc_assert (icode != 0);
6727 emit_insn (GEN_FCN (icode) (op0));
6728 return NULL_RTX;
6729
6730 case ARC_BUILTIN_VDORUN:
6731 case ARC_BUILTIN_VDIRUN:
6732 arg0 = CALL_EXPR_ARG (exp, 0);
6733 arg1 = CALL_EXPR_ARG (exp, 1);
6734 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6735 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6736
6737 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
6738
6739 mode0 = insn_data[icode].operand[1].mode;
6740 mode1 = insn_data[icode].operand[2].mode;
6741
6742 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6743 op0 = copy_to_mode_reg (mode0, op0);
6744
6745 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6746 op1 = copy_to_mode_reg (mode1, op1);
6747
6748 pat = GEN_FCN (icode) (target, op0, op1);
6749 if (!pat)
6750 return NULL_RTX;
6751
6752 emit_insn (pat);
6753 return NULL_RTX;
6754
6755 case ARC_BUILTIN_VDIWR:
6756 case ARC_BUILTIN_VDOWR:
6757 arg0 = CALL_EXPR_ARG (exp, 0);
6758 arg1 = CALL_EXPR_ARG (exp, 1);
6759 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6760 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6761
6762 if (!CONST_INT_P (op0)
6763 || !(UNSIGNED_INT3 (INTVAL (op0))))
6764 error ("operand 1 should be an unsigned 3-bit immediate");
6765
6766 mode1 = insn_data[icode].operand[1].mode;
6767
6768 if (icode == CODE_FOR_vdiwr_insn)
6769 target = gen_rtx_REG (SImode,
6770 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
6771 else if (icode == CODE_FOR_vdowr_insn)
6772 target = gen_rtx_REG (SImode,
6773 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
6774 else
6775 gcc_unreachable ();
6776
6777 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6778 op1 = copy_to_mode_reg (mode1, op1);
6779
6780 pat = GEN_FCN (icode) (target, op1);
6781 if (!pat)
6782 return NULL_RTX;
6783
6784 emit_insn (pat);
6785 return NULL_RTX;
6786
6787 case ARC_BUILTIN_VASRW:
6788 case ARC_BUILTIN_VSR8:
6789 case ARC_BUILTIN_VSR8AW:
6790 arg0 = CALL_EXPR_ARG (exp, 0);
6791 arg1 = CALL_EXPR_ARG (exp, 1);
6792 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6793 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6794 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6795
6796 target = gen_reg_rtx (V8HImode);
6797 mode0 = insn_data[icode].operand[1].mode;
6798 mode1 = insn_data[icode].operand[2].mode;
6799
6800 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6801 op0 = copy_to_mode_reg (mode0, op0);
6802
6803 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6804 || !(UNSIGNED_INT3 (INTVAL (op1))))
6805 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6806
6807 pat = GEN_FCN (icode) (target, op0, op1, op2);
6808 if (!pat)
6809 return NULL_RTX;
6810
6811 emit_insn (pat);
6812 return target;
6813
6814 case ARC_BUILTIN_VLD32WH:
6815 case ARC_BUILTIN_VLD32WL:
6816 case ARC_BUILTIN_VLD64:
6817 case ARC_BUILTIN_VLD32:
6818 rtx src_vreg;
6819 icode = d->icode;
6820 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6821 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6822 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6823
6824 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6825 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6826 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6827 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6828
6829 /* target <- src vreg. */
6830 emit_insn (gen_move_insn (target, src_vreg));
6831
6832 /* target <- vec_concat: target, mem (Ib, u8). */
6833 mode0 = insn_data[icode].operand[3].mode;
6834 mode1 = insn_data[icode].operand[1].mode;
6835
6836 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
6837 || !(UNSIGNED_INT3 (INTVAL (op0))))
6838 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6839
6840 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6841 || !(UNSIGNED_INT8 (INTVAL (op1))))
6842 error ("operand 2 should be an unsigned 8-bit value");
6843
6844 pat = GEN_FCN (icode) (target, op1, op2, op0);
6845 if (!pat)
6846 return NULL_RTX;
6847
6848 emit_insn (pat);
6849 return target;
6850
6851 case ARC_BUILTIN_VLD64W:
6852 case ARC_BUILTIN_VLD128:
6853 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
6854 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6855
6856 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6857 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6858 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6859
6860 /* target <- src vreg. */
6861 target = gen_reg_rtx (V8HImode);
6862
6863 /* target <- vec_concat: target, mem (Ib, u8). */
6864 mode0 = insn_data[icode].operand[1].mode;
6865 mode1 = insn_data[icode].operand[2].mode;
6866 mode2 = insn_data[icode].operand[3].mode;
6867
6868 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6869 || !(UNSIGNED_INT3 (INTVAL (op1))))
6870 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6871
6872 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
6873 || !(UNSIGNED_INT8 (INTVAL (op2))))
6874 error ("operand 2 should be an unsigned 8-bit value");
6875
6876 pat = GEN_FCN (icode) (target, op0, op1, op2);
6877
6878 if (!pat)
6879 return NULL_RTX;
6880
6881 emit_insn (pat);
6882 return target;
6883
6884 case ARC_BUILTIN_VST128:
6885 case ARC_BUILTIN_VST64:
6886 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
6887 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6888 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6889
6890 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6891 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6892 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6893 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6894
6895 mode0 = insn_data[icode].operand[0].mode;
6896 mode1 = insn_data[icode].operand[1].mode;
6897 mode2 = insn_data[icode].operand[2].mode;
6898 mode3 = insn_data[icode].operand[3].mode;
6899
6900 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6901 || !(UNSIGNED_INT3 (INTVAL (op1))))
6902 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6903
6904 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6905 || !(UNSIGNED_INT8 (INTVAL (op2))))
6906 error ("operand 3 should be an unsigned 8-bit value");
6907
6908 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6909 op3 = copy_to_mode_reg (mode3, op3);
6910
6911 pat = GEN_FCN (icode) (op0, op1, op2, op3);
6912 if (!pat)
6913 return NULL_RTX;
6914
6915 emit_insn (pat);
6916 return NULL_RTX;
6917
6918 case ARC_BUILTIN_VST16_N:
6919 case ARC_BUILTIN_VST32_N:
6920 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6921 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
6922 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
6923 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
6924
6925 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
6926 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6927 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6928 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6929 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6930
6931 mode0 = insn_data[icode].operand[0].mode;
6932 mode2 = insn_data[icode].operand[2].mode;
6933 mode3 = insn_data[icode].operand[3].mode;
6934 mode4 = insn_data[icode].operand[4].mode;
6935
6936 /* Do some correctness checks for the operands. */
6937 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
6938 || !(UNSIGNED_INT8 (INTVAL (op0))))
6939 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6940
6941 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6942 || !(UNSIGNED_INT3 (INTVAL (op2))))
6943 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6944
6945 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6946 op3 = copy_to_mode_reg (mode3, op3);
6947
6948 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
6949 || !(UNSIGNED_INT3 (INTVAL (op4))))
6950 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6951 else if (icode == CODE_FOR_vst32_n_insn
6952 && ((INTVAL (op4) % 2) != 0))
6953 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6954
6955 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
6956 if (!pat)
6957 return NULL_RTX;
6958
6959 emit_insn (pat);
6960 return NULL_RTX;
6961
6962 default:
6963 break;
6964 }
6965
6966 /* 2nd part: Expand regular builtins. */
6967 if (icode == 0)
6968 internal_error ("bad builtin fcode");
6969
6970 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6971 j = 0;
6972
6973 if (nonvoid)
6974 {
6975 if (target == NULL_RTX
6976 || GET_MODE (target) != tmode
6977 || !insn_data[icode].operand[0].predicate (target, tmode))
6978 {
6979 target = gen_reg_rtx (tmode);
6980 }
6981 xop[j++] = target;
6982 }
6983
6984 gcc_assert (n_args <= 4);
6985 for (i = 0; i < n_args; i++, j++)
6986 {
6987 tree arg = CALL_EXPR_ARG (exp, i);
6988 machine_mode mode = insn_data[icode].operand[j].mode;
6989 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
6990 machine_mode opmode = GET_MODE (op);
6991 char c = insn_data[icode].operand[j].constraint[0];
6992
6993 /* SIMD extension requires exact immediate operand match. */
6994 if ((id > ARC_BUILTIN_SIMD_BEGIN)
6995 && (id < ARC_BUILTIN_SIMD_END)
6996 && (c != 'v')
6997 && (c != 'r'))
6998 {
6999 if (!CONST_INT_P (op))
7000 error ("builtin requires an immediate for operand %d", j);
7001 switch (c)
7002 {
7003 case 'L':
7004 if (!satisfies_constraint_L (op))
7005 error ("operand %d should be a 6 bit unsigned immediate", j);
7006 break;
7007 case 'P':
7008 if (!satisfies_constraint_P (op))
7009 error ("operand %d should be a 8 bit unsigned immediate", j);
7010 break;
7011 case 'K':
7012 if (!satisfies_constraint_K (op))
7013 error ("operand %d should be a 3 bit unsigned immediate", j);
7014 break;
7015 default:
7016 error ("unknown builtin immediate operand type for operand %d",
7017 j);
7018 }
7019 }
7020
7021 if (CONST_INT_P (op))
7022 opmode = mode;
7023
7024 if ((opmode == SImode) && (mode == HImode))
7025 {
7026 opmode = HImode;
7027 op = gen_lowpart (HImode, op);
7028 }
7029
7030 /* In case the insn wants input operands in modes different from
7031 the result, abort. */
7032 gcc_assert (opmode == mode || opmode == VOIDmode);
7033
7034 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
7035 op = copy_to_mode_reg (mode, op);
7036
7037 xop[j] = op;
7038 }
7039
7040 pat = apply_GEN_FCN (icode, xop);
7041 if (pat == NULL_RTX)
7042 return NULL_RTX;
7043
7044 emit_insn (pat);
7045
7046 if (nonvoid)
7047 return target;
7048 else
7049 return const0_rtx;
7050 }
7051
7052 /* Implement TARGET_FOLD_BUILTIN. */
7053
7054 static tree
7055 arc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
7056 bool ignore ATTRIBUTE_UNUSED)
7057 {
7058 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
7059
7060 switch (fcode)
7061 {
7062 default:
7063 break;
7064
7065 case ARC_BUILTIN_SWAP:
7066 return fold_build2 (LROTATE_EXPR, integer_type_node, arg[0],
7067 build_int_cst (integer_type_node, 16));
7068
7069 case ARC_BUILTIN_NORM:
7070 if (TREE_CODE (arg[0]) == INTEGER_CST
7071 && !TREE_OVERFLOW (arg[0]))
7072 {
7073 wide_int arg0 = wi::to_wide (arg[0], 32);
7074 wide_int result = wi::shwi (wi::clrsb (arg0), 32);
7075 return wide_int_to_tree (integer_type_node, result);
7076 }
7077 break;
7078
7079 case ARC_BUILTIN_NORMW:
7080 if (TREE_CODE (arg[0]) == INTEGER_CST
7081 && !TREE_OVERFLOW (arg[0]))
7082 {
7083 wide_int arg0 = wi::to_wide (arg[0], 16);
7084 wide_int result = wi::shwi (wi::clrsb (arg0), 32);
7085 return wide_int_to_tree (integer_type_node, result);
7086 }
7087 break;
7088 }
7089 return NULL_TREE;
7090 }
7091
7092 /* Returns true if the operands[opno] is a valid compile-time constant to be
7093 used as register number in the code for builtins. Else it flags an error
7094 and returns false. */
7095
7096 bool
7097 check_if_valid_regno_const (rtx *operands, int opno)
7098 {
7099
7100 switch (GET_CODE (operands[opno]))
7101 {
7102 case SYMBOL_REF :
7103 case CONST :
7104 case CONST_INT :
7105 return true;
7106 default:
7107 error ("register number must be a compile-time constant. "
7108 "Try giving higher optimization levels");
7109 break;
7110 }
7111 return false;
7112 }
7113
7114 /* Return true if it is ok to make a tail-call to DECL. */
7115
7116 static bool
7117 arc_function_ok_for_sibcall (tree decl,
7118 tree exp ATTRIBUTE_UNUSED)
7119 {
7120 tree attrs = NULL_TREE;
7121
7122 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7123 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
7124 return false;
7125
7126 if (decl)
7127 {
7128 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
7129
7130 if (lookup_attribute ("jli_always", attrs))
7131 return false;
7132 if (lookup_attribute ("jli_fixed", attrs))
7133 return false;
7134 if (lookup_attribute ("secure_call", attrs))
7135 return false;
7136 }
7137
7138 /* Everything else is ok. */
7139 return true;
7140 }
7141
7142 /* Output code to add DELTA to the first argument, and then jump
7143 to FUNCTION. Used for C++ multiple inheritance. */
7144
7145 static void
7146 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7147 HOST_WIDE_INT delta,
7148 HOST_WIDE_INT vcall_offset,
7149 tree function)
7150 {
7151 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
7152 int mi_delta = delta;
7153 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
7154 int shift = 0;
7155 int this_regno
7156 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
7157 rtx fnaddr;
7158
7159 assemble_start_function (thunk, fnname);
7160
7161 if (mi_delta < 0)
7162 mi_delta = - mi_delta;
7163
7164 /* Add DELTA. When possible use a plain add, otherwise load it into
7165 a register first. */
7166
7167 while (mi_delta != 0)
7168 {
7169 if ((mi_delta & (3 << shift)) == 0)
7170 shift += 2;
7171 else
7172 {
7173 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
7174 mi_op, reg_names[this_regno], reg_names[this_regno],
7175 mi_delta & (0xff << shift));
7176 mi_delta &= ~(0xff << shift);
7177 shift += 8;
7178 }
7179 }
7180
7181 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7182 if (vcall_offset != 0)
7183 {
7184 /* ld r12,[this] --> temp = *this
7185 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7186 ld r12,[r12]
7187 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7188 asm_fprintf (file, "\tld\t%s, [%s]\n",
7189 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
7190 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
7191 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7192 asm_fprintf (file, "\tld\t%s, [%s]\n",
7193 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7194 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7195 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7196 }
7197
7198 fnaddr = XEXP (DECL_RTL (function), 0);
7199
7200 if (arc_is_longcall_p (fnaddr))
7201 {
7202 if (flag_pic)
7203 {
7204 asm_fprintf (file, "\tld\t%s, [pcl, @",
7205 ARC_TEMP_SCRATCH_REG);
7206 assemble_name (file, XSTR (fnaddr, 0));
7207 fputs ("@gotpc]\n", file);
7208 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7209 }
7210 else
7211 {
7212 fputs ("\tj\t@", file);
7213 assemble_name (file, XSTR (fnaddr, 0));
7214 }
7215 }
7216 else
7217 {
7218 fputs ("\tb\t@", file);
7219 assemble_name (file, XSTR (fnaddr, 0));
7220 if (flag_pic)
7221 fputs ("@plt\n", file);
7222 }
7223 fputc ('\n', file);
7224 assemble_end_function (thunk, fnname);
7225 }
7226
7227 /* Return true if a 32 bit "long_call" should be generated for
7228 this calling SYM_REF. We generate a long_call if the function:
7229
7230 a. has an __attribute__((long call))
7231 or b. the -mlong-calls command line switch has been specified
7232
7233 However we do not generate a long call if the function has an
7234 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7235
7236 This function will be called by C fragments contained in the machine
7237 description file. */
7238
7239 bool
7240 arc_is_longcall_p (rtx sym_ref)
7241 {
7242 if (GET_CODE (sym_ref) != SYMBOL_REF)
7243 return false;
7244
7245 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7246 || (TARGET_LONG_CALLS_SET
7247 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7248 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7249
7250 }
7251
7252 /* Likewise for short calls. */
7253
7254 bool
7255 arc_is_shortcall_p (rtx sym_ref)
7256 {
7257 if (GET_CODE (sym_ref) != SYMBOL_REF)
7258 return false;
7259
7260 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7261 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7262 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7263 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7264
7265 }
7266
7267 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7268
7269 static bool
7270 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7271 {
7272 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7273 return true;
7274 else
7275 {
7276 HOST_WIDE_INT size = int_size_in_bytes (type);
7277 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
7278 }
7279 }
7280
7281 static bool
7282 arc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
7283 {
7284 return (arg.type != 0
7285 && (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST
7286 || TREE_ADDRESSABLE (arg.type)));
7287 }
7288
7289 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7290
7291 static bool
7292 arc_can_use_doloop_p (const widest_int &,
7293 const widest_int &iterations_max,
7294 unsigned int loop_depth, bool entered_at_top)
7295 {
7296 /* Considering limitations in the hardware, only use doloop
7297 for innermost loops which must be entered from the top. */
7298 if (loop_depth > 1 || !entered_at_top)
7299 return false;
7300
7301 /* Check for lp_count width boundary. */
7302 if (arc_lpcwidth != 32
7303 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7304 || wi::eq_p (iterations_max, 0)))
7305 return false;
7306 return true;
7307 }
7308
7309 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7310 return why doloop cannot be applied. */
7311
7312 static const char *
7313 arc_invalid_within_doloop (const rtx_insn *insn)
7314 {
7315 if (CALL_P (insn))
7316 return "Function call in the loop.";
7317
7318 /* FIXME! add here all the ZOL exceptions. */
7319 return NULL;
7320 }
7321
7322 /* Return the next active insn, skiping the inline assembly code. */
7323
7324 static rtx_insn *
7325 arc_active_insn (rtx_insn *insn)
7326 {
7327 while (insn)
7328 {
7329 insn = NEXT_INSN (insn);
7330 if (insn == 0
7331 || (active_insn_p (insn)
7332 && NONDEBUG_INSN_P (insn)
7333 && !NOTE_P (insn)
7334 && GET_CODE (PATTERN (insn)) != UNSPEC_VOLATILE
7335 && GET_CODE (PATTERN (insn)) != PARALLEL))
7336 break;
7337 }
7338 return insn;
7339 }
7340
7341 /* Search for a sequence made out of two stores and a given number of
7342 loads, insert a nop if required. */
7343
7344 static void
7345 check_store_cacheline_hazard (void)
7346 {
7347 rtx_insn *insn, *succ0, *insn1;
7348 bool found = false;
7349
7350 for (insn = get_insns (); insn; insn = arc_active_insn (insn))
7351 {
7352 succ0 = arc_active_insn (insn);
7353
7354 if (!succ0)
7355 return;
7356
7357 if (!single_set (insn))
7358 continue;
7359
7360 if ((get_attr_type (insn) != TYPE_STORE))
7361 continue;
7362
7363 /* Found at least two consecutive stores. Goto the end of the
7364 store sequence. */
7365 for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1))
7366 if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE)
7367 break;
7368
7369 /* Save were we are. */
7370 succ0 = insn1;
7371
7372 /* Now, check the next two instructions for the following cases:
7373 1. next instruction is a LD => insert 2 nops between store
7374 sequence and load.
7375 2. next-next instruction is a LD => inset 1 nop after the store
7376 sequence. */
7377 if (insn1 && single_set (insn1)
7378 && (get_attr_type (insn1) == TYPE_LOAD))
7379 {
7380 found = true;
7381 emit_insn_before (gen_nopv (), insn1);
7382 emit_insn_before (gen_nopv (), insn1);
7383 }
7384 else
7385 {
7386 if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE))
7387 {
7388 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7389 reorg, so it is safe to reuse it for avoiding the
7390 current compare insn to be part of a BRcc
7391 optimization. */
7392 add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3));
7393 }
7394 insn1 = arc_active_insn (insn1);
7395 if (insn1 && single_set (insn1)
7396 && (get_attr_type (insn1) == TYPE_LOAD))
7397 {
7398 found = true;
7399 emit_insn_before (gen_nopv (), insn1);
7400 }
7401 }
7402
7403 if (found)
7404 {
7405 insn = insn1;
7406 found = false;
7407 }
7408 else
7409 insn = succ0;
7410 }
7411 }
7412
7413 /* Return true if a load instruction (CONSUMER) uses the same address as a
7414 store instruction (PRODUCER). This function is used to avoid st/ld
7415 address hazard in ARC700 cores. */
7416
7417 static bool
7418 arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer)
7419 {
7420 rtx in_set, out_set;
7421 rtx out_addr, in_addr;
7422
7423 if (!producer)
7424 return false;
7425
7426 if (!consumer)
7427 return false;
7428
7429 /* Peel the producer and the consumer for the address. */
7430 out_set = single_set (producer);
7431 if (out_set)
7432 {
7433 out_addr = SET_DEST (out_set);
7434 if (!out_addr)
7435 return false;
7436 if (GET_CODE (out_addr) == ZERO_EXTEND
7437 || GET_CODE (out_addr) == SIGN_EXTEND)
7438 out_addr = XEXP (out_addr, 0);
7439
7440 if (!MEM_P (out_addr))
7441 return false;
7442
7443 in_set = single_set (consumer);
7444 if (in_set)
7445 {
7446 in_addr = SET_SRC (in_set);
7447 if (!in_addr)
7448 return false;
7449 if (GET_CODE (in_addr) == ZERO_EXTEND
7450 || GET_CODE (in_addr) == SIGN_EXTEND)
7451 in_addr = XEXP (in_addr, 0);
7452
7453 if (!MEM_P (in_addr))
7454 return false;
7455 /* Get rid of the MEM and check if the addresses are
7456 equivalent. */
7457 in_addr = XEXP (in_addr, 0);
7458 out_addr = XEXP (out_addr, 0);
7459
7460 return exp_equiv_p (in_addr, out_addr, 0, true);
7461 }
7462 }
7463 return false;
7464 }
7465
7466 /* Return TRUE is we have an store address hazard. */
7467
7468 bool
7469 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7470 {
7471 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
7472 return true;
7473 return arc_store_addr_hazard_internal_p (producer, consumer);
7474 }
7475
7476 /* Return length adjustment for INSN.
7477 For ARC600:
7478 A write to a core reg greater or equal to 32 must not be immediately
7479 followed by a use. Anticipate the length requirement to insert a nop
7480 between PRED and SUCC to prevent a hazard. */
7481
7482 static int
7483 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
7484 {
7485 if (!TARGET_ARC600)
7486 return 0;
7487 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
7488 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
7489 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
7490 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
7491 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7492 || recog_memoized (pred) == CODE_FOR_umul_600
7493 || recog_memoized (pred) == CODE_FOR_mac_600
7494 || recog_memoized (pred) == CODE_FOR_mul64_600
7495 || recog_memoized (pred) == CODE_FOR_mac64_600
7496 || recog_memoized (pred) == CODE_FOR_umul64_600
7497 || recog_memoized (pred) == CODE_FOR_umac64_600)
7498 return 0;
7499 subrtx_iterator::array_type array;
7500 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7501 {
7502 const_rtx x = *iter;
7503 switch (GET_CODE (x))
7504 {
7505 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7506 break;
7507 default:
7508 /* This is also fine for PRE/POST_MODIFY, because they
7509 contain a SET. */
7510 continue;
7511 }
7512 rtx dest = XEXP (x, 0);
7513 /* Check if this sets a an extension register. N.B. we use 61 for the
7514 condition codes, which is definitely not an extension register. */
7515 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7516 /* Check if the same register is used by the PAT. */
7517 && (refers_to_regno_p
7518 (REGNO (dest),
7519 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7520 PATTERN (succ), 0)))
7521 return 4;
7522 }
7523 return 0;
7524 }
7525
7526 /* For ARC600:
7527 A write to a core reg greater or equal to 32 must not be immediately
7528 followed by a use. Anticipate the length requirement to insert a nop
7529 between PRED and SUCC to prevent a hazard. */
7530
7531 int
7532 arc_hazard (rtx_insn *pred, rtx_insn *succ)
7533 {
7534 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7535 return 0;
7536
7537 if (TARGET_ARC600)
7538 return arc600_corereg_hazard (pred, succ);
7539
7540 return 0;
7541 }
7542
7543 /* When compiling for release 310a, insert a nop before any
7544 conditional jump. */
7545
7546 static int
7547 arc_check_release31a (rtx_insn *pred, rtx_insn *succ)
7548 {
7549 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7550 return 0;
7551
7552 if (!JUMP_P (pred) && !single_set (pred))
7553 return 0;
7554
7555 if (!JUMP_P (succ) && !single_set (succ))
7556 return 0;
7557
7558 if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
7559 switch (get_attr_type (pred))
7560 {
7561 case TYPE_STORE:
7562 switch (get_attr_type (succ))
7563 {
7564 case TYPE_BRCC:
7565 case TYPE_BRCC_NO_DELAY_SLOT:
7566 case TYPE_LOOP_END:
7567 return 1;
7568 default:
7569 break;
7570 }
7571 break;
7572 case TYPE_BRCC:
7573 case TYPE_BRCC_NO_DELAY_SLOT:
7574 case TYPE_LOOP_END:
7575 if (get_attr_type (succ) == TYPE_STORE)
7576 return 1;
7577 break;
7578 default:
7579 break;
7580 }
7581
7582 return 0;
7583 }
7584
7585 /* The same functionality as arc_hazard. It is called in machine
7586 reorg before any other optimization. Hence, the NOP size is taken
7587 into account when doing branch shortening. */
7588
7589 static void
7590 workaround_arc_anomaly (void)
7591 {
7592 rtx_insn *insn, *succ0;
7593
7594 /* For any architecture: call arc_hazard here. */
7595 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7596 {
7597 succ0 = next_real_insn (insn);
7598 if (arc_hazard (insn, succ0) || arc_check_release31a (insn, succ0))
7599 emit_insn_before (gen_nopv (), succ0);
7600 }
7601
7602 if (!TARGET_ARC700)
7603 return;
7604
7605 /* Old A7 are suffering of a cache hazard, and we need to insert two
7606 nops between any sequence of stores and a load. */
7607 if (arc_tune != ARC_TUNE_ARC7XX)
7608 check_store_cacheline_hazard ();
7609 }
7610
7611 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7612 turns out not to be optimizable; we have to split the loop_end pattern into
7613 a subtract and a test. */
7614
7615 static void
7616 hwloop_fail (hwloop_info loop)
7617 {
7618 rtx test;
7619 rtx insn = loop->loop_end;
7620
7621 if (TARGET_DBNZ
7622 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7623 && REG_P (loop->iter_reg))
7624 {
7625 /* TARGET_V2 core3 has dbnz instructions. */
7626 test = gen_dbnz (loop->iter_reg, loop->start_label);
7627 insn = emit_jump_insn_before (test, loop->loop_end);
7628 }
7629 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7630 {
7631 /* We have the lp_count as loop iterator, try to use it. */
7632 emit_insn_before (gen_loop_fail (), loop->loop_end);
7633 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7634 const0_rtx);
7635 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7636 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7637 pc_rtx);
7638 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7639 loop->loop_end);
7640 }
7641 else
7642 {
7643 emit_insn_before (gen_addsi3 (loop->iter_reg,
7644 loop->iter_reg,
7645 constm1_rtx),
7646 loop->loop_end);
7647 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7648 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7649 loop->iter_reg,
7650 const0_rtx,
7651 loop->start_label),
7652 loop->loop_end);
7653 }
7654 JUMP_LABEL (insn) = loop->start_label;
7655 LABEL_NUSES (loop->start_label)++;
7656 delete_insn (loop->loop_end);
7657 }
7658
7659 /* Return the next insn after INSN that is not a NOTE, but stop the
7660 search before we enter another basic block. This routine does not
7661 look inside SEQUENCEs. */
7662
7663 static rtx_insn *
7664 next_nonnote_insn_bb (rtx_insn *insn)
7665 {
7666 while (insn)
7667 {
7668 insn = NEXT_INSN (insn);
7669 if (insn == 0 || !NOTE_P (insn))
7670 break;
7671 if (NOTE_INSN_BASIC_BLOCK_P (insn))
7672 return NULL;
7673 }
7674
7675 return insn;
7676 }
7677
7678 /* Optimize LOOP. */
7679
7680 static bool
7681 hwloop_optimize (hwloop_info loop)
7682 {
7683 int i;
7684 edge entry_edge;
7685 basic_block entry_bb, bb;
7686 rtx iter_reg;
7687 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label;
7688 unsigned int length;
7689 bool need_fix = false;
7690 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7691
7692 if (loop->depth > 1)
7693 {
7694 if (dump_file)
7695 fprintf (dump_file, ";; loop %d is not innermost\n",
7696 loop->loop_no);
7697 return false;
7698 }
7699
7700 if (!loop->incoming_dest)
7701 {
7702 if (dump_file)
7703 fprintf (dump_file, ";; loop %d has more than one entry\n",
7704 loop->loop_no);
7705 return false;
7706 }
7707
7708 if (loop->incoming_dest != loop->head)
7709 {
7710 if (dump_file)
7711 fprintf (dump_file, ";; loop %d is not entered from head\n",
7712 loop->loop_no);
7713 return false;
7714 }
7715
7716 if (loop->has_call || loop->has_asm)
7717 {
7718 if (dump_file)
7719 fprintf (dump_file, ";; loop %d has invalid insn\n",
7720 loop->loop_no);
7721 return false;
7722 }
7723
7724 /* Scan all the blocks to make sure they don't use iter_reg. */
7725 if (loop->iter_reg_used || loop->iter_reg_used_outside)
7726 {
7727 if (dump_file)
7728 fprintf (dump_file, ";; loop %d uses iterator\n",
7729 loop->loop_no);
7730 return false;
7731 }
7732
7733 /* Check if start_label appears before doloop_end. */
7734 length = 0;
7735 for (insn = loop->start_label;
7736 insn && insn != loop->loop_end;
7737 insn = NEXT_INSN (insn))
7738 {
7739 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
7740 if (JUMP_TABLES_IN_TEXT_SECTION
7741 && JUMP_TABLE_DATA_P (insn))
7742 {
7743 if (dump_file)
7744 fprintf (dump_file, ";; loop %d has a jump table\n",
7745 loop->loop_no);
7746 return false;
7747 }
7748 }
7749
7750 if (!insn)
7751 {
7752 if (dump_file)
7753 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
7754 loop->loop_no);
7755 return false;
7756 }
7757
7758 loop->length = length;
7759 if (loop->length > ARC_MAX_LOOP_LENGTH)
7760 {
7761 if (dump_file)
7762 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7763 return false;
7764 }
7765 else if (!loop->length)
7766 {
7767 if (dump_file)
7768 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
7769 return false;
7770 }
7771
7772 /* Check if we use a register or not. */
7773 if (!REG_P (loop->iter_reg))
7774 {
7775 if (dump_file)
7776 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7777 loop->loop_no);
7778 return false;
7779 }
7780
7781 /* Check if we use a register or not. */
7782 if (!REG_P (loop->iter_reg))
7783 {
7784 if (dump_file)
7785 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7786 loop->loop_no);
7787 return false;
7788 }
7789
7790 /* Check if loop register is lpcount. */
7791 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
7792 {
7793 if (dump_file)
7794 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
7795 " iterator\n",
7796 loop->loop_no);
7797 /* This loop doesn't use the lp_count, check though if we can
7798 fix it. */
7799 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
7800 /* In very unique cases we may have LP_COUNT alive. */
7801 || (loop->incoming_src
7802 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
7803 LP_COUNT)))
7804 {
7805 if (dump_file)
7806 fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no);
7807 return false;
7808 }
7809 else
7810 need_fix = true;
7811 }
7812
7813 /* Check for control like instruction as the last instruction of a
7814 ZOL. */
7815 bb = loop->tail;
7816 last_insn = PREV_INSN (loop->loop_end);
7817
7818 while (1)
7819 {
7820 for (; last_insn != BB_HEAD (bb);
7821 last_insn = PREV_INSN (last_insn))
7822 if (NONDEBUG_INSN_P (last_insn))
7823 break;
7824
7825 if (last_insn != BB_HEAD (bb))
7826 break;
7827
7828 if (single_pred_p (bb)
7829 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
7830 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
7831 {
7832 bb = single_pred (bb);
7833 last_insn = BB_END (bb);
7834 continue;
7835 }
7836 else
7837 {
7838 last_insn = NULL;
7839 break;
7840 }
7841 }
7842
7843 if (!last_insn)
7844 {
7845 if (dump_file)
7846 fprintf (dump_file, ";; loop %d has no last instruction\n",
7847 loop->loop_no);
7848 return false;
7849 }
7850
7851 if ((TARGET_ARC600_FAMILY || TARGET_HS)
7852 && INSN_P (last_insn)
7853 && (JUMP_P (last_insn) || CALL_P (last_insn)
7854 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
7855 /* At this stage we can have (insn (clobber (mem:BLK
7856 (reg)))) instructions, ignore them. */
7857 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
7858 && (get_attr_type (last_insn) == TYPE_BRCC
7859 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
7860 {
7861 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
7862 {
7863 if (dump_file)
7864 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7865 return false;
7866 }
7867 if (dump_file)
7868 fprintf (dump_file, ";; loop %d has a control like last insn; "
7869 "add a nop\n",
7870 loop->loop_no);
7871
7872 last_insn = emit_insn_after (gen_nopv (), last_insn);
7873 }
7874
7875 if (LABEL_P (last_insn))
7876 {
7877 if (dump_file)
7878 fprintf (dump_file, ";; loop %d has a label as last insn; "
7879 "add a nop\n",
7880 loop->loop_no);
7881 last_insn = emit_insn_after (gen_nopv (), last_insn);
7882 }
7883
7884 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7885 and we can use it to indicate the last ZOL instruction cannot be
7886 part of a delay slot. */
7887 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
7888
7889 loop->last_insn = last_insn;
7890
7891 /* Get the loop iteration register. */
7892 iter_reg = loop->iter_reg;
7893
7894 gcc_assert (REG_P (iter_reg));
7895
7896 entry_edge = NULL;
7897
7898 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
7899 if (entry_edge->flags & EDGE_FALLTHRU)
7900 break;
7901
7902 if (entry_edge == NULL)
7903 {
7904 if (dump_file)
7905 fprintf (dump_file, ";; loop %d has no fallthru edge jumping "
7906 "into the loop\n",
7907 loop->loop_no);
7908 return false;
7909 }
7910 /* The loop is good. */
7911 end_label = gen_label_rtx ();
7912 loop->end_label = end_label;
7913
7914 /* Place the zero_cost_loop_start instruction before the loop. */
7915 entry_bb = entry_edge->src;
7916
7917 start_sequence ();
7918
7919 if (need_fix)
7920 {
7921 /* The loop uses a R-register, but the lp_count is free, thus
7922 use lp_count. */
7923 emit_insn (gen_rtx_SET (lp_reg, iter_reg));
7924 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
7925 iter_reg = lp_reg;
7926 if (dump_file)
7927 {
7928 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
7929 loop->loop_no);
7930 }
7931 }
7932
7933 insn = emit_insn (gen_arc_lp (loop->start_label,
7934 loop->end_label));
7935
7936 seq = get_insns ();
7937 end_sequence ();
7938
7939 entry_after = BB_END (entry_bb);
7940 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
7941 || !entry_after)
7942 {
7943 basic_block new_bb;
7944 edge e;
7945 edge_iterator ei;
7946
7947 emit_insn_before (seq, BB_HEAD (loop->head));
7948 seq = emit_label_before (gen_label_rtx (), seq);
7949 new_bb = create_basic_block (seq, insn, entry_bb);
7950 FOR_EACH_EDGE (e, ei, loop->incoming)
7951 {
7952 if (!(e->flags & EDGE_FALLTHRU))
7953 redirect_edge_and_branch_force (e, new_bb);
7954 else
7955 redirect_edge_succ (e, new_bb);
7956 }
7957
7958 make_edge (new_bb, loop->head, 0);
7959 }
7960 else
7961 {
7962 #if 0
7963 while (DEBUG_INSN_P (entry_after)
7964 || (NOTE_P (entry_after)
7965 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
7966 /* Make sure we don't split a call and its corresponding
7967 CALL_ARG_LOCATION note. */
7968 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
7969 entry_after = NEXT_INSN (entry_after);
7970 #endif
7971 entry_after = next_nonnote_insn_bb (entry_after);
7972
7973 gcc_assert (entry_after);
7974 emit_insn_before (seq, entry_after);
7975 }
7976
7977 /* Insert the loop end label before the last instruction of the
7978 loop. */
7979 emit_label_after (end_label, loop->last_insn);
7980 /* Make sure we mark the begining and end label as used. */
7981 LABEL_NUSES (loop->end_label)++;
7982 LABEL_NUSES (loop->start_label)++;
7983
7984 return true;
7985 }
7986
7987 /* A callback for the hw-doloop pass. This function examines INSN; if
7988 it is a loop_end pattern we recognize, return the reg rtx for the
7989 loop counter. Otherwise, return NULL_RTX. */
7990
7991 static rtx
7992 hwloop_pattern_reg (rtx_insn *insn)
7993 {
7994 rtx reg;
7995
7996 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
7997 return NULL_RTX;
7998
7999 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
8000 if (!REG_P (reg))
8001 return NULL_RTX;
8002 return reg;
8003 }
8004
8005 static struct hw_doloop_hooks arc_doloop_hooks =
8006 {
8007 hwloop_pattern_reg,
8008 hwloop_optimize,
8009 hwloop_fail
8010 };
8011
8012 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8013 and tries to rewrite the RTL of these loops so that proper Blackfin
8014 hardware loops are generated. */
8015
8016 static void
8017 arc_reorg_loops (void)
8018 {
8019 reorg_loops (true, &arc_doloop_hooks);
8020 }
8021
8022 /* Scan all calls and add symbols to be emitted in the jli section if
8023 needed. */
8024
8025 static void
8026 jli_call_scan (void)
8027 {
8028 rtx_insn *insn;
8029
8030 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8031 {
8032 if (!CALL_P (insn))
8033 continue;
8034
8035 rtx pat = PATTERN (insn);
8036 if (GET_CODE (pat) == COND_EXEC)
8037 pat = COND_EXEC_CODE (pat);
8038 pat = XVECEXP (pat, 0, 0);
8039 if (GET_CODE (pat) == SET)
8040 pat = SET_SRC (pat);
8041
8042 pat = XEXP (XEXP (pat, 0), 0);
8043 if (GET_CODE (pat) == SYMBOL_REF
8044 && arc_is_jli_call_p (pat))
8045 arc_add_jli_section (pat);
8046 }
8047 }
8048
8049 /* Add padding if necessary to avoid a mispredict. A return could
8050 happen immediately after the function start. A call/return and
8051 return/return must be 6 bytes apart to avoid mispredict. */
8052
8053 static void
8054 pad_return (void)
8055 {
8056 rtx_insn *insn;
8057 long offset;
8058
8059 if (!TARGET_PAD_RETURN)
8060 return;
8061
8062 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8063 {
8064 rtx_insn *prev0 = prev_active_insn (insn);
8065 bool wantlong = false;
8066
8067 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN)
8068 continue;
8069
8070 if (!prev0)
8071 {
8072 prev0 = emit_insn_before (gen_nopv (), insn);
8073 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8074 so it is safe to reuse it for forcing a particular length
8075 for an instruction. */
8076 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8077 emit_insn_before (gen_nopv (), insn);
8078 continue;
8079 }
8080 offset = get_attr_length (prev0);
8081
8082 if (get_attr_length (prev0) == 2
8083 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE)
8084 {
8085 /* Force long version of the insn. */
8086 wantlong = true;
8087 offset += 2;
8088 }
8089
8090 rtx_insn *prev = prev_active_insn (prev0);
8091 if (prev)
8092 offset += get_attr_length (prev);
8093
8094 prev = prev_active_insn (prev);
8095 if (prev)
8096 offset += get_attr_length (prev);
8097
8098 switch (offset)
8099 {
8100 case 2:
8101 prev = emit_insn_before (gen_nopv (), insn);
8102 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1));
8103 break;
8104 case 4:
8105 emit_insn_before (gen_nopv (), insn);
8106 break;
8107 default:
8108 continue;
8109 }
8110
8111 if (wantlong)
8112 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8113
8114 /* Emit a blockage to avoid delay slot scheduling. */
8115 emit_insn_before (gen_blockage (), insn);
8116 }
8117 }
8118
8119 static int arc_reorg_in_progress = 0;
8120
8121 /* ARC's machince specific reorg function. */
8122
8123 static void
8124 arc_reorg (void)
8125 {
8126 rtx_insn *insn;
8127 rtx pattern;
8128 rtx pc_target;
8129 long offset;
8130 int changed;
8131
8132 cfun->machine->arc_reorg_started = 1;
8133 arc_reorg_in_progress = 1;
8134
8135 compute_bb_for_insn ();
8136
8137 df_analyze ();
8138
8139 /* Doloop optimization. */
8140 arc_reorg_loops ();
8141
8142 workaround_arc_anomaly ();
8143 jli_call_scan ();
8144 pad_return ();
8145
8146 /* There are cases when conditional execution is only possible after
8147 delay slot scheduling:
8148
8149 - If a delay slot is filled with a nocond/set insn from above, the previous
8150 basic block can become elegible for conditional execution.
8151 - If a delay slot is filled with a nocond insn from the fall-through path,
8152 the branch with that delay slot can become eligble for conditional
8153 execution (however, with the same sort of data flow analysis that dbr
8154 does, we could have figured out before that we don't need to
8155 conditionalize this insn.)
8156 - If a delay slot insn is filled with an insn from the target, the
8157 target label gets its uses decremented (even deleted if falling to zero),
8158 thus possibly creating more condexec opportunities there.
8159 Therefore, we should still be prepared to apply condexec optimization on
8160 non-prepared branches if the size increase of conditionalized insns is no
8161 more than the size saved from eliminating the branch. An invocation option
8162 could also be used to reserve a bit of extra size for condbranches so that
8163 this'll work more often (could also test in arc_reorg if the block is
8164 'close enough' to be eligible for condexec to make this likely, and
8165 estimate required size increase). */
8166 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8167 if (TARGET_NO_BRCC_SET)
8168 return;
8169
8170 do
8171 {
8172 init_insn_lengths();
8173 changed = 0;
8174
8175 /* Call shorten_branches to calculate the insn lengths. */
8176 shorten_branches (get_insns());
8177
8178 if (!INSN_ADDRESSES_SET_P())
8179 fatal_error (input_location,
8180 "insn addresses not set after shorten branches");
8181
8182 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8183 {
8184 rtx label;
8185 enum attr_type insn_type;
8186
8187 /* If a non-jump insn (or a casesi jump table), continue. */
8188 if (GET_CODE (insn) != JUMP_INSN ||
8189 GET_CODE (PATTERN (insn)) == ADDR_VEC
8190 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
8191 continue;
8192
8193 /* If we already have a brcc, note if it is suitable for brcc_s.
8194 Be a bit generous with the brcc_s range so that we can take
8195 advantage of any code shortening from delay slot scheduling. */
8196 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
8197 {
8198 rtx pat = PATTERN (insn);
8199 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
8200 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
8201
8202 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8203 if ((offset >= -140 && offset < 140)
8204 && rtx_equal_p (XEXP (op, 1), const0_rtx)
8205 && compact_register_operand (XEXP (op, 0), VOIDmode)
8206 && equality_comparison_operator (op, VOIDmode))
8207 PUT_MODE (*ccp, CC_Zmode);
8208 else if (GET_MODE (*ccp) == CC_Zmode)
8209 PUT_MODE (*ccp, CC_ZNmode);
8210 continue;
8211 }
8212 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
8213 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
8214 continue;
8215
8216 /* OK. so we have a jump insn. */
8217 /* We need to check that it is a bcc. */
8218 /* Bcc => set (pc) (if_then_else ) */
8219 pattern = PATTERN (insn);
8220 if (GET_CODE (pattern) != SET
8221 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
8222 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
8223 continue;
8224
8225 /* Now check if the jump is beyond the s9 range. */
8226 if (CROSSING_JUMP_P (insn))
8227 continue;
8228 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8229
8230 if(offset > 253 || offset < -254)
8231 continue;
8232
8233 pc_target = SET_SRC (pattern);
8234
8235 /* Avoid FPU instructions. */
8236 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
8237 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUEmode)
8238 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
8239 continue;
8240
8241 /* Now go back and search for the set cc insn. */
8242
8243 label = XEXP (pc_target, 1);
8244
8245 {
8246 rtx pat;
8247 rtx_insn *scan, *link_insn = NULL;
8248
8249 for (scan = PREV_INSN (insn);
8250 scan && GET_CODE (scan) != CODE_LABEL;
8251 scan = PREV_INSN (scan))
8252 {
8253 if (! INSN_P (scan))
8254 continue;
8255 pat = PATTERN (scan);
8256 if (GET_CODE (pat) == SET
8257 && cc_register (SET_DEST (pat), VOIDmode))
8258 {
8259 link_insn = scan;
8260 break;
8261 }
8262 }
8263 if (!link_insn)
8264 continue;
8265 else
8266 {
8267 /* Check if this is a data dependency. */
8268 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
8269 rtx cmp0, cmp1;
8270
8271 /* Make sure we can use it for brcc insns. */
8272 if (find_reg_note (link_insn, REG_SAVE_NOTE, GEN_INT (3)))
8273 continue;
8274
8275 /* Ok this is the set cc. copy args here. */
8276 op = XEXP (pc_target, 0);
8277
8278 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
8279 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
8280 if (GET_CODE (op0) == ZERO_EXTRACT
8281 && XEXP (op0, 1) == const1_rtx
8282 && (GET_CODE (op) == EQ
8283 || GET_CODE (op) == NE))
8284 {
8285 /* btst / b{eq,ne} -> bbit{0,1} */
8286 op0 = XEXP (cmp0, 0);
8287 op1 = XEXP (cmp0, 2);
8288 }
8289 else if (!register_operand (op0, VOIDmode)
8290 || !general_operand (op1, VOIDmode))
8291 continue;
8292 /* Be careful not to break what cmpsfpx_raw is
8293 trying to create for checking equality of
8294 single-precision floats. */
8295 else if (TARGET_SPFP
8296 && GET_MODE (op0) == SFmode
8297 && GET_MODE (op1) == SFmode)
8298 continue;
8299
8300 /* None of the two cmp operands should be set between the
8301 cmp and the branch. */
8302 if (reg_set_between_p (op0, link_insn, insn))
8303 continue;
8304
8305 if (reg_set_between_p (op1, link_insn, insn))
8306 continue;
8307
8308 /* Since the MODE check does not work, check that this is
8309 CC reg's last set location before insn, and also no
8310 instruction between the cmp and branch uses the
8311 condition codes. */
8312 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
8313 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
8314 continue;
8315
8316 /* CC reg should be dead after insn. */
8317 if (!find_regno_note (insn, REG_DEAD, CC_REG))
8318 continue;
8319
8320 op = gen_rtx_fmt_ee (GET_CODE (op),
8321 GET_MODE (op), cmp0, cmp1);
8322 /* If we create a LIMM where there was none before,
8323 we only benefit if we can avoid a scheduling bubble
8324 for the ARC600. Otherwise, we'd only forgo chances
8325 at short insn generation, and risk out-of-range
8326 branches. */
8327 if (!brcc_nolimm_operator (op, VOIDmode)
8328 && !long_immediate_operand (op1, VOIDmode)
8329 && (TARGET_ARC700
8330 || (TARGET_V2 && optimize_size)
8331 || next_active_insn (link_insn) != insn))
8332 continue;
8333
8334 /* Emit bbit / brcc (or brcc_s if possible).
8335 CC_Zmode indicates that brcc_s is possible. */
8336
8337 if (op0 != cmp0)
8338 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
8339 else if ((offset >= -140 && offset < 140)
8340 && rtx_equal_p (op1, const0_rtx)
8341 && compact_register_operand (op0, VOIDmode)
8342 && (GET_CODE (op) == EQ
8343 || GET_CODE (op) == NE))
8344 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
8345 else
8346 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
8347
8348 brcc_insn
8349 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
8350 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
8351 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
8352 brcc_insn
8353 = gen_rtx_PARALLEL
8354 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
8355 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
8356
8357 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
8358 note = find_reg_note (insn, REG_BR_PROB, 0);
8359 if (note)
8360 {
8361 XEXP (note, 1) = REG_NOTES (brcc_insn);
8362 REG_NOTES (brcc_insn) = note;
8363 }
8364 note = find_reg_note (link_insn, REG_DEAD, op0);
8365 if (note)
8366 {
8367 remove_note (link_insn, note);
8368 XEXP (note, 1) = REG_NOTES (brcc_insn);
8369 REG_NOTES (brcc_insn) = note;
8370 }
8371 note = find_reg_note (link_insn, REG_DEAD, op1);
8372 if (note)
8373 {
8374 XEXP (note, 1) = REG_NOTES (brcc_insn);
8375 REG_NOTES (brcc_insn) = note;
8376 }
8377
8378 changed = 1;
8379
8380 /* Delete the bcc insn. */
8381 set_insn_deleted (insn);
8382
8383 /* Delete the cmp insn. */
8384 set_insn_deleted (link_insn);
8385
8386 }
8387 }
8388 }
8389 /* Clear out insn_addresses. */
8390 INSN_ADDRESSES_FREE ();
8391
8392 } while (changed);
8393
8394 if (INSN_ADDRESSES_SET_P())
8395 fatal_error (input_location, "insn addresses not freed");
8396
8397 arc_reorg_in_progress = 0;
8398 }
8399
8400 /* Check if the operands are valid for BRcc.d generation
8401 Valid Brcc.d patterns are
8402 Brcc.d b, c, s9
8403 Brcc.d b, u6, s9
8404
8405 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
8406 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8407 does not have a delay slot
8408
8409 Assumed precondition: Second operand is either a register or a u6 value. */
8410
8411 bool
8412 valid_brcc_with_delay_p (rtx *operands)
8413 {
8414 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
8415 return false;
8416 return brcc_nolimm_operator (operands[0], VOIDmode);
8417 }
8418
8419 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8420 access DECL using %gp_rel(...)($gp). */
8421
8422 static bool
8423 arc_in_small_data_p (const_tree decl)
8424 {
8425 HOST_WIDE_INT size;
8426 tree attr;
8427
8428 /* Only variables are going into small data area. */
8429 if (TREE_CODE (decl) != VAR_DECL)
8430 return false;
8431
8432 if (TARGET_NO_SDATA_SET)
8433 return false;
8434
8435 /* Disable sdata references to weak variables. */
8436 if (DECL_WEAK (decl))
8437 return false;
8438
8439 /* Don't put constants into the small data section: we want them to
8440 be in ROM rather than RAM. */
8441 if (TREE_READONLY (decl))
8442 return false;
8443
8444 /* To ensure -mvolatile-cache works ld.di does not have a
8445 gp-relative variant. */
8446 if (!TARGET_VOLATILE_CACHE_SET
8447 && TREE_THIS_VOLATILE (decl))
8448 return false;
8449
8450 /* Likewise for uncached data. */
8451 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
8452 if (lookup_attribute ("uncached", attr))
8453 return false;
8454
8455 /* and for aux regs. */
8456 attr = DECL_ATTRIBUTES (decl);
8457 if (lookup_attribute ("aux", attr))
8458 return false;
8459
8460 if (DECL_SECTION_NAME (decl) != 0)
8461 {
8462 const char *name = DECL_SECTION_NAME (decl);
8463 if (strcmp (name, ".sdata") == 0
8464 || strcmp (name, ".sbss") == 0)
8465 return true;
8466 }
8467 /* If it's not public, there's no need to put it in the small data
8468 section. */
8469 else if (TREE_PUBLIC (decl))
8470 {
8471 size = int_size_in_bytes (TREE_TYPE (decl));
8472 return (size > 0 && size <= g_switch_value);
8473 }
8474 return false;
8475 }
8476
8477 /* Return true if OP is an acceptable memory operand for ARCompact
8478 16-bit gp-relative load instructions.
8479 */
8480 /* volatile cache option still to be handled. */
8481
8482 bool
8483 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
8484 {
8485 rtx addr;
8486 int size;
8487 int align = 0;
8488 int mask = 0;
8489
8490 /* Eliminate non-memory operations. */
8491 if (GET_CODE (op) != MEM)
8492 return false;
8493
8494 if (mode == VOIDmode)
8495 mode = GET_MODE (op);
8496
8497 size = GET_MODE_SIZE (mode);
8498
8499 /* dword operations really put out 2 instructions, so eliminate them. */
8500 if (size > UNITS_PER_WORD)
8501 return false;
8502
8503 /* Decode the address now. */
8504 addr = XEXP (op, 0);
8505
8506 if (!legitimate_small_data_address_p (addr, mode))
8507 return false;
8508
8509 if (!short_p || size == 1)
8510 return true;
8511
8512 /* Now check for the alignment, the short loads using gp require the
8513 addresses to be aligned. */
8514 align = get_symbol_alignment (addr);
8515 switch (mode)
8516 {
8517 case E_HImode:
8518 mask = 1;
8519 break;
8520 default:
8521 mask = 3;
8522 break;
8523 }
8524
8525 if (align && ((align & mask) == 0))
8526 return true;
8527 return false;
8528 }
8529
8530 /* Return TRUE if PAT is accessing an aux-reg. */
8531
8532 static bool
8533 arc_is_aux_reg_p (rtx pat)
8534 {
8535 tree attrs = NULL_TREE;
8536 tree addr;
8537
8538 if (!MEM_P (pat))
8539 return false;
8540
8541 /* Get the memory attributes. */
8542 addr = MEM_EXPR (pat);
8543 if (!addr)
8544 return false;
8545
8546 /* Get the attributes. */
8547 if (VAR_P (addr))
8548 attrs = DECL_ATTRIBUTES (addr);
8549 else if (TREE_CODE (addr) == MEM_REF)
8550 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8551 else
8552 return false;
8553
8554 if (lookup_attribute ("aux", attrs))
8555 return true;
8556 return false;
8557 }
8558
8559 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8560
8561 void
8562 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8563 unsigned HOST_WIDE_INT size,
8564 unsigned HOST_WIDE_INT align,
8565 unsigned HOST_WIDE_INT globalize_p)
8566 {
8567 int in_small_data = arc_in_small_data_p (decl);
8568 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8569
8570 /* Don't output aux-reg symbols. */
8571 if (mem != NULL_RTX && MEM_P (mem)
8572 && SYMBOL_REF_P (XEXP (mem, 0))
8573 && arc_is_aux_reg_p (mem))
8574 return;
8575
8576 if (in_small_data)
8577 switch_to_section (get_named_section (NULL, ".sbss", 0));
8578 /* named_section (0,".sbss",0); */
8579 else
8580 switch_to_section (bss_section);
8581
8582 if (globalize_p)
8583 (*targetm.asm_out.globalize_label) (stream, name);
8584
8585 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8586 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8587 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8588 ASM_OUTPUT_LABEL (stream, name);
8589
8590 if (size != 0)
8591 ASM_OUTPUT_SKIP (stream, size);
8592 }
8593
8594 static bool
8595 arc_preserve_reload_p (rtx in)
8596 {
8597 return (GET_CODE (in) == PLUS
8598 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8599 && CONST_INT_P (XEXP (in, 1))
8600 && !((INTVAL (XEXP (in, 1)) & 511)));
8601 }
8602
8603 /* Implement TARGET_REGISTER_MOVE_COST. */
8604
8605 static int
8606 arc_register_move_cost (machine_mode,
8607 reg_class_t from_class, reg_class_t to_class)
8608 {
8609 /* Force an attempt to 'mov Dy,Dx' to spill. */
8610 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
8611 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8612 return 100;
8613
8614 return 2;
8615 }
8616
8617 /* Emit code for an addsi3 instruction with OPERANDS.
8618 COND_P indicates if this will use conditional execution.
8619 Return the length of the instruction.
8620 If OUTPUT_P is false, don't actually output the instruction, just return
8621 its length. */
8622 static int
8623 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8624 {
8625 char format[35];
8626
8627 int match = operands_match_p (operands[0], operands[1]);
8628 int match2 = operands_match_p (operands[0], operands[2]);
8629 int intval = (REG_P (operands[2]) ? 1
8630 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8631 int neg_intval = -intval;
8632 int short_0 = arc_check_short_reg_p (operands[0]);
8633 int short_p = (!cond_p && short_0 && arc_check_short_reg_p (operands[1]));
8634 int ret = 0;
8635
8636 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8637 && REGNO (OP) != 30) \
8638 || !TARGET_V2))
8639
8640 #define ADDSI_OUTPUT1(FORMAT) do {\
8641 if (output_p) \
8642 output_asm_insn (FORMAT, operands);\
8643 return ret; \
8644 } while (0)
8645 #define ADDSI_OUTPUT(LIST) do {\
8646 if (output_p) \
8647 sprintf LIST;\
8648 ADDSI_OUTPUT1 (format);\
8649 return ret; \
8650 } while (0)
8651
8652 /* First try to emit a 16 bit insn. */
8653 ret = 2;
8654 if (!cond_p
8655 /* If we are actually about to output this insn, don't try a 16 bit
8656 variant if we already decided that we don't want that
8657 (I.e. we upsized this insn to align some following insn.)
8658 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8659 but add1 r0,sp,35 doesn't. */
8660 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8661 {
8662 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8663 patterns. */
8664 if (short_p
8665 && ((REG_H_P (operands[2])
8666 && (match || arc_check_short_reg_p (operands[2])))
8667 || (CONST_INT_P (operands[2])
8668 && ((unsigned) intval <= (match ? 127 : 7)))))
8669 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8670
8671 /* Generate add_s b,b,h patterns. */
8672 if (short_0 && match2 && REG_H_P (operands[1]))
8673 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8674
8675 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8676 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8677 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8678 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8679
8680 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8681 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8682 && match && !(neg_intval & ~124)))
8683 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8684
8685 /* Generate add_s h,h,s3 patterns. */
8686 if (REG_H_P (operands[0]) && match && TARGET_V2
8687 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8688 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8689
8690 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8691 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8692 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8693 && arc_check_short_reg_p (operands[1])
8694 && satisfies_constraint_L (operands[2]))
8695 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8696 }
8697
8698 /* Now try to emit a 32 bit insn without long immediate. */
8699 ret = 4;
8700 if (!match && match2 && REG_P (operands[1]))
8701 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8702 if (match || !cond_p)
8703 {
8704 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8705 int range_factor = neg_intval & intval;
8706 int shift;
8707
8708 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8709 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8710
8711 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8712 same size, do, so - the insn latency is lower. */
8713 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8714 0x800 is not. */
8715 if ((intval >= 0 && intval <= limit)
8716 || (intval == -0x800 && limit == 0x7ff))
8717 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8718 else if ((intval < 0 && neg_intval <= limit)
8719 || (intval == 0x800 && limit == 0x7ff))
8720 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8721 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
8722 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
8723 gcc_assert ((((1 << shift) - 1) & intval) == 0);
8724 if (((intval < 0 && intval != -0x4000)
8725 /* sub[123] is slower than add_s / sub, only use it if it
8726 avoids a long immediate. */
8727 && neg_intval <= limit << shift)
8728 || (intval == 0x4000 && limit == 0x7ff))
8729 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
8730 shift, neg_intval >> shift));
8731 else if ((intval >= 0 && intval <= limit << shift)
8732 || (intval == -0x4000 && limit == 0x7ff))
8733 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
8734 }
8735 /* Try to emit a 16 bit opcode with long immediate. */
8736 ret = 6;
8737 if (short_p && match)
8738 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8739
8740 /* We have to use a 32 bit opcode, and with a long immediate. */
8741 ret = 8;
8742 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8743 }
8744
8745 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8746 Return the length of the instruction.
8747 If OUTPUT_P is false, don't actually output the instruction, just return
8748 its length. */
8749 int
8750 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
8751 {
8752 enum rtx_code commutative_op = GET_CODE (operands[3]);
8753 const char *pat = NULL;
8754
8755 /* Canonical rtl should not have a constant in the first operand position. */
8756 gcc_assert (!CONSTANT_P (operands[1]));
8757
8758 switch (commutative_op)
8759 {
8760 case AND:
8761 if (satisfies_constraint_C1p (operands[2]))
8762 pat = "bmsk%? %0,%1,%Z2";
8763 else if (satisfies_constraint_C2p (operands[2]))
8764 {
8765 operands[2] = GEN_INT ((~INTVAL (operands[2])));
8766 pat = "bmskn%? %0,%1,%Z2";
8767 }
8768 else if (satisfies_constraint_Ccp (operands[2]))
8769 pat = "bclr%? %0,%1,%M2";
8770 else if (satisfies_constraint_CnL (operands[2]))
8771 pat = "bic%? %0,%1,%n2-1";
8772 break;
8773 case IOR:
8774 if (satisfies_constraint_C0p (operands[2]))
8775 pat = "bset%? %0,%1,%z2";
8776 break;
8777 case XOR:
8778 if (satisfies_constraint_C0p (operands[2]))
8779 pat = "bxor%? %0,%1,%z2";
8780 break;
8781 case PLUS:
8782 return arc_output_addsi (operands, true, output_p);
8783 default: break;
8784 }
8785 if (output_p)
8786 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
8787 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
8788 return 4;
8789 return 8;
8790 }
8791
8792 /* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
8793 Emit code and return an potentially modified address such that offsets
8794 up to SIZE are can be added to yield a legitimate address.
8795 if REUSE is set, ADDR is a register that may be modified. */
8796
8797 static rtx
8798 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
8799 {
8800 rtx base = addr;
8801 rtx offs = const0_rtx;
8802
8803 if (GET_CODE (base) == PLUS)
8804 {
8805 offs = XEXP (base, 1);
8806 base = XEXP (base, 0);
8807 }
8808 if (!REG_P (base)
8809 || (REGNO (base) != STACK_POINTER_REGNUM
8810 && REGNO_PTR_FRAME_P (REGNO (base)))
8811 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
8812 || !SMALL_INT (INTVAL (offs) + size))
8813 {
8814 if (reuse)
8815 emit_insn (gen_add2_insn (addr, offs));
8816 else
8817 addr = copy_to_mode_reg (Pmode, addr);
8818 }
8819 return addr;
8820 }
8821
8822 /* Like move_by_pieces, but take account of load latency, and actual
8823 offset ranges. Return true on success. */
8824
8825 bool
8826 arc_expand_cpymem (rtx *operands)
8827 {
8828 rtx dst = operands[0];
8829 rtx src = operands[1];
8830 rtx dst_addr, src_addr;
8831 HOST_WIDE_INT size;
8832 int align = INTVAL (operands[3]);
8833 unsigned n_pieces;
8834 int piece = align;
8835 rtx store[2];
8836 rtx tmpx[2];
8837 int i;
8838
8839 if (!CONST_INT_P (operands[2]))
8840 return false;
8841 size = INTVAL (operands[2]);
8842 /* move_by_pieces_ninsns is static, so we can't use it. */
8843 if (align >= 4)
8844 {
8845 if (TARGET_LL64)
8846 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
8847 else
8848 n_pieces = (size + 2) / 4U + (size & 1);
8849 }
8850 else if (align == 2)
8851 n_pieces = (size + 1) / 2U;
8852 else
8853 n_pieces = size;
8854 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
8855 return false;
8856 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8857 possible. */
8858 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
8859 piece = 8;
8860 else if (piece > 4)
8861 piece = 4;
8862 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
8863 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
8864 store[0] = store[1] = NULL_RTX;
8865 tmpx[0] = tmpx[1] = NULL_RTX;
8866 for (i = 0; size > 0; i ^= 1, size -= piece)
8867 {
8868 rtx tmp;
8869 machine_mode mode;
8870
8871 while (piece > size)
8872 piece >>= 1;
8873 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
8874 /* If we don't re-use temporaries, the scheduler gets carried away,
8875 and the register pressure gets unnecessarily high. */
8876 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
8877 tmp = tmpx[i];
8878 else
8879 tmpx[i] = tmp = gen_reg_rtx (mode);
8880 dst_addr = force_offsettable (dst_addr, piece, 1);
8881 src_addr = force_offsettable (src_addr, piece, 1);
8882 if (store[i])
8883 emit_insn (store[i]);
8884 emit_move_insn (tmp, change_address (src, mode, src_addr));
8885 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
8886 dst_addr = plus_constant (Pmode, dst_addr, piece);
8887 src_addr = plus_constant (Pmode, src_addr, piece);
8888 }
8889 if (store[i])
8890 emit_insn (store[i]);
8891 if (store[i^1])
8892 emit_insn (store[i^1]);
8893 return true;
8894 }
8895
8896 static bool
8897 arc_get_aux_arg (rtx pat, int *auxr)
8898 {
8899 tree attr, addr = MEM_EXPR (pat);
8900 if (TREE_CODE (addr) != VAR_DECL)
8901 return false;
8902
8903 attr = DECL_ATTRIBUTES (addr);
8904 if (lookup_attribute ("aux", attr))
8905 {
8906 tree arg = TREE_VALUE (attr);
8907 if (arg)
8908 {
8909 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
8910 return true;
8911 }
8912 }
8913
8914 return false;
8915 }
8916
8917 /* Prepare operands for move in MODE. Return true iff the move has
8918 been emitted. */
8919
8920 bool
8921 prepare_move_operands (rtx *operands, machine_mode mode)
8922 {
8923 if ((MEM_P (operands[0]) || MEM_P (operands[1]))
8924 && SCALAR_INT_MODE_P (mode))
8925 {
8926 /* First handle aux attribute. */
8927 if (mode == SImode)
8928 {
8929 rtx tmp;
8930 int auxr = 0;
8931 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
8932 {
8933 /* Save operation. */
8934 if (arc_get_aux_arg (operands[0], &auxr))
8935 {
8936 tmp = gen_reg_rtx (SImode);
8937 emit_move_insn (tmp, GEN_INT (auxr));
8938 }
8939 else
8940 tmp = XEXP (operands[0], 0);
8941
8942 operands[1] = force_reg (SImode, operands[1]);
8943 emit_insn (gen_rtx_UNSPEC_VOLATILE
8944 (VOIDmode, gen_rtvec (2, operands[1], tmp),
8945 VUNSPEC_ARC_SR));
8946 return true;
8947 }
8948 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
8949 {
8950 if (arc_get_aux_arg (operands[1], &auxr))
8951 {
8952 tmp = gen_reg_rtx (SImode);
8953 emit_move_insn (tmp, GEN_INT (auxr));
8954 }
8955 else
8956 {
8957 tmp = XEXP (operands[1], 0);
8958 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
8959 }
8960 /* Load operation. */
8961 gcc_assert (REG_P (operands[0]));
8962 emit_insn (gen_rtx_SET (operands[0],
8963 gen_rtx_UNSPEC_VOLATILE
8964 (SImode, gen_rtvec (1, tmp),
8965 VUNSPEC_ARC_LR)));
8966 return true;
8967 }
8968 }
8969 /* Second, we check for the uncached. */
8970 if (arc_is_uncached_mem_p (operands[0]))
8971 {
8972 if (!REG_P (operands[1]))
8973 operands[1] = force_reg (mode, operands[1]);
8974 emit_insn (gen_rtx_UNSPEC_VOLATILE
8975 (VOIDmode, gen_rtvec (2, operands[0], operands[1]),
8976 VUNSPEC_ARC_STDI));
8977 return true;
8978 }
8979 if (arc_is_uncached_mem_p (operands[1]))
8980 {
8981 rtx tmp = operands[0];
8982
8983 if (MEM_P (operands[0]))
8984 tmp = gen_reg_rtx (mode);
8985
8986 emit_insn (gen_rtx_SET
8987 (tmp,
8988 gen_rtx_UNSPEC_VOLATILE
8989 (mode, gen_rtvec (1, operands[1]),
8990 VUNSPEC_ARC_LDDI)));
8991 if (MEM_P (operands[0]))
8992 {
8993 operands[1] = tmp;
8994 return false;
8995 }
8996 return true;
8997 }
8998 }
8999
9000 if (GET_CODE (operands[1]) == SYMBOL_REF)
9001 {
9002 enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
9003 if (MEM_P (operands[0]))
9004 operands[1] = force_reg (mode, operands[1]);
9005 else if (model)
9006 operands[1] = arc_legitimize_tls_address (operands[1], model);
9007 }
9008
9009 operands[1] = arc_legitimize_pic_address (operands[1]);
9010
9011 /* Store instructions are limited, they only accept as address an
9012 immediate, a register or a register plus a small immediate. */
9013 if (MEM_P (operands[0])
9014 && !move_dest_operand (operands[0], mode))
9015 {
9016 rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9017 rtx tmp1 = change_address (operands[0], mode, tmp0);
9018 MEM_COPY_ATTRIBUTES (tmp1, operands[0]);
9019 operands[0] = tmp1;
9020 }
9021
9022 /* Check if it is constant but it is not legitimized. */
9023 if (CONSTANT_P (operands[1])
9024 && !arc_legitimate_constant_p (mode, operands[1]))
9025 operands[1] = force_reg (mode, XEXP (operands[1], 0));
9026 else if (MEM_P (operands[0])
9027 && ((CONSTANT_P (operands[1])
9028 && !satisfies_constraint_Cm3 (operands[1]))
9029 || MEM_P (operands[1])))
9030 operands[1] = force_reg (mode, operands[1]);
9031
9032 return false;
9033 }
9034
9035 /* Output a library call to a function called FNAME that has been arranged
9036 to be local to any dso. */
9037
9038 const char *
9039 arc_output_libcall (const char *fname)
9040 {
9041 unsigned len = strlen (fname);
9042 static char buf[64];
9043
9044 gcc_assert (len < sizeof buf - 35);
9045 if (TARGET_LONG_CALLS_SET)
9046 {
9047 if (flag_pic)
9048 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
9049 else
9050 sprintf (buf, "jl%%! @%s", fname);
9051 }
9052 else
9053 sprintf (buf, "bl%%!%%* @%s", fname);
9054 return buf;
9055 }
9056
9057 /* Return the SImode highpart of the DImode value IN. */
9058
9059 rtx
9060 disi_highpart (rtx in)
9061 {
9062 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
9063 }
9064
9065 /* Given a rtx, check if it is an assembly instruction or not. */
9066
9067 static int
9068 arc_asm_insn_p (rtx x)
9069 {
9070 int i, j;
9071
9072 if (x == 0)
9073 return 0;
9074
9075 switch (GET_CODE (x))
9076 {
9077 case ASM_OPERANDS:
9078 case ASM_INPUT:
9079 return 1;
9080
9081 case SET:
9082 return arc_asm_insn_p (SET_SRC (x));
9083
9084 case PARALLEL:
9085 j = 0;
9086 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
9087 j += arc_asm_insn_p (XVECEXP (x, 0, i));
9088 if ( j > 0)
9089 return 1;
9090 break;
9091
9092 default:
9093 break;
9094 }
9095
9096 return 0;
9097 }
9098
9099 /* Return length adjustment for INSN. */
9100
9101 int
9102 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
9103 {
9104 if (!INSN_P (insn))
9105 return len;
9106 /* We already handle sequences by ignoring the delay sequence flag. */
9107 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
9108 return len;
9109
9110 /* Check for return with but one preceding insn since function
9111 start / call. */
9112 if (TARGET_PAD_RETURN
9113 && JUMP_P (insn)
9114 && GET_CODE (PATTERN (insn)) != ADDR_VEC
9115 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
9116 && get_attr_type (insn) == TYPE_RETURN)
9117 {
9118 rtx_insn *prev = prev_active_insn (insn);
9119
9120 if (!prev || !(prev = prev_active_insn (prev))
9121 || ((NONJUMP_INSN_P (prev)
9122 && GET_CODE (PATTERN (prev)) == SEQUENCE)
9123 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9124 NON_SIBCALL)
9125 : CALL_ATTR (prev, NON_SIBCALL)))
9126 return len + 4;
9127 }
9128 if (TARGET_ARC600)
9129 {
9130 rtx_insn *succ = next_real_insn (insn);
9131
9132 /* One the ARC600, a write to an extension register must be separated
9133 from a read. */
9134 if (succ && INSN_P (succ))
9135 len += arc600_corereg_hazard (insn, succ);
9136 }
9137
9138 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9139 can go awry. */
9140 extract_constrain_insn_cached (insn);
9141
9142 return len;
9143 }
9144
9145 /* Return version of PAT conditionalized with COND, which is part of INSN.
9146 ANNULLED indicates if INSN is an annulled delay-slot insn.
9147 Register further changes if necessary. */
9148 static rtx
9149 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
9150 {
9151 /* For commutative operators, we generally prefer to have
9152 the first source match the destination. */
9153 if (GET_CODE (pat) == SET)
9154 {
9155 rtx src = SET_SRC (pat);
9156
9157 if (COMMUTATIVE_P (src))
9158 {
9159 rtx src0 = XEXP (src, 0);
9160 rtx src1 = XEXP (src, 1);
9161 rtx dst = SET_DEST (pat);
9162
9163 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
9164 /* Leave add_n alone - the canonical form is to
9165 have the complex summand first. */
9166 && REG_P (src0))
9167 pat = gen_rtx_SET (dst,
9168 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
9169 src1, src0));
9170 }
9171 }
9172
9173 /* dwarf2out.cc:dwarf2out_frame_debug_expr doesn't know
9174 what to do with COND_EXEC. */
9175 if (RTX_FRAME_RELATED_P (insn))
9176 {
9177 /* If this is the delay slot insn of an anulled branch,
9178 dwarf2out.cc:scan_trace understands the anulling semantics
9179 without the COND_EXEC. */
9180 gcc_assert (annulled);
9181 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
9182 REG_NOTES (insn));
9183 validate_change (insn, &REG_NOTES (insn), note, 1);
9184 }
9185 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9186 return pat;
9187 }
9188
9189
9190 /* Find annulled delay insns and convert them to use the appropriate predicate.
9191 This allows branch shortening to size up these insns properly. */
9192
9193 static unsigned
9194 arc_predicate_delay_insns (void)
9195 {
9196 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9197 {
9198 rtx pat, jump, dlay, src, cond, *patp;
9199 int reverse;
9200
9201 if (!NONJUMP_INSN_P (insn)
9202 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9203 continue;
9204 jump = XVECEXP (pat, 0, 0);
9205 dlay = XVECEXP (pat, 0, 1);
9206 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9207 continue;
9208 /* If the branch insn does the annulling, leave the delay insn alone. */
9209 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9210 continue;
9211 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9212 on the other path. */
9213 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9214 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9215 src = SET_SRC (PATTERN (jump));
9216 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9217 cond = XEXP (src, 0);
9218 if (XEXP (src, 2) == pc_rtx)
9219 reverse = 0;
9220 else if (XEXP (src, 1) == pc_rtx)
9221 reverse = 1;
9222 else
9223 gcc_unreachable ();
9224 if (reverse != !INSN_FROM_TARGET_P (dlay))
9225 {
9226 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9227 enum rtx_code code = reverse_condition (GET_CODE (cond));
9228 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9229 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9230
9231 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9232 copy_rtx (XEXP (cond, 0)),
9233 copy_rtx (XEXP (cond, 1)));
9234 }
9235 else
9236 cond = copy_rtx (cond);
9237 patp = &PATTERN (dlay);
9238 pat = *patp;
9239 pat = conditionalize_nonjump (pat, cond, dlay, true);
9240 validate_change (dlay, patp, pat, 1);
9241 if (!apply_change_group ())
9242 gcc_unreachable ();
9243 }
9244 return 0;
9245 }
9246
9247 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9248 (other than of a forward brcc), it creates a hazard when there is a read
9249 of the same register at the branch target. We can't know what is at the
9250 branch target of calls, and for branches, we don't really know before the
9251 end of delay slot scheduling, either. Not only can individual instruction
9252 be hoisted out into a delay slot, a basic block can also be emptied this
9253 way, and branch and/or fall through targets be redirected. Hence we don't
9254 want such writes in a delay slot. */
9255
9256 /* Return nonzreo iff INSN writes to an extension core register. */
9257
9258 int
9259 arc_write_ext_corereg (rtx insn)
9260 {
9261 subrtx_iterator::array_type array;
9262 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9263 {
9264 const_rtx x = *iter;
9265 switch (GET_CODE (x))
9266 {
9267 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9268 break;
9269 default:
9270 /* This is also fine for PRE/POST_MODIFY, because they
9271 contain a SET. */
9272 continue;
9273 }
9274 const_rtx dest = XEXP (x, 0);
9275 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9276 return 1;
9277 }
9278 return 0;
9279 }
9280
9281 /* This is like the hook, but returns NULL when it can't / won't generate
9282 a legitimate address. */
9283
9284 static rtx
9285 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9286 machine_mode mode)
9287 {
9288 rtx addr, inner;
9289
9290 addr = x;
9291 if (GET_CODE (addr) == CONST)
9292 addr = XEXP (addr, 0);
9293
9294 if (GET_CODE (addr) == PLUS
9295 && CONST_INT_P (XEXP (addr, 1))
9296 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9297 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9298 || (REG_P (XEXP (addr, 0))
9299 && (INTVAL (XEXP (addr, 1)) & 252))))
9300 {
9301 HOST_WIDE_INT offs, upper;
9302 int size = GET_MODE_SIZE (mode);
9303
9304 offs = INTVAL (XEXP (addr, 1));
9305 upper = (offs + 256 * size) & ~511 * size;
9306 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9307 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9308 if (GET_CODE (x) == CONST)
9309 inner = gen_rtx_CONST (Pmode, inner);
9310 #endif
9311 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9312 x = addr;
9313 }
9314 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9315 x = force_reg (Pmode, x);
9316 if (memory_address_p ((machine_mode) mode, x))
9317 return x;
9318 return NULL_RTX;
9319 }
9320
9321 static rtx
9322 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9323 {
9324 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9325
9326 if (new_x)
9327 return new_x;
9328 return orig_x;
9329 }
9330
9331 static rtx
9332 arc_delegitimize_address_0 (rtx op)
9333 {
9334 switch (GET_CODE (op))
9335 {
9336 case CONST:
9337 return arc_delegitimize_address_0 (XEXP (op, 0));
9338
9339 case UNSPEC:
9340 switch (XINT (op, 1))
9341 {
9342 case ARC_UNSPEC_GOT:
9343 case ARC_UNSPEC_GOTOFFPC:
9344 return XVECEXP (op, 0, 0);
9345 default:
9346 break;
9347 }
9348 break;
9349
9350 case PLUS:
9351 {
9352 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9353 rtx t2 = XEXP (op, 1);
9354
9355 if (t1 && t2)
9356 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9357 break;
9358 }
9359
9360 default:
9361 break;
9362 }
9363 return NULL_RTX;
9364 }
9365
9366 static rtx
9367 arc_delegitimize_address (rtx orig_x)
9368 {
9369 rtx x = orig_x;
9370
9371 if (MEM_P (x))
9372 x = XEXP (x, 0);
9373
9374 x = arc_delegitimize_address_0 (x);
9375 if (!x)
9376 return orig_x;
9377
9378 if (MEM_P (orig_x))
9379 x = replace_equiv_address_nv (orig_x, x);
9380 return x;
9381 }
9382
9383 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9384 differ from the hardware register number in order to allow the generic
9385 code to correctly split the concatenation of acc1 and acc2. */
9386
9387 rtx
9388 gen_acc1 (void)
9389 {
9390 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9391 }
9392
9393 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9394 differ from the hardware register number in order to allow the generic
9395 code to correctly split the concatenation of acc1 and acc2. */
9396
9397 rtx
9398 gen_acc2 (void)
9399 {
9400 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9401 }
9402
9403 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9404 are three reasons why we need to consider branches to be length 6:
9405 - annull-false delay slot insns are implemented using conditional execution,
9406 thus preventing short insn formation where used.
9407 - for ARC600: annul-true delay slot insns are implemented where possible
9408 using conditional execution, preventing short insn formation where used.
9409 - for ARC700: likely or somewhat likely taken branches are made long and
9410 unaligned if possible to avoid branch penalty. */
9411
9412 bool
9413 arc_branch_size_unknown_p (void)
9414 {
9415 return !optimize_size && arc_reorg_in_progress;
9416 }
9417
9418 /* The usual; we set up our machine_function data. */
9419
9420 static struct machine_function *
9421 arc_init_machine_status (void)
9422 {
9423 struct machine_function *machine;
9424 machine = ggc_cleared_alloc<machine_function> ();
9425 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9426
9427 return machine;
9428 }
9429
9430 /* Implements INIT_EXPANDERS. We just set up to call the above
9431 function. */
9432
9433 void
9434 arc_init_expanders (void)
9435 {
9436 init_machine_status = arc_init_machine_status;
9437 }
9438
9439 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9440 indicates a number of elements to ignore - that allows to have a
9441 sibcall pattern that starts with (return). LOAD_P is zero for store
9442 multiple (for prologues), and one for load multiples (for epilogues),
9443 and two for load multiples where no final clobber of blink is required.
9444 We also skip the first load / store element since this is supposed to
9445 be checked in the instruction pattern. */
9446
9447 int
9448 arc_check_millicode (rtx op, int offset, int load_p)
9449 {
9450 int len = XVECLEN (op, 0) - offset;
9451 int i;
9452
9453 if (load_p == 2)
9454 {
9455 if (len < 2 || len > 13)
9456 return 0;
9457 load_p = 1;
9458 }
9459 else
9460 {
9461 rtx elt = XVECEXP (op, 0, --len);
9462
9463 if (GET_CODE (elt) != CLOBBER
9464 || !REG_P (XEXP (elt, 0))
9465 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9466 || len < 3 || len > 13)
9467 return 0;
9468 }
9469 for (i = 1; i < len; i++)
9470 {
9471 rtx elt = XVECEXP (op, 0, i + offset);
9472 rtx reg, mem, addr;
9473
9474 if (GET_CODE (elt) != SET)
9475 return 0;
9476 mem = XEXP (elt, load_p);
9477 reg = XEXP (elt, 1-load_p);
9478 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9479 return 0;
9480 addr = XEXP (mem, 0);
9481 if (GET_CODE (addr) != PLUS
9482 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9483 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9484 return 0;
9485 }
9486 return 1;
9487 }
9488
9489 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9490 constant in operand 1, but which would require a LIMM because of
9491 operand mismatch.
9492 operands 3 and 4 are new SET_SRCs for operands 0. */
9493
9494 void
9495 split_subsi (rtx *operands)
9496 {
9497 int val = INTVAL (operands[1]);
9498
9499 /* Try for two short insns first. Lengths being equal, we prefer
9500 expansions with shorter register lifetimes. */
9501 if (arc_check_short_reg_p (operands[0])
9502 && arc_check_short_reg_p (operands[2]))
9503 {
9504 if (val >= -31 && val <= 127)
9505 {
9506 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9507 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9508 return;
9509 }
9510 else if (val >= 0 && val < 255)
9511 {
9512 operands[3] = operands[1];
9513 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9514 return;
9515 }
9516 }
9517 /* If the destination is not an ARCompact16 register, we might
9518 still have a chance to make a short insn if the source is;
9519 we need to start with a reg-reg move for this. */
9520 operands[3] = operands[2];
9521 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9522 }
9523
9524 /* Handle DOUBLE_REGS uses.
9525 Operand 0: destination register
9526 Operand 1: source register */
9527
9528 static bool
9529 arc_process_double_reg_moves (rtx *operands)
9530 {
9531 enum usesDxState { none, srcDx, destDx, maxDx };
9532 enum usesDxState state = none;
9533 rtx dest = operands[0];
9534 rtx src = operands[1];
9535
9536 if (refers_to_regno_p (40, 44, src, 0))
9537 {
9538 state = srcDx;
9539 gcc_assert (REG_P (dest));
9540 }
9541 if (refers_to_regno_p (40, 44, dest, 0))
9542 {
9543 /* Via arc_register_move_cost, we should never see D,D moves. */
9544 gcc_assert (REG_P (src));
9545 gcc_assert (state == none);
9546 state = destDx;
9547 }
9548
9549 if (state == none)
9550 return false;
9551
9552 if (state == srcDx)
9553 {
9554 /* Without the LR insn, we need to split this into a
9555 sequence of insns which will use the DEXCLx and DADDHxy
9556 insns to be able to read the Dx register in question. */
9557 if (TARGET_DPFP_DISABLE_LRSR)
9558 {
9559 /* gen *movdf_insn_nolrsr */
9560 rtx set = gen_rtx_SET (dest, src);
9561 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9562 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9563 }
9564 else
9565 {
9566 /* When we have 'mov D, r' or 'mov D, D' then get the target
9567 register pair for use with LR insn. */
9568 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9569 TARGET_BIG_ENDIAN ? 0 : 4);
9570 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9571 TARGET_BIG_ENDIAN ? 4 : 0);
9572
9573 /* Produce the two LR insns to get the high and low parts. */
9574 emit_insn (gen_rtx_SET (destHigh,
9575 gen_rtx_UNSPEC_VOLATILE (Pmode,
9576 gen_rtvec (1, src),
9577 VUNSPEC_ARC_LR_HIGH)));
9578 emit_insn (gen_rtx_SET (destLow,
9579 gen_rtx_UNSPEC_VOLATILE (Pmode,
9580 gen_rtvec (1, src),
9581 VUNSPEC_ARC_LR)));
9582 }
9583 }
9584 else if (state == destDx)
9585 {
9586 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9587 LR insn get the target register pair. */
9588 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9589 TARGET_BIG_ENDIAN ? 0 : 4);
9590 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9591 TARGET_BIG_ENDIAN ? 4 : 0);
9592
9593 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9594 }
9595 else
9596 gcc_unreachable ();
9597
9598 return true;
9599 }
9600
9601
9602 /* Check if we need to split a 64bit move. We do not need to split it if we can
9603 use vadd2 or ldd/std instructions. */
9604
9605 bool
9606 arc_split_move_p (rtx *operands)
9607 {
9608 machine_mode mode = GET_MODE (operands[0]);
9609
9610 if (TARGET_LL64
9611 && ((memory_operand (operands[0], mode)
9612 && (even_register_operand (operands[1], mode)
9613 || satisfies_constraint_Cm3 (operands[1])))
9614 || (memory_operand (operands[1], mode)
9615 && even_register_operand (operands[0], mode))))
9616 return false;
9617
9618 if (TARGET_PLUS_QMACW
9619 && even_register_operand (operands[0], mode)
9620 && even_register_operand (operands[1], mode))
9621 return false;
9622
9623 return true;
9624 }
9625
9626 /* operands 0..1 are the operands of a 64 bit move instruction.
9627 split it into two moves with operands 2/3 and 4/5. */
9628
9629 void
9630 arc_split_move (rtx *operands)
9631 {
9632 machine_mode mode = GET_MODE (operands[0]);
9633 int i;
9634 int swap = 0;
9635 rtx xop[4];
9636
9637 if (TARGET_DPFP)
9638 {
9639 if (arc_process_double_reg_moves (operands))
9640 return;
9641 }
9642
9643 if (TARGET_PLUS_QMACW
9644 && GET_CODE (operands[1]) == CONST_VECTOR)
9645 {
9646 HOST_WIDE_INT intval0, intval1;
9647 if (GET_MODE (operands[1]) == V2SImode)
9648 {
9649 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9650 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9651 }
9652 else
9653 {
9654 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9655 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9656 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9657 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9658 }
9659 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9660 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9661 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9662 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9663 emit_move_insn (xop[0], xop[2]);
9664 emit_move_insn (xop[3], xop[1]);
9665 return;
9666 }
9667
9668 for (i = 0; i < 2; i++)
9669 {
9670 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9671 {
9672 rtx addr = XEXP (operands[i], 0);
9673 rtx r, o;
9674 enum rtx_code code;
9675
9676 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9677 switch (GET_CODE (addr))
9678 {
9679 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9680 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9681 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9682 pre_modify:
9683 code = PRE_MODIFY;
9684 break;
9685 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9686 case POST_INC: o = GEN_INT (8); goto post_modify;
9687 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9688 post_modify:
9689 code = POST_MODIFY;
9690 swap = 2;
9691 break;
9692 default:
9693 gcc_unreachable ();
9694 }
9695 r = XEXP (addr, 0);
9696 xop[0+i] = adjust_automodify_address_nv
9697 (operands[i], SImode,
9698 gen_rtx_fmt_ee (code, Pmode, r,
9699 gen_rtx_PLUS (Pmode, r, o)),
9700 0);
9701 xop[2+i] = adjust_automodify_address_nv
9702 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9703 }
9704 else
9705 {
9706 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9707 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9708 }
9709 }
9710 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9711 {
9712 swap = 2;
9713 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9714 }
9715
9716 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9717 emit_move_insn (xop[2 - swap], xop[3 - swap]);
9718
9719 }
9720
9721 /* Select between the instruction output templates s_tmpl (for short INSNs)
9722 and l_tmpl (for long INSNs). */
9723
9724 const char *
9725 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
9726 {
9727 int is_short = arc_verify_short (insn, -1);
9728
9729 extract_constrain_insn_cached (insn);
9730 return is_short ? s_tmpl : l_tmpl;
9731 }
9732
9733 /* Searches X for any reference to REGNO, returning the rtx of the
9734 reference found if any. Otherwise, returns NULL_RTX. */
9735
9736 rtx
9737 arc_regno_use_in (unsigned int regno, rtx x)
9738 {
9739 const char *fmt;
9740 int i, j;
9741 rtx tem;
9742
9743 if (REG_P (x) && refers_to_regno_p (regno, x))
9744 return x;
9745
9746 fmt = GET_RTX_FORMAT (GET_CODE (x));
9747 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9748 {
9749 if (fmt[i] == 'e')
9750 {
9751 if ((tem = regno_use_in (regno, XEXP (x, i))))
9752 return tem;
9753 }
9754 else if (fmt[i] == 'E')
9755 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9756 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9757 return tem;
9758 }
9759
9760 return NULL_RTX;
9761 }
9762
9763 /* Code has a minimum p2 alignment of 1, which we must restore after
9764 an ADDR_DIFF_VEC. */
9765
9766 int
9767 arc_label_align (rtx_insn *label)
9768 {
9769 if (align_labels.levels[0].log < 1)
9770 {
9771 rtx_insn *next = next_nonnote_nondebug_insn (label);
9772 if (INSN_P (next) && recog_memoized (next) >= 0)
9773 return 1;
9774 }
9775 return align_labels.levels[0].log;
9776 }
9777
9778 /* Return true if LABEL is in executable code. */
9779
9780 bool
9781 arc_text_label (rtx_insn *label)
9782 {
9783 rtx_insn *next;
9784
9785 /* ??? We use deleted labels like they were still there, see
9786 gcc.c-torture/compile/20000326-2.c . */
9787 gcc_assert (GET_CODE (label) == CODE_LABEL
9788 || (GET_CODE (label) == NOTE
9789 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9790 next = next_nonnote_insn (label);
9791 if (next)
9792 return (!JUMP_TABLE_DATA_P (next)
9793 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9794 else if (!PREV_INSN (label))
9795 /* ??? sometimes text labels get inserted very late, see
9796 gcc.dg/torture/stackalign/comp-goto-1.c */
9797 return true;
9798 return false;
9799 }
9800
9801 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9802 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9803 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9804 to redirect two breqs. */
9805
9806 static bool
9807 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
9808 {
9809 /* ??? get_attr_type is declared to take an rtx. */
9810 union { const rtx_insn *c; rtx_insn *r; } u;
9811
9812 u.c = follower;
9813 if (CROSSING_JUMP_P (followee))
9814 switch (get_attr_type (u.r))
9815 {
9816 case TYPE_BRANCH:
9817 if (get_attr_length (u.r) != 2)
9818 break;
9819 /* Fall through. */
9820 case TYPE_BRCC:
9821 case TYPE_BRCC_NO_DELAY_SLOT:
9822 return false;
9823 default:
9824 return true;
9825 }
9826 return true;
9827 }
9828
9829
9830 /* Implement EPILOGUE_USES.
9831 Return true if REGNO should be added to the deemed uses of the epilogue.
9832
9833 We have to make sure all the register restore instructions are
9834 known to be live in interrupt functions, plus the blink register if
9835 it is clobbered by the isr. */
9836
9837 bool
9838 arc_epilogue_uses (int regno)
9839 {
9840 unsigned int fn_type;
9841 fn_type = arc_compute_function_type (cfun);
9842
9843 if (regno == arc_tp_regno)
9844 return true;
9845
9846 if (regno == RETURN_ADDR_REGNUM)
9847 return true;
9848
9849 if (regno == arc_return_address_register (fn_type))
9850 return true;
9851
9852 if (epilogue_completed && ARC_INTERRUPT_P (fn_type))
9853 {
9854 /* An interrupt function restores more registers. */
9855 if (df_regs_ever_live_p (regno) || call_used_or_fixed_reg_p (regno))
9856 return true;
9857 }
9858
9859 return false;
9860 }
9861
9862 /* Helper for EH_USES macro. */
9863
9864 bool
9865 arc_eh_uses (int regno)
9866 {
9867 if (regno == arc_tp_regno)
9868 return true;
9869 return false;
9870 }
9871
9872 /* Return true if we use LRA instead of reload pass. */
9873
9874 bool
9875 arc_lra_p (void)
9876 {
9877 return arc_lra_flag;
9878 }
9879
9880 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to
9881 use q registers, because some insn are shorter with them. OTOH we
9882 already have separate alternatives for this purpose, and other
9883 insns don't mind, so maybe we should rather prefer the other
9884 registers? We need more data, and we can only get that if we allow
9885 people to try all options. */
9886 static int
9887 arc_register_priority (int r)
9888 {
9889 switch (arc_lra_priority_tag)
9890 {
9891 case ARC_LRA_PRIORITY_NONE:
9892 return 0;
9893 case ARC_LRA_PRIORITY_NONCOMPACT:
9894 return ((((r & 7) ^ 4) - 4) & 15) != r;
9895 case ARC_LRA_PRIORITY_COMPACT:
9896 return ((((r & 7) ^ 4) - 4) & 15) == r;
9897 default:
9898 gcc_unreachable ();
9899 }
9900 }
9901
9902 static reg_class_t
9903 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
9904 {
9905 return GENERAL_REGS;
9906 }
9907
9908 bool
9909 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
9910 int itype)
9911 {
9912 rtx x = *p;
9913 enum reload_type type = (enum reload_type) itype;
9914
9915 if (GET_CODE (x) == PLUS
9916 && CONST_INT_P (XEXP (x, 1))
9917 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9918 || (REG_P (XEXP (x, 0))
9919 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9920 {
9921 int scale = GET_MODE_SIZE (mode);
9922 int shift;
9923 rtx index_rtx = XEXP (x, 1);
9924 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9925 rtx reg, sum, sum2;
9926
9927 if (scale > 4)
9928 scale = 4;
9929 if ((scale-1) & offset)
9930 scale = 1;
9931 shift = scale >> 1;
9932 offset_base
9933 = ((offset + (256 << shift))
9934 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
9935 /* Sometimes the normal form does not suit DImode. We
9936 could avoid that by using smaller ranges, but that
9937 would give less optimized code when SImode is
9938 prevalent. */
9939 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9940 {
9941 int regno;
9942
9943 reg = XEXP (x, 0);
9944 regno = REGNO (reg);
9945 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9946
9947 if (reg_equiv_constant (regno))
9948 {
9949 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9950 offset_base);
9951 if (GET_CODE (sum2) == PLUS)
9952 sum2 = gen_rtx_CONST (Pmode, sum2);
9953 }
9954 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9955 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9956 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9957 type);
9958 return true;
9959 }
9960 }
9961 /* We must re-recognize what we created before. */
9962 else if (GET_CODE (x) == PLUS
9963 && GET_CODE (XEXP (x, 0)) == PLUS
9964 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9965 && REG_P (XEXP (XEXP (x, 0), 0))
9966 && CONST_INT_P (XEXP (x, 1)))
9967 {
9968 /* Because this address is so complex, we know it must have
9969 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9970 it is already unshared, and needs no further unsharing. */
9971 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9972 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
9973 return true;
9974 }
9975 return false;
9976 }
9977
9978 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9979
9980 static bool
9981 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
9982 unsigned int align,
9983 enum by_pieces_operation op,
9984 bool speed_p)
9985 {
9986 /* Let the cpymem expander handle small block moves. */
9987 if (op == MOVE_BY_PIECES)
9988 return false;
9989
9990 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
9991 }
9992
9993 /* Emit a (pre) memory barrier around an atomic sequence according to
9994 MODEL. */
9995
9996 static void
9997 arc_pre_atomic_barrier (enum memmodel model)
9998 {
9999 if (need_atomic_barrier_p (model, true))
10000 emit_insn (gen_memory_barrier ());
10001 }
10002
10003 /* Emit a (post) memory barrier around an atomic sequence according to
10004 MODEL. */
10005
10006 static void
10007 arc_post_atomic_barrier (enum memmodel model)
10008 {
10009 if (need_atomic_barrier_p (model, false))
10010 emit_insn (gen_memory_barrier ());
10011 }
10012
10013 /* Expand a compare and swap pattern. */
10014
10015 static void
10016 emit_unlikely_jump (rtx insn)
10017 {
10018 rtx_insn *jump = emit_jump_insn (insn);
10019 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10020 }
10021
10022 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10023 32-bit compare and swap on the word containing the byte or
10024 half-word. The difference between a weak and a strong CAS is that
10025 the weak version may simply fail. The strong version relies on two
10026 loops, one checks if the SCOND op is succsfully or not, the other
10027 checks if the 32 bit accessed location which contains the 8 or 16
10028 bit datum is not changed by other thread. The first loop is
10029 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10030 loops is implemented by this routine. */
10031
10032 static void
10033 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10034 rtx oldval, rtx newval, rtx weak,
10035 rtx mod_s, rtx mod_f)
10036 {
10037 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10038 rtx addr = gen_reg_rtx (Pmode);
10039 rtx off = gen_reg_rtx (SImode);
10040 rtx oldv = gen_reg_rtx (SImode);
10041 rtx newv = gen_reg_rtx (SImode);
10042 rtx oldvalue = gen_reg_rtx (SImode);
10043 rtx newvalue = gen_reg_rtx (SImode);
10044 rtx res = gen_reg_rtx (SImode);
10045 rtx resv = gen_reg_rtx (SImode);
10046 rtx memsi, val, mask, end_label, loop_label, cc, x;
10047 machine_mode mode;
10048 bool is_weak = (weak != const0_rtx);
10049
10050 /* Truncate the address. */
10051 emit_insn (gen_rtx_SET (addr,
10052 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10053
10054 /* Compute the datum offset. */
10055 emit_insn (gen_rtx_SET (off,
10056 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10057 if (TARGET_BIG_ENDIAN)
10058 emit_insn (gen_rtx_SET (off,
10059 gen_rtx_MINUS (SImode,
10060 (GET_MODE (mem) == QImode) ?
10061 GEN_INT (3) : GEN_INT (2), off)));
10062
10063 /* Normal read from truncated address. */
10064 memsi = gen_rtx_MEM (SImode, addr);
10065 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10066 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10067
10068 val = copy_to_reg (memsi);
10069
10070 /* Convert the offset in bits. */
10071 emit_insn (gen_rtx_SET (off,
10072 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10073
10074 /* Get the proper mask. */
10075 if (GET_MODE (mem) == QImode)
10076 mask = force_reg (SImode, GEN_INT (0xff));
10077 else
10078 mask = force_reg (SImode, GEN_INT (0xffff));
10079
10080 emit_insn (gen_rtx_SET (mask,
10081 gen_rtx_ASHIFT (SImode, mask, off)));
10082
10083 /* Prepare the old and new values. */
10084 emit_insn (gen_rtx_SET (val,
10085 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10086 val)));
10087
10088 oldval = gen_lowpart (SImode, oldval);
10089 emit_insn (gen_rtx_SET (oldv,
10090 gen_rtx_ASHIFT (SImode, oldval, off)));
10091
10092 newval = gen_lowpart_common (SImode, newval);
10093 emit_insn (gen_rtx_SET (newv,
10094 gen_rtx_ASHIFT (SImode, newval, off)));
10095
10096 emit_insn (gen_rtx_SET (oldv,
10097 gen_rtx_AND (SImode, oldv, mask)));
10098
10099 emit_insn (gen_rtx_SET (newv,
10100 gen_rtx_AND (SImode, newv, mask)));
10101
10102 if (!is_weak)
10103 {
10104 end_label = gen_label_rtx ();
10105 loop_label = gen_label_rtx ();
10106 emit_label (loop_label);
10107 }
10108
10109 /* Make the old and new values. */
10110 emit_insn (gen_rtx_SET (oldvalue,
10111 gen_rtx_IOR (SImode, oldv, val)));
10112
10113 emit_insn (gen_rtx_SET (newvalue,
10114 gen_rtx_IOR (SImode, newv, val)));
10115
10116 /* Try an 32bit atomic compare and swap. It clobbers the CC
10117 register. */
10118 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10119 weak, mod_s, mod_f));
10120
10121 /* Regardless of the weakness of the operation, a proper boolean
10122 result needs to be provided. */
10123 x = gen_rtx_REG (CC_Zmode, CC_REG);
10124 x = gen_rtx_EQ (SImode, x, const0_rtx);
10125 emit_insn (gen_rtx_SET (bool_result, x));
10126
10127 if (!is_weak)
10128 {
10129 /* Check the results: if the atomic op is successfully the goto
10130 to end label. */
10131 x = gen_rtx_REG (CC_Zmode, CC_REG);
10132 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10133 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10134 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10135 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10136
10137 /* Wait for the right moment when the accessed 32-bit location
10138 is stable. */
10139 emit_insn (gen_rtx_SET (resv,
10140 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10141 res)));
10142 mode = SELECT_CC_MODE (NE, resv, val);
10143 cc = gen_rtx_REG (mode, CC_REG);
10144 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10145
10146 /* Set the new value of the 32 bit location, proper masked. */
10147 emit_insn (gen_rtx_SET (val, resv));
10148
10149 /* Try again if location is unstable. Fall through if only
10150 scond op failed. */
10151 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10152 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10153 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10154 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10155
10156 emit_label (end_label);
10157 }
10158
10159 /* End: proper return the result for the given mode. */
10160 emit_insn (gen_rtx_SET (res,
10161 gen_rtx_AND (SImode, res, mask)));
10162
10163 emit_insn (gen_rtx_SET (res,
10164 gen_rtx_LSHIFTRT (SImode, res, off)));
10165
10166 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10167 }
10168
10169 /* Helper function used by "atomic_compare_and_swap" expand
10170 pattern. */
10171
10172 void
10173 arc_expand_compare_and_swap (rtx operands[])
10174 {
10175 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10176 machine_mode mode;
10177
10178 bval = operands[0];
10179 rval = operands[1];
10180 mem = operands[2];
10181 oldval = operands[3];
10182 newval = operands[4];
10183 is_weak = operands[5];
10184 mod_s = operands[6];
10185 mod_f = operands[7];
10186 mode = GET_MODE (mem);
10187
10188 if (reg_overlap_mentioned_p (rval, oldval))
10189 oldval = copy_to_reg (oldval);
10190
10191 if (mode == SImode)
10192 {
10193 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10194 is_weak, mod_s, mod_f));
10195 x = gen_rtx_REG (CC_Zmode, CC_REG);
10196 x = gen_rtx_EQ (SImode, x, const0_rtx);
10197 emit_insn (gen_rtx_SET (bval, x));
10198 }
10199 else
10200 {
10201 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10202 is_weak, mod_s, mod_f);
10203 }
10204 }
10205
10206 /* Helper function used by the "atomic_compare_and_swapsi_1"
10207 pattern. */
10208
10209 void
10210 arc_split_compare_and_swap (rtx operands[])
10211 {
10212 rtx rval, mem, oldval, newval;
10213 machine_mode mode;
10214 enum memmodel mod_s, mod_f;
10215 bool is_weak;
10216 rtx label1, label2, x, cond;
10217
10218 rval = operands[0];
10219 mem = operands[1];
10220 oldval = operands[2];
10221 newval = operands[3];
10222 is_weak = (operands[4] != const0_rtx);
10223 mod_s = (enum memmodel) INTVAL (operands[5]);
10224 mod_f = (enum memmodel) INTVAL (operands[6]);
10225 mode = GET_MODE (mem);
10226
10227 /* ARC atomic ops work only with 32-bit aligned memories. */
10228 gcc_assert (mode == SImode);
10229
10230 arc_pre_atomic_barrier (mod_s);
10231
10232 label1 = NULL_RTX;
10233 if (!is_weak)
10234 {
10235 label1 = gen_label_rtx ();
10236 emit_label (label1);
10237 }
10238 label2 = gen_label_rtx ();
10239
10240 /* Load exclusive. */
10241 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10242
10243 /* Check if it is oldval. */
10244 mode = SELECT_CC_MODE (NE, rval, oldval);
10245 cond = gen_rtx_REG (mode, CC_REG);
10246 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10247
10248 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10249 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10250 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10251 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10252
10253 /* Exclusively store new item. Store clobbers CC reg. */
10254 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10255
10256 if (!is_weak)
10257 {
10258 /* Check the result of the store. */
10259 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10260 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10261 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10262 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10263 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10264 }
10265
10266 if (mod_f != MEMMODEL_RELAXED)
10267 emit_label (label2);
10268
10269 arc_post_atomic_barrier (mod_s);
10270
10271 if (mod_f == MEMMODEL_RELAXED)
10272 emit_label (label2);
10273 }
10274
10275 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10276 to perform. MEM is the memory on which to operate. VAL is the second
10277 operand of the binary operator. BEFORE and AFTER are optional locations to
10278 return the value of MEM either before of after the operation. MODEL_RTX
10279 is a CONST_INT containing the memory model to use. */
10280
10281 void
10282 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10283 rtx orig_before, rtx orig_after, rtx model_rtx)
10284 {
10285 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10286 machine_mode mode = GET_MODE (mem);
10287 rtx label, x, cond;
10288 rtx before = orig_before, after = orig_after;
10289
10290 /* ARC atomic ops work only with 32-bit aligned memories. */
10291 gcc_assert (mode == SImode);
10292
10293 arc_pre_atomic_barrier (model);
10294
10295 label = gen_label_rtx ();
10296 emit_label (label);
10297 label = gen_rtx_LABEL_REF (VOIDmode, label);
10298
10299 if (before == NULL_RTX)
10300 before = gen_reg_rtx (mode);
10301
10302 if (after == NULL_RTX)
10303 after = gen_reg_rtx (mode);
10304
10305 /* Load exclusive. */
10306 emit_insn (gen_arc_load_exclusivesi (before, mem));
10307
10308 switch (code)
10309 {
10310 case NOT:
10311 x = gen_rtx_AND (mode, before, val);
10312 emit_insn (gen_rtx_SET (after, x));
10313 x = gen_rtx_NOT (mode, after);
10314 emit_insn (gen_rtx_SET (after, x));
10315 break;
10316
10317 case MINUS:
10318 if (CONST_INT_P (val))
10319 {
10320 val = GEN_INT (-INTVAL (val));
10321 code = PLUS;
10322 }
10323
10324 /* FALLTHRU. */
10325 default:
10326 x = gen_rtx_fmt_ee (code, mode, before, val);
10327 emit_insn (gen_rtx_SET (after, x));
10328 break;
10329 }
10330
10331 /* Exclusively store new item. Store clobbers CC reg. */
10332 emit_insn (gen_arc_store_exclusivesi (mem, after));
10333
10334 /* Check the result of the store. */
10335 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10336 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10337 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10338 label, pc_rtx);
10339 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10340
10341 arc_post_atomic_barrier (model);
10342 }
10343
10344 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10345
10346 static bool
10347 arc_no_speculation_in_delay_slots_p ()
10348 {
10349 return true;
10350 }
10351
10352 /* Return a parallel of registers to represent where to find the
10353 register pieces if required, otherwise NULL_RTX. */
10354
10355 static rtx
10356 arc_dwarf_register_span (rtx rtl)
10357 {
10358 machine_mode mode = GET_MODE (rtl);
10359 unsigned regno;
10360 rtx p;
10361
10362 if (GET_MODE_SIZE (mode) != 8)
10363 return NULL_RTX;
10364
10365 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10366 regno = REGNO (rtl);
10367 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10368 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10369
10370 return p;
10371 }
10372
10373 /* Return true if OP is an acceptable memory operand for ARCompact
10374 16-bit load instructions of MODE.
10375
10376 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10377 non scaled instructions.
10378
10379 SCALED: TRUE if address can be scaled. */
10380
10381 bool
10382 compact_memory_operand_p (rtx op, machine_mode mode,
10383 bool av2short, bool scaled)
10384 {
10385 rtx addr, plus0, plus1;
10386 int size, off;
10387
10388 /* Eliminate non-memory operations. */
10389 if (GET_CODE (op) != MEM)
10390 return 0;
10391
10392 /* .di instructions have no 16-bit form. */
10393 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10394 return false;
10395
10396 /* likewise for uncached types. */
10397 if (arc_is_uncached_mem_p (op))
10398 return false;
10399
10400 if (mode == VOIDmode)
10401 mode = GET_MODE (op);
10402
10403 size = GET_MODE_SIZE (mode);
10404
10405 /* dword operations really put out 2 instructions, so eliminate
10406 them. */
10407 if (size > UNITS_PER_WORD)
10408 return false;
10409
10410 /* Decode the address now. */
10411 addr = XEXP (op, 0);
10412 switch (GET_CODE (addr))
10413 {
10414 case REG:
10415 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10416 || COMPACT_GP_REG_P (REGNO (addr))
10417 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10418 case PLUS:
10419 plus0 = XEXP (addr, 0);
10420 plus1 = XEXP (addr, 1);
10421
10422 if ((GET_CODE (plus0) == REG)
10423 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10424 || COMPACT_GP_REG_P (REGNO (plus0)))
10425 && ((GET_CODE (plus1) == REG)
10426 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10427 || COMPACT_GP_REG_P (REGNO (plus1)))))
10428 {
10429 return !av2short;
10430 }
10431
10432 if ((GET_CODE (plus0) == REG)
10433 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10434 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10435 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10436 && (GET_CODE (plus1) == CONST_INT))
10437 {
10438 bool valid = false;
10439
10440 off = INTVAL (plus1);
10441
10442 /* Negative offset is not supported in 16-bit load/store insns. */
10443 if (off < 0)
10444 return 0;
10445
10446 /* Only u5 immediates allowed in code density instructions. */
10447 if (av2short)
10448 {
10449 switch (size)
10450 {
10451 case 1:
10452 return false;
10453 case 2:
10454 /* This is an ldh_s.x instruction, check the u6
10455 immediate. */
10456 if (COMPACT_GP_REG_P (REGNO (plus0)))
10457 valid = true;
10458 break;
10459 case 4:
10460 /* Only u5 immediates allowed in 32bit access code
10461 density instructions. */
10462 if (REGNO (plus0) <= 31)
10463 return ((off < 32) && (off % 4 == 0));
10464 break;
10465 default:
10466 return false;
10467 }
10468 }
10469 else
10470 if (COMPACT_GP_REG_P (REGNO (plus0)))
10471 valid = true;
10472
10473 if (valid)
10474 {
10475
10476 switch (size)
10477 {
10478 case 1:
10479 return (off < 32);
10480 case 2:
10481 /* The 6-bit constant get shifted to fit the real
10482 5-bits field. Check also for the alignment. */
10483 return ((off < 64) && (off % 2 == 0));
10484 case 4:
10485 return ((off < 128) && (off % 4 == 0));
10486 default:
10487 return false;
10488 }
10489 }
10490 }
10491
10492 if (REG_P (plus0) && CONST_INT_P (plus1)
10493 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10494 || SP_REG_P (REGNO (plus0)))
10495 && !av2short)
10496 {
10497 off = INTVAL (plus1);
10498 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10499 }
10500
10501 if ((GET_CODE (plus0) == MULT)
10502 && (GET_CODE (XEXP (plus0, 0)) == REG)
10503 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10504 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10505 && (GET_CODE (plus1) == REG)
10506 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10507 || COMPACT_GP_REG_P (REGNO (plus1))))
10508 return scaled;
10509 default:
10510 break ;
10511 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10512 for 16-bit load instructions. */
10513 }
10514 return false;
10515 }
10516
10517 /* Return nonzero if a jli call should be generated for a call from
10518 the current function to DECL. */
10519
10520 bool
10521 arc_is_jli_call_p (rtx pat)
10522 {
10523 tree attrs;
10524 tree decl = SYMBOL_REF_DECL (pat);
10525
10526 /* If it is not a well defined public function then return false. */
10527 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
10528 return false;
10529
10530 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10531 if (lookup_attribute ("jli_always", attrs))
10532 return true;
10533
10534 if (lookup_attribute ("jli_fixed", attrs))
10535 return true;
10536
10537 return TARGET_JLI_ALWAYS;
10538 }
10539
10540 /* Handle and "jli" attribute; arguments as in struct
10541 attribute_spec.handler. */
10542
10543 static tree
10544 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
10545 tree name, tree args, int,
10546 bool *no_add_attrs)
10547 {
10548 if (!TARGET_V2)
10549 {
10550 warning (OPT_Wattributes,
10551 "%qE attribute only valid for ARCv2 architecture",
10552 name);
10553 *no_add_attrs = true;
10554 }
10555
10556 if (args == NULL_TREE)
10557 {
10558 warning (OPT_Wattributes,
10559 "argument of %qE attribute is missing",
10560 name);
10561 *no_add_attrs = true;
10562 }
10563 else
10564 {
10565 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10566 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10567 tree arg = TREE_VALUE (args);
10568 if (TREE_CODE (arg) != INTEGER_CST)
10569 {
10570 warning (0, "%qE attribute allows only an integer constant argument",
10571 name);
10572 *no_add_attrs = true;
10573 }
10574 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10575 }
10576 return NULL_TREE;
10577 }
10578
10579 /* Handle and "scure" attribute; arguments as in struct
10580 attribute_spec.handler. */
10581
10582 static tree
10583 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
10584 tree name, tree args, int,
10585 bool *no_add_attrs)
10586 {
10587 if (!TARGET_EM)
10588 {
10589 warning (OPT_Wattributes,
10590 "%qE attribute only valid for ARC EM architecture",
10591 name);
10592 *no_add_attrs = true;
10593 }
10594
10595 if (args == NULL_TREE)
10596 {
10597 warning (OPT_Wattributes,
10598 "argument of %qE attribute is missing",
10599 name);
10600 *no_add_attrs = true;
10601 }
10602 else
10603 {
10604 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10605 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10606 tree arg = TREE_VALUE (args);
10607 if (TREE_CODE (arg) != INTEGER_CST)
10608 {
10609 warning (0, "%qE attribute allows only an integer constant argument",
10610 name);
10611 *no_add_attrs = true;
10612 }
10613 }
10614 return NULL_TREE;
10615 }
10616
10617 /* Return nonzero if the symbol is a secure function. */
10618
10619 bool
10620 arc_is_secure_call_p (rtx pat)
10621 {
10622 tree attrs;
10623 tree decl = SYMBOL_REF_DECL (pat);
10624
10625 if (!decl)
10626 return false;
10627
10628 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10629 if (lookup_attribute ("secure_call", attrs))
10630 return true;
10631
10632 return false;
10633 }
10634
10635 /* Handle "uncached" qualifier. */
10636
10637 static tree
10638 arc_handle_uncached_attribute (tree *node,
10639 tree name, tree args,
10640 int flags ATTRIBUTE_UNUSED,
10641 bool *no_add_attrs)
10642 {
10643 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
10644 {
10645 error ("%qE attribute only applies to types",
10646 name);
10647 *no_add_attrs = true;
10648 }
10649 else if (args)
10650 {
10651 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
10652 }
10653 return NULL_TREE;
10654 }
10655
10656 /* Return TRUE if PAT is a memory addressing an uncached data. */
10657
10658 bool
10659 arc_is_uncached_mem_p (rtx pat)
10660 {
10661 tree attrs = NULL_TREE;
10662 tree addr;
10663
10664 if (!MEM_P (pat))
10665 return false;
10666
10667 /* Get the memory attributes. */
10668 addr = MEM_EXPR (pat);
10669 if (!addr)
10670 return false;
10671
10672 /* Get the attributes. */
10673 if (TREE_CODE (addr) == MEM_REF
10674 || VAR_P (addr))
10675 {
10676 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10677 if (lookup_attribute ("uncached", attrs))
10678 return true;
10679 }
10680 if (TREE_CODE (addr) == MEM_REF)
10681 {
10682 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10683 if (lookup_attribute ("uncached", attrs))
10684 return true;
10685 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10686 if (lookup_attribute ("uncached", attrs))
10687 return true;
10688 }
10689
10690 /* Check the definitions of the structs. */
10691 while (handled_component_p (addr))
10692 {
10693 if (TREE_CODE (addr) == COMPONENT_REF)
10694 {
10695 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10696 if (lookup_attribute ("uncached", attrs))
10697 return true;
10698 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10699 if (lookup_attribute ("uncached", attrs))
10700 return true;
10701 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10702 if (lookup_attribute ("uncached", attrs))
10703 return true;
10704 }
10705 addr = TREE_OPERAND (addr, 0);
10706 }
10707 return false;
10708 }
10709
10710 /* Handle aux attribute. The auxiliary registers are addressed using
10711 special instructions lr and sr. The attribute 'aux' indicates if a
10712 variable refers to the aux-regs and what is the register number
10713 desired. */
10714
10715 static tree
10716 arc_handle_aux_attribute (tree *node,
10717 tree name, tree args, int,
10718 bool *no_add_attrs)
10719 {
10720 /* Isn't it better to use address spaces for the aux-regs? */
10721 if (DECL_P (*node))
10722 {
10723 if (TREE_CODE (*node) != VAR_DECL)
10724 {
10725 error ("%qE attribute only applies to variables", name);
10726 *no_add_attrs = true;
10727 }
10728 else if (args)
10729 {
10730 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10731 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10732 tree arg = TREE_VALUE (args);
10733 if (TREE_CODE (arg) != INTEGER_CST)
10734 {
10735 warning (OPT_Wattributes, "%qE attribute allows only an integer "
10736 "constant argument", name);
10737 *no_add_attrs = true;
10738 }
10739 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10740 }
10741
10742 if (VAR_P (*node))
10743 {
10744 tree fntype = TREE_TYPE (*node);
10745 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
10746 {
10747 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
10748 TYPE_ATTRIBUTES (fntype));
10749 TYPE_ATTRIBUTES (fntype) = attrs;
10750 }
10751 }
10752 }
10753 return NULL_TREE;
10754 }
10755
10756 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10757 anchors for small data: the GP register acts as an anchor in that
10758 case. We also don't want to use them for PC-relative accesses,
10759 where the PC acts as an anchor. Prohibit also TLS symbols to use
10760 anchors. */
10761
10762 static bool
10763 arc_use_anchors_for_symbol_p (const_rtx symbol)
10764 {
10765 if (SYMBOL_REF_TLS_MODEL (symbol))
10766 return false;
10767
10768 if (flag_pic)
10769 return false;
10770
10771 if (SYMBOL_REF_SMALL_P (symbol))
10772 return false;
10773
10774 return default_use_anchors_for_symbol_p (symbol);
10775 }
10776
10777 /* Return true if SUBST can't safely replace its equivalent during RA. */
10778 static bool
10779 arc_cannot_substitute_mem_equiv_p (rtx)
10780 {
10781 /* If SUBST is mem[base+index], the address may not fit ISA,
10782 thus return true. */
10783 return true;
10784 }
10785
10786 /* Checks whether the operands are valid for use in an LDD/STD
10787 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
10788 by the patterns. Assumes that the address in the base register RN
10789 is word aligned. Pattern guarantees that both memory accesses use
10790 the same base register, the offsets are constants within the range,
10791 and the gap between the offsets is 4. If reload complete then
10792 check that registers are legal. */
10793
10794 static bool
10795 operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT offset)
10796 {
10797 unsigned int t, t2;
10798
10799 if (!reload_completed)
10800 return true;
10801
10802 if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & (~0x03),
10803 (offset & (GET_MODE_SIZE (DImode) - 1) & 3
10804 ? 0 : -(-GET_MODE_SIZE (DImode) | (~0x03)) >> 1))))
10805 return false;
10806
10807 t = REGNO (rt);
10808 t2 = REGNO (rt2);
10809
10810 if ((t2 == PCL_REG)
10811 || (t % 2 != 0) /* First destination register is not even. */
10812 || (t2 != t + 1))
10813 return false;
10814
10815 return true;
10816 }
10817
10818 /* Helper for gen_operands_ldd_std. Returns true iff the memory
10819 operand MEM's address contains an immediate offset from the base
10820 register and has no side effects, in which case it sets BASE and
10821 OFFSET accordingly. */
10822
10823 static bool
10824 mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset)
10825 {
10826 rtx addr;
10827
10828 gcc_assert (base != NULL && offset != NULL);
10829
10830 /* TODO: Handle more general memory operand patterns, such as
10831 PRE_DEC and PRE_INC. */
10832
10833 if (side_effects_p (mem))
10834 return false;
10835
10836 /* Can't deal with subregs. */
10837 if (GET_CODE (mem) == SUBREG)
10838 return false;
10839
10840 gcc_assert (MEM_P (mem));
10841
10842 *offset = const0_rtx;
10843
10844 addr = XEXP (mem, 0);
10845
10846 /* If addr isn't valid for DImode, then we can't handle it. */
10847 if (!arc_legitimate_address_p (DImode, addr,
10848 reload_in_progress || reload_completed))
10849 return false;
10850
10851 if (REG_P (addr))
10852 {
10853 *base = addr;
10854 return true;
10855 }
10856 else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
10857 {
10858 *base = XEXP (addr, 0);
10859 *offset = XEXP (addr, 1);
10860 return (REG_P (*base) && CONST_INT_P (*offset));
10861 }
10862
10863 return false;
10864 }
10865
10866 /* Called from peephole2 to replace two word-size accesses with a
10867 single LDD/STD instruction. Returns true iff we can generate a new
10868 instruction sequence. That is, both accesses use the same base
10869 register and the gap between constant offsets is 4. OPERANDS are
10870 the operands found by the peephole matcher; OPERANDS[0,1] are
10871 register operands, and OPERANDS[2,3] are the corresponding memory
10872 operands. LOAD indicates whether the access is load or store. */
10873
10874 bool
10875 gen_operands_ldd_std (rtx *operands, bool load, bool commute)
10876 {
10877 int i, gap;
10878 HOST_WIDE_INT offsets[2], offset;
10879 int nops = 2;
10880 rtx cur_base, cur_offset, tmp;
10881 rtx base = NULL_RTX;
10882
10883 /* Check that the memory references are immediate offsets from the
10884 same base register. Extract the base register, the destination
10885 registers, and the corresponding memory offsets. */
10886 for (i = 0; i < nops; i++)
10887 {
10888 if (!mem_ok_for_ldd_std (operands[nops+i], &cur_base, &cur_offset))
10889 return false;
10890
10891 if (i == 0)
10892 base = cur_base;
10893 else if (REGNO (base) != REGNO (cur_base))
10894 return false;
10895
10896 offsets[i] = INTVAL (cur_offset);
10897 if (GET_CODE (operands[i]) == SUBREG)
10898 {
10899 tmp = SUBREG_REG (operands[i]);
10900 gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp));
10901 operands[i] = tmp;
10902 }
10903 }
10904
10905 /* Make sure there is no dependency between the individual loads. */
10906 if (load && REGNO (operands[0]) == REGNO (base))
10907 return false; /* RAW. */
10908
10909 if (load && REGNO (operands[0]) == REGNO (operands[1]))
10910 return false; /* WAW. */
10911
10912 /* Make sure the instructions are ordered with lower memory access first. */
10913 if (offsets[0] > offsets[1])
10914 {
10915 gap = offsets[0] - offsets[1];
10916 offset = offsets[1];
10917
10918 /* Swap the instructions such that lower memory is accessed first. */
10919 std::swap (operands[0], operands[1]);
10920 std::swap (operands[2], operands[3]);
10921 }
10922 else
10923 {
10924 gap = offsets[1] - offsets[0];
10925 offset = offsets[0];
10926 }
10927
10928 /* Make sure accesses are to consecutive memory locations. */
10929 if (gap != 4)
10930 return false;
10931
10932 /* Make sure we generate legal instructions. */
10933 if (operands_ok_ldd_std (operands[0], operands[1], offset))
10934 return true;
10935
10936 if (load && commute)
10937 {
10938 /* Try reordering registers. */
10939 std::swap (operands[0], operands[1]);
10940 if (operands_ok_ldd_std (operands[0], operands[1], offset))
10941 return true;
10942 }
10943
10944 return false;
10945 }
10946
10947 /* This order of allocation is used when we compile for size. It
10948 allocates first the registers which are most probably to end up in
10949 a short instruction. */
10950 static const int size_alloc_order[] =
10951 {
10952 0, 1, 2, 3, 12, 13, 14, 15,
10953 4, 5, 6, 7, 8, 9, 10, 11
10954 };
10955
10956 /* Adjust register allocation order when compiling for size. */
10957 void
10958 arc_adjust_reg_alloc_order (void)
10959 {
10960 const int arc_default_alloc_order[] = REG_ALLOC_ORDER;
10961 memcpy (reg_alloc_order, arc_default_alloc_order, sizeof (reg_alloc_order));
10962 if (optimize_size)
10963 memcpy (reg_alloc_order, size_alloc_order, sizeof (size_alloc_order));
10964 }
10965
10966 /* Implement TARGET_MEMORY_MOVE_COST. */
10967
10968 static int
10969 arc_memory_move_cost (machine_mode mode,
10970 reg_class_t rclass ATTRIBUTE_UNUSED,
10971 bool in ATTRIBUTE_UNUSED)
10972 {
10973 if ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
10974 || ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD * 2) && TARGET_LL64))
10975 return 6;
10976
10977 return (2 * GET_MODE_SIZE (mode));
10978 }
10979
10980 /* Split an OR instruction into multiple BSET/OR instructions in a
10981 attempt to avoid long immediate constants. The next strategies are
10982 employed when destination is 'q' reg.
10983
10984 1. if there are up to three bits set in the mask, a succession of
10985 three bset instruction will be emitted:
10986 OR rA, rB, mask ->
10987 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
10988
10989 2. if the lower 6 bits of the mask is set and there is only one
10990 bit set in the upper remaining bits then we will emit one bset and
10991 one OR instruction:
10992 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
10993
10994 3. otherwise an OR with limm will be emmitted. */
10995
10996 void
10997 arc_split_ior (rtx *operands)
10998 {
10999 unsigned HOST_WIDE_INT mask, maskx;
11000 rtx op1 = operands[1];
11001
11002 gcc_assert (CONST_INT_P (operands[2]));
11003 mask = INTVAL (operands[2]) & 0xffffffff;
11004
11005 if (__builtin_popcount (mask) > 3 || (mask & 0x3f))
11006 {
11007 maskx = mask & 0x3f;
11008 emit_insn (gen_rtx_SET (operands[0],
11009 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11010 op1 = operands[0];
11011 mask &= ~maskx;
11012 }
11013
11014 switch (__builtin_popcount (mask))
11015 {
11016 case 3:
11017 maskx = 1 << (__builtin_ffs (mask) - 1);
11018 emit_insn (gen_rtx_SET (operands[0],
11019 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11020 mask &= ~maskx;
11021 op1 = operands[0];
11022 /* FALLTHRU */
11023 case 2:
11024 maskx = 1 << (__builtin_ffs (mask) - 1);
11025 emit_insn (gen_rtx_SET (operands[0],
11026 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11027 mask &= ~maskx;
11028 op1 = operands[0];
11029 /* FALLTHRU */
11030 case 1:
11031 maskx = 1 << (__builtin_ffs (mask) - 1);
11032 emit_insn (gen_rtx_SET (operands[0],
11033 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11034 break;
11035 case 0:
11036 break;
11037 default:
11038 gcc_unreachable ();
11039 }
11040 }
11041
11042 /* Helper to check C0x constraint. */
11043
11044 bool
11045 arc_check_ior_const (HOST_WIDE_INT ival)
11046 {
11047 unsigned int mask = (unsigned int) (ival & 0xffffffff);
11048
11049 if (UNSIGNED_INT6 (ival)
11050 || IS_POWEROF2_P (mask))
11051 return false;
11052 if (__builtin_popcount (mask) <= 3)
11053 return true;
11054 if (__builtin_popcount (mask & ~0x3f) <= 1)
11055 return true;
11056 return false;
11057 }
11058
11059 /* Split a mov with long immediate instruction into smaller, size
11060 friendly instructions. */
11061
11062 bool
11063 arc_split_mov_const (rtx *operands)
11064 {
11065 unsigned HOST_WIDE_INT ival;
11066 HOST_WIDE_INT shimm;
11067 machine_mode mode = GET_MODE (operands[0]);
11068
11069 /* Manage a constant. */
11070 gcc_assert (CONST_INT_P (operands[1]));
11071 ival = INTVAL (operands[1]) & 0xffffffff;
11072
11073 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11074 if (TARGET_BARREL_SHIFTER && TARGET_V2
11075 && ((ival & ~0x3f000000) == 0))
11076 {
11077 shimm = (ival >> 24) & 0x3f;
11078 emit_insn (gen_rtx_SET (operands[0],
11079 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11080 GEN_INT (8))));
11081 return true;
11082 }
11083 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11084 if (TARGET_BARREL_SHIFTER && TARGET_V2
11085 && ((ival & ~0x3f00) == 0))
11086 {
11087 shimm = (ival >> 8) & 0x3f;
11088 emit_insn (gen_rtx_SET (operands[0],
11089 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11090 GEN_INT (8))));
11091 return true;
11092 }
11093
11094 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11095 if (TARGET_SWAP && TARGET_V2
11096 && ((ival & ~0x3f0000) == 0))
11097 {
11098 shimm = (ival >> 16) & 0x3f;
11099 emit_insn (gen_rtx_SET (operands[0],
11100 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11101 GEN_INT (16))));
11102 return true;
11103 }
11104
11105 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11106 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0
11107 && TARGET_BARREL_SHIFTER)
11108 {
11109 HOST_WIDE_INT shift = __builtin_ffs (ival);
11110 shimm = (ival >> (shift - 1)) & 0xff;
11111 emit_insn (gen_rtx_SET (operands[0], GEN_INT (shimm)));
11112 emit_insn (gen_rtx_SET (operands[0],
11113 gen_rtx_ASHIFT (mode, operands[0],
11114 GEN_INT (shift - 1))));
11115 return true;
11116 }
11117
11118 /* 5. Check if we can just rotate the limm, useful when no barrel
11119 shifter is present. */
11120 if ((ival & ~0x8000001f) == 0)
11121 {
11122 shimm = (ival * 2 + 1) & 0x3f;
11123 emit_insn (gen_rtx_SET (operands[0],
11124 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11125 const1_rtx)));
11126 return true;
11127 }
11128
11129 /* 6. Check if we can do something with bmask. */
11130 if (IS_POWEROF2_P (ival + 1))
11131 {
11132 emit_insn (gen_rtx_SET (operands[0], constm1_rtx));
11133 emit_insn (gen_rtx_SET (operands[0],
11134 gen_rtx_AND (mode, operands[0],
11135 GEN_INT (ival))));
11136 return true;
11137 }
11138
11139 gcc_unreachable ();
11140 }
11141
11142 /* Helper to check Cax constraint. */
11143
11144 bool
11145 arc_check_mov_const (HOST_WIDE_INT ival)
11146 {
11147 ival = ival & 0xffffffff;
11148
11149 if (SIGNED_INT12 (ival))
11150 return false;
11151
11152 if ((ival & ~0x8000001f) == 0)
11153 return true;
11154
11155 if (IS_POWEROF2_P (ival + 1))
11156 return true;
11157
11158 /* The next rules requires a barrel shifter. */
11159 if (!TARGET_BARREL_SHIFTER)
11160 return false;
11161
11162 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0)
11163 return true;
11164
11165 if ((ival & ~0x3f00) == 0)
11166 return true;
11167
11168 if ((ival & ~0x3f0000) == 0)
11169 return true;
11170
11171 if ((ival & ~0x3f000000) == 0)
11172 return true;
11173
11174 return false;
11175 }
11176
11177 /* Return nonzero if this function is known to have a null epilogue.
11178 This allows the optimizer to omit jumps to jumps if no stack
11179 was created. */
11180
11181 bool
11182 arc_can_use_return_insn (void)
11183 {
11184 return (reload_completed && cfun->machine->frame_info.total_size == 0
11185 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
11186 }
11187
11188 /* Helper for INSN_COST.
11189
11190 Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
11191 insn, a set, a set source, any random piece of one). set_src_cost,
11192 set_rtx_cost, etc. are helper functions that use that.
11193
11194 Those functions do not work for parallels. Also, costs are not
11195 additive like this simplified model assumes. Also, more complex
11196 backends tend to miss many cases in their rtx_costs function.
11197
11198 Many passes that want costs want to know the cost of a full insn. Like
11199 combine. That's why I created insn_cost: it solves all of the above
11200 problems. */
11201
11202 static int
11203 arc_insn_cost (rtx_insn *insn, bool speed)
11204 {
11205 int cost;
11206 enum attr_type type;
11207 if (recog_memoized (insn) >= 0)
11208 {
11209 if (speed)
11210 {
11211 /* Use cost if provided. */
11212 cost = get_attr_cost (insn);
11213 if (cost > 0)
11214 return cost;
11215 /* For speed make a simple cost model: memory access is more
11216 expensive than any other instruction. */
11217 type = get_attr_type (insn);
11218 if (type == TYPE_LOAD || type == TYPE_STORE)
11219 return COSTS_N_INSNS (2);
11220 }
11221 else
11222 {
11223 /* If optimizing for size, we want the insn size. */
11224 type = get_attr_type (insn);
11225 if (type != TYPE_MULTI)
11226 return get_attr_length (insn);
11227 }
11228 }
11229
11230 if (rtx set = single_set (insn))
11231 cost = set_rtx_cost (set, speed);
11232 else
11233 cost = pattern_cost (PATTERN (insn), speed);
11234 /* If the cost is zero, then it's likely a complex insn. We don't
11235 want the cost of these to be less than something we know about. */
11236 return cost ? cost : COSTS_N_INSNS (2);
11237 }
11238
11239 static unsigned
11240 arc_libm_function_max_error (unsigned cfn, machine_mode mode,
11241 bool boundary_p)
11242 {
11243 #ifdef OPTION_GLIBC
11244 bool glibc_p = OPTION_GLIBC;
11245 #else
11246 bool glibc_p = false;
11247 #endif
11248 if (glibc_p)
11249 {
11250 int rnd = flag_rounding_math ? 4 : 0;
11251 switch (cfn)
11252 {
11253 CASE_CFN_SIN:
11254 CASE_CFN_SIN_FN:
11255 if (!boundary_p && mode == DFmode)
11256 return 7 + rnd;
11257 break;
11258 CASE_CFN_COS:
11259 CASE_CFN_COS_FN:
11260 if (!boundary_p && mode == DFmode)
11261 return 4 + rnd;
11262 default:
11263 break;
11264 }
11265 return glibc_linux_libm_function_max_error (cfn, mode, boundary_p);
11266 }
11267 return default_libm_function_max_error (cfn, mode, boundary_p);
11268 }
11269
11270 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11271 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11272
11273 #undef TARGET_CONSTANT_ALIGNMENT
11274 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11275
11276 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11277 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11278
11279 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11280 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11281
11282 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11283 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11284
11285 #undef TARGET_REGISTER_MOVE_COST
11286 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11287
11288 #undef TARGET_MEMORY_MOVE_COST
11289 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11290
11291 #undef TARGET_INSN_COST
11292 #define TARGET_INSN_COST arc_insn_cost
11293
11294 #undef TARGET_LIBM_FUNCTION_MAX_ERROR
11295 #define TARGET_LIBM_FUNCTION_MAX_ERROR arc_libm_function_max_error
11296
11297 struct gcc_target targetm = TARGET_INITIALIZER;
11298
11299 #include "gt-arc.h"