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