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