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