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