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