]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/arc.c
Implement LWG 2534, Constrain rvalue stream operators.
[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
f50bb868
CZ
6507/* The same functionality as arc_hazard. It is called in machine
6508 reorg before any other optimization. Hence, the NOP size is taken
6509 into account when doing branch shortening. */
6510
6511static void
6512workaround_arc_anomaly (void)
6513{
6514 rtx_insn *insn, *succ0;
6515
6516 /* For any architecture: call arc_hazard here. */
6517 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6518 {
6519 succ0 = next_real_insn (insn);
6520 if (arc_hazard (insn, succ0))
6521 {
6522 emit_insn_before (gen_nopv (), succ0);
6523 }
6524 }
6525}
6526
526b7aee
SV
6527static int arc_reorg_in_progress = 0;
6528
6529/* ARC's machince specific reorg function. */
6530
6531static void
6532arc_reorg (void)
6533{
b3458f61
DM
6534 rtx_insn *insn;
6535 rtx pattern;
526b7aee
SV
6536 rtx pc_target;
6537 long offset;
6538 int changed;
6539
f50bb868
CZ
6540 workaround_arc_anomaly ();
6541
526b7aee
SV
6542 cfun->machine->arc_reorg_started = 1;
6543 arc_reorg_in_progress = 1;
6544
6545 /* Emit special sections for profiling. */
6546 if (crtl->profile)
6547 {
6548 section *save_text_section;
b3458f61 6549 rtx_insn *insn;
526b7aee
SV
6550 int size = get_max_uid () >> 4;
6551 htab_t htab = htab_create (size, unspec_prof_hash, unspec_prof_htab_eq,
6552 NULL);
6553
6554 save_text_section = in_section;
6555 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6556 if (NONJUMP_INSN_P (insn))
6557 walk_stores (PATTERN (insn), write_profile_sections, htab);
6558 if (htab_elements (htab))
6559 in_section = 0;
6560 switch_to_section (save_text_section);
6561 htab_delete (htab);
6562 }
6563
6564 /* Link up loop ends with their loop start. */
6565 {
6566 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6567 if (GET_CODE (insn) == JUMP_INSN
6568 && recog_memoized (insn) == CODE_FOR_doloop_end_i)
6569 {
b3458f61
DM
6570 rtx_insn *top_label
6571 = as_a <rtx_insn *> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0));
526b7aee 6572 rtx num = GEN_INT (CODE_LABEL_NUMBER (top_label));
b3458f61
DM
6573 rtx_insn *lp, *prev = prev_nonnote_insn (top_label);
6574 rtx_insn *lp_simple = NULL;
6575 rtx_insn *next = NULL;
526b7aee
SV
6576 rtx op0 = XEXP (XVECEXP (PATTERN (insn), 0, 1), 0);
6577 HOST_WIDE_INT loop_end_id
6578 = -INTVAL (XEXP (XVECEXP (PATTERN (insn), 0, 4), 0));
6579 int seen_label = 0;
6580
6581 for (lp = prev;
6582 (lp && NONJUMP_INSN_P (lp)
6583 && recog_memoized (lp) != CODE_FOR_doloop_begin_i);
6584 lp = prev_nonnote_insn (lp))
6585 ;
6586 if (!lp || !NONJUMP_INSN_P (lp)
6587 || dead_or_set_regno_p (lp, LP_COUNT))
6588 {
b3458f61 6589 for (prev = next = insn, lp = NULL ; prev || next;)
526b7aee
SV
6590 {
6591 if (prev)
6592 {
6593 if (NONJUMP_INSN_P (prev)
6594 && recog_memoized (prev) == CODE_FOR_doloop_begin_i
6595 && (INTVAL (XEXP (XVECEXP (PATTERN (prev), 0, 5), 0))
6596 == loop_end_id))
6597 {
6598 lp = prev;
6599 break;
6600 }
6601 else if (LABEL_P (prev))
6602 seen_label = 1;
6603 prev = prev_nonnote_insn (prev);
6604 }
6605 if (next)
6606 {
6607 if (NONJUMP_INSN_P (next)
6608 && recog_memoized (next) == CODE_FOR_doloop_begin_i
6609 && (INTVAL (XEXP (XVECEXP (PATTERN (next), 0, 5), 0))
6610 == loop_end_id))
6611 {
6612 lp = next;
6613 break;
6614 }
6615 next = next_nonnote_insn (next);
6616 }
6617 }
b3458f61 6618 prev = NULL;
526b7aee
SV
6619 }
6620 else
6621 lp_simple = lp;
6622 if (lp && !dead_or_set_regno_p (lp, LP_COUNT))
6623 {
6624 rtx begin_cnt = XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0);
6625 if (INTVAL (XEXP (XVECEXP (PATTERN (lp), 0, 4), 0)))
6626 /* The loop end insn has been duplicated. That can happen
6627 when there is a conditional block at the very end of
6628 the loop. */
6629 goto failure;
6630 /* If Register allocation failed to allocate to the right
6631 register, There is no point into teaching reload to
6632 fix this up with reloads, as that would cost more
6633 than using an ordinary core register with the
6634 doloop_fallback pattern. */
6635 if ((true_regnum (op0) != LP_COUNT || !REG_P (begin_cnt))
6636 /* Likewise, if the loop setup is evidently inside the loop,
6637 we loose. */
6638 || (!lp_simple && lp != next && !seen_label))
6639 {
6640 remove_insn (lp);
6641 goto failure;
6642 }
6643 /* It is common that the optimizers copy the loop count from
6644 another register, and doloop_begin_i is stuck with the
6645 source of the move. Making doloop_begin_i only accept "l"
6646 is nonsentical, as this then makes reload evict the pseudo
6647 used for the loop end. The underlying cause is that the
6648 optimizers don't understand that the register allocation for
6649 doloop_begin_i should be treated as part of the loop.
6650 Try to work around this problem by verifying the previous
6651 move exists. */
6652 if (true_regnum (begin_cnt) != LP_COUNT)
6653 {
b3458f61
DM
6654 rtx_insn *mov;
6655 rtx set, note;
526b7aee
SV
6656
6657 for (mov = prev_nonnote_insn (lp); mov;
6658 mov = prev_nonnote_insn (mov))
6659 {
6660 if (!NONJUMP_INSN_P (mov))
6661 mov = 0;
6662 else if ((set = single_set (mov))
6663 && rtx_equal_p (SET_SRC (set), begin_cnt)
6664 && rtx_equal_p (SET_DEST (set), op0))
6665 break;
6666 }
6667 if (mov)
6668 {
6669 XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0) = op0;
6670 note = find_regno_note (lp, REG_DEAD, REGNO (begin_cnt));
6671 if (note)
6672 remove_note (lp, note);
6673 }
6674 else
6675 {
6676 remove_insn (lp);
6677 goto failure;
6678 }
6679 }
6680 XEXP (XVECEXP (PATTERN (insn), 0, 4), 0) = num;
6681 XEXP (XVECEXP (PATTERN (lp), 0, 4), 0) = num;
6682 if (next == lp)
6683 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const2_rtx;
6684 else if (!lp_simple)
6685 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const1_rtx;
6686 else if (prev != lp)
6687 {
6688 remove_insn (lp);
6689 add_insn_after (lp, prev, NULL);
6690 }
6691 if (!lp_simple)
6692 {
6693 XEXP (XVECEXP (PATTERN (lp), 0, 7), 0)
6694 = gen_rtx_LABEL_REF (Pmode, top_label);
6695 add_reg_note (lp, REG_LABEL_OPERAND, top_label);
6696 LABEL_NUSES (top_label)++;
6697 }
6698 /* We can avoid tedious loop start / end setting for empty loops
6699 be merely setting the loop count to its final value. */
6700 if (next_active_insn (top_label) == insn)
6701 {
6702 rtx lc_set
f7df4a84 6703 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp), 0, 3), 0),
526b7aee
SV
6704 const0_rtx);
6705
b3458f61 6706 rtx_insn *lc_set_insn = emit_insn_before (lc_set, insn);
526b7aee
SV
6707 delete_insn (lp);
6708 delete_insn (insn);
b3458f61 6709 insn = lc_set_insn;
526b7aee
SV
6710 }
6711 /* If the loop is non-empty with zero length, we can't make it
6712 a zero-overhead loop. That can happen for empty asms. */
6713 else
6714 {
b3458f61 6715 rtx_insn *scan;
526b7aee
SV
6716
6717 for (scan = top_label;
6718 (scan && scan != insn
6719 && (!NONJUMP_INSN_P (scan) || !get_attr_length (scan)));
6720 scan = NEXT_INSN (scan));
6721 if (scan == insn)
6722 {
6723 remove_insn (lp);
6724 goto failure;
6725 }
6726 }
6727 }
6728 else
6729 {
6730 /* Sometimes the loop optimizer makes a complete hash of the
6731 loop. If it were only that the loop is not entered at the
6732 top, we could fix this up by setting LP_START with SR .
6733 However, if we can't find the loop begin were it should be,
6734 chances are that it does not even dominate the loop, but is
6735 inside the loop instead. Using SR there would kill
6736 performance.
6737 We use the doloop_fallback pattern here, which executes
6738 in two cycles on the ARC700 when predicted correctly. */
6739 failure:
6740 if (!REG_P (op0))
6741 {
6742 rtx op3 = XEXP (XVECEXP (PATTERN (insn), 0, 5), 0);
6743
6744 emit_insn_before (gen_move_insn (op3, op0), insn);
6745 PATTERN (insn)
6746 = gen_doloop_fallback_m (op3, JUMP_LABEL (insn), op0);
6747 }
6748 else
6749 XVEC (PATTERN (insn), 0)
6750 = gen_rtvec (2, XVECEXP (PATTERN (insn), 0, 0),
6751 XVECEXP (PATTERN (insn), 0, 1));
6752 INSN_CODE (insn) = -1;
6753 }
6754 }
6755 }
6756
6757/* FIXME: should anticipate ccfsm action, generate special patterns for
6758 to-be-deleted branches that have no delay slot and have at least the
6759 length of the size increase forced on other insns that are conditionalized.
6760 This can also have an insn_list inside that enumerates insns which are
6761 not actually conditionalized because the destinations are dead in the
6762 not-execute case.
6763 Could also tag branches that we want to be unaligned if they get no delay
6764 slot, or even ones that we don't want to do delay slot sheduling for
6765 because we can unalign them.
6766
6767 However, there are cases when conditional execution is only possible after
6768 delay slot scheduling:
6769
6770 - If a delay slot is filled with a nocond/set insn from above, the previous
6771 basic block can become elegible for conditional execution.
6772 - If a delay slot is filled with a nocond insn from the fall-through path,
6773 the branch with that delay slot can become eligble for conditional
6774 execution (however, with the same sort of data flow analysis that dbr
6775 does, we could have figured out before that we don't need to
6776 conditionalize this insn.)
6777 - If a delay slot insn is filled with an insn from the target, the
6778 target label gets its uses decremented (even deleted if falling to zero),
6779 thus possibly creating more condexec opportunities there.
6780 Therefore, we should still be prepared to apply condexec optimization on
6781 non-prepared branches if the size increase of conditionalized insns is no
6782 more than the size saved from eliminating the branch. An invocation option
6783 could also be used to reserve a bit of extra size for condbranches so that
6784 this'll work more often (could also test in arc_reorg if the block is
6785 'close enough' to be eligible for condexec to make this likely, and
6786 estimate required size increase). */
6787 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
6788 if (TARGET_NO_BRCC_SET)
6789 return;
6790
6791 do
6792 {
6793 init_insn_lengths();
6794 changed = 0;
6795
6796 if (optimize > 1 && !TARGET_NO_COND_EXEC)
6797 {
6798 arc_ifcvt ();
6799 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
6800 df_finish_pass ((flags & TODO_df_verify) != 0);
6801 }
6802
6803 /* Call shorten_branches to calculate the insn lengths. */
6804 shorten_branches (get_insns());
6805 cfun->machine->ccfsm_current_insn = NULL_RTX;
6806
6807 if (!INSN_ADDRESSES_SET_P())
40fecdd6 6808 fatal_error (input_location, "Insn addresses not set after shorten_branches");
526b7aee
SV
6809
6810 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6811 {
6812 rtx label;
6813 enum attr_type insn_type;
6814
6815 /* If a non-jump insn (or a casesi jump table), continue. */
6816 if (GET_CODE (insn) != JUMP_INSN ||
6817 GET_CODE (PATTERN (insn)) == ADDR_VEC
6818 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
6819 continue;
6820
6821 /* If we already have a brcc, note if it is suitable for brcc_s.
6822 Be a bit generous with the brcc_s range so that we can take
6823 advantage of any code shortening from delay slot scheduling. */
6824 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
6825 {
6826 rtx pat = PATTERN (insn);
6827 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
6828 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
6829
6830 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6831 if ((offset >= -140 && offset < 140)
6832 && rtx_equal_p (XEXP (op, 1), const0_rtx)
6833 && compact_register_operand (XEXP (op, 0), VOIDmode)
6834 && equality_comparison_operator (op, VOIDmode))
6835 PUT_MODE (*ccp, CC_Zmode);
6836 else if (GET_MODE (*ccp) == CC_Zmode)
6837 PUT_MODE (*ccp, CC_ZNmode);
6838 continue;
6839 }
6840 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
6841 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
6842 continue;
6843
6844 /* OK. so we have a jump insn. */
6845 /* We need to check that it is a bcc. */
6846 /* Bcc => set (pc) (if_then_else ) */
6847 pattern = PATTERN (insn);
6848 if (GET_CODE (pattern) != SET
6849 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
6850 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
6851 continue;
6852
6853 /* Now check if the jump is beyond the s9 range. */
339ba33b 6854 if (CROSSING_JUMP_P (insn))
526b7aee
SV
6855 continue;
6856 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6857
6858 if(offset > 253 || offset < -254)
6859 continue;
6860
6861 pc_target = SET_SRC (pattern);
6862
8f3304d0
CZ
6863 /* Avoid FPU instructions. */
6864 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
6865 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
6866 continue;
6867
526b7aee
SV
6868 /* Now go back and search for the set cc insn. */
6869
6870 label = XEXP (pc_target, 1);
6871
6872 {
b3458f61
DM
6873 rtx pat;
6874 rtx_insn *scan, *link_insn = NULL;
526b7aee
SV
6875
6876 for (scan = PREV_INSN (insn);
6877 scan && GET_CODE (scan) != CODE_LABEL;
6878 scan = PREV_INSN (scan))
6879 {
6880 if (! INSN_P (scan))
6881 continue;
6882 pat = PATTERN (scan);
6883 if (GET_CODE (pat) == SET
6884 && cc_register (SET_DEST (pat), VOIDmode))
6885 {
6886 link_insn = scan;
6887 break;
6888 }
6889 }
8f3304d0 6890 if (!link_insn)
526b7aee
SV
6891 continue;
6892 else
6893 /* Check if this is a data dependency. */
6894 {
6895 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
6896 rtx cmp0, cmp1;
6897
6898 /* Ok this is the set cc. copy args here. */
6899 op = XEXP (pc_target, 0);
6900
6901 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
6902 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
6903 if (GET_CODE (op0) == ZERO_EXTRACT
6904 && XEXP (op0, 1) == const1_rtx
6905 && (GET_CODE (op) == EQ
6906 || GET_CODE (op) == NE))
6907 {
6908 /* btst / b{eq,ne} -> bbit{0,1} */
6909 op0 = XEXP (cmp0, 0);
6910 op1 = XEXP (cmp0, 2);
6911 }
6912 else if (!register_operand (op0, VOIDmode)
6913 || !general_operand (op1, VOIDmode))
6914 continue;
6915 /* Be careful not to break what cmpsfpx_raw is
6916 trying to create for checking equality of
6917 single-precision floats. */
6918 else if (TARGET_SPFP
6919 && GET_MODE (op0) == SFmode
6920 && GET_MODE (op1) == SFmode)
6921 continue;
6922
6923 /* None of the two cmp operands should be set between the
6924 cmp and the branch. */
6925 if (reg_set_between_p (op0, link_insn, insn))
6926 continue;
6927
6928 if (reg_set_between_p (op1, link_insn, insn))
6929 continue;
6930
6931 /* Since the MODE check does not work, check that this is
6932 CC reg's last set location before insn, and also no
6933 instruction between the cmp and branch uses the
6934 condition codes. */
6935 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
6936 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
6937 continue;
6938
6939 /* CC reg should be dead after insn. */
6940 if (!find_regno_note (insn, REG_DEAD, CC_REG))
6941 continue;
6942
6943 op = gen_rtx_fmt_ee (GET_CODE (op),
6944 GET_MODE (op), cmp0, cmp1);
6945 /* If we create a LIMM where there was none before,
6946 we only benefit if we can avoid a scheduling bubble
6947 for the ARC600. Otherwise, we'd only forgo chances
6948 at short insn generation, and risk out-of-range
6949 branches. */
6950 if (!brcc_nolimm_operator (op, VOIDmode)
6951 && !long_immediate_operand (op1, VOIDmode)
6952 && (TARGET_ARC700
6953 || next_active_insn (link_insn) != insn))
6954 continue;
6955
6956 /* Emit bbit / brcc (or brcc_s if possible).
6957 CC_Zmode indicates that brcc_s is possible. */
6958
6959 if (op0 != cmp0)
6960 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
6961 else if ((offset >= -140 && offset < 140)
6962 && rtx_equal_p (op1, const0_rtx)
6963 && compact_register_operand (op0, VOIDmode)
6964 && (GET_CODE (op) == EQ
6965 || GET_CODE (op) == NE))
6966 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
6967 else
6968 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
6969
6970 brcc_insn
6971 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
f7df4a84 6972 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
526b7aee
SV
6973 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
6974 brcc_insn
6975 = gen_rtx_PARALLEL
6976 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
6977 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
6978
6979 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
6980 note = find_reg_note (insn, REG_BR_PROB, 0);
6981 if (note)
6982 {
6983 XEXP (note, 1) = REG_NOTES (brcc_insn);
6984 REG_NOTES (brcc_insn) = note;
6985 }
6986 note = find_reg_note (link_insn, REG_DEAD, op0);
6987 if (note)
6988 {
6989 remove_note (link_insn, note);
6990 XEXP (note, 1) = REG_NOTES (brcc_insn);
6991 REG_NOTES (brcc_insn) = note;
6992 }
6993 note = find_reg_note (link_insn, REG_DEAD, op1);
6994 if (note)
6995 {
6996 XEXP (note, 1) = REG_NOTES (brcc_insn);
6997 REG_NOTES (brcc_insn) = note;
6998 }
6999
7000 changed = 1;
7001
7002 /* Delete the bcc insn. */
7003 set_insn_deleted (insn);
7004
7005 /* Delete the cmp insn. */
7006 set_insn_deleted (link_insn);
7007
7008 }
7009 }
7010 }
7011 /* Clear out insn_addresses. */
7012 INSN_ADDRESSES_FREE ();
7013
7014 } while (changed);
7015
7016 if (INSN_ADDRESSES_SET_P())
40fecdd6 7017 fatal_error (input_location, "insn addresses not freed");
526b7aee
SV
7018
7019 arc_reorg_in_progress = 0;
7020}
7021
7022 /* Check if the operands are valid for BRcc.d generation
7023 Valid Brcc.d patterns are
7024 Brcc.d b, c, s9
7025 Brcc.d b, u6, s9
7026
7027 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7028 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7029 does not have a delay slot
7030
7031 Assumed precondition: Second operand is either a register or a u6 value. */
7032
7033bool
7034valid_brcc_with_delay_p (rtx *operands)
7035{
7036 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
7037 return false;
7038 return brcc_nolimm_operator (operands[0], VOIDmode);
7039}
7040
7041/* ??? Hack. This should no really be here. See PR32143. */
7042static bool
7043arc_decl_anon_ns_mem_p (const_tree decl)
7044{
7045 while (1)
7046 {
7047 if (decl == NULL_TREE || decl == error_mark_node)
7048 return false;
7049 if (TREE_CODE (decl) == NAMESPACE_DECL
7050 && DECL_NAME (decl) == NULL_TREE)
7051 return true;
7052 /* Classes and namespaces inside anonymous namespaces have
7053 TREE_PUBLIC == 0, so we can shortcut the search. */
7054 else if (TYPE_P (decl))
7055 return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
7056 else if (TREE_CODE (decl) == NAMESPACE_DECL)
7057 return (TREE_PUBLIC (decl) == 0);
7058 else
7059 decl = DECL_CONTEXT (decl);
7060 }
7061}
7062
7063/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7064 access DECL using %gp_rel(...)($gp). */
7065
7066static bool
7067arc_in_small_data_p (const_tree decl)
7068{
7069 HOST_WIDE_INT size;
7070
7071 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
7072 return false;
7073
7074
7075 /* We don't yet generate small-data references for -mabicalls. See related
7076 -G handling in override_options. */
7077 if (TARGET_NO_SDATA_SET)
7078 return false;
7079
7080 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
7081 {
7082 const char *name;
7083
7084 /* Reject anything that isn't in a known small-data section. */
f961457f 7085 name = DECL_SECTION_NAME (decl);
526b7aee
SV
7086 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
7087 return false;
7088
7089 /* If a symbol is defined externally, the assembler will use the
7090 usual -G rules when deciding how to implement macros. */
7091 if (!DECL_EXTERNAL (decl))
7092 return true;
7093 }
7094 /* Only global variables go into sdata section for now. */
7095 else if (1)
7096 {
7097 /* Don't put constants into the small data section: we want them
7098 to be in ROM rather than RAM. */
7099 if (TREE_CODE (decl) != VAR_DECL)
7100 return false;
7101
7102 if (TREE_READONLY (decl)
7103 && !TREE_SIDE_EFFECTS (decl)
7104 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
7105 return false;
7106
7107 /* TREE_PUBLIC might change after the first call, because of the patch
7108 for PR19238. */
7109 if (default_binds_local_p_1 (decl, 1)
7110 || arc_decl_anon_ns_mem_p (decl))
7111 return false;
7112
7113 /* To ensure -mvolatile-cache works
7114 ld.di does not have a gp-relative variant. */
7115 if (TREE_THIS_VOLATILE (decl))
7116 return false;
7117 }
7118
7119 /* Disable sdata references to weak variables. */
7120 if (DECL_WEAK (decl))
7121 return false;
7122
7123 size = int_size_in_bytes (TREE_TYPE (decl));
7124
7125/* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7126/* return false; */
7127
7128 /* Allow only <=4B long data types into sdata. */
7129 return (size > 0 && size <= 4);
7130}
7131
7132/* Return true if X is a small data address that can be rewritten
7133 as a gp+symref. */
7134
7135static bool
752ae22f 7136arc_rewrite_small_data_p (const_rtx x)
526b7aee
SV
7137{
7138 if (GET_CODE (x) == CONST)
7139 x = XEXP (x, 0);
7140
7141 if (GET_CODE (x) == PLUS)
7142 {
7143 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
7144 x = XEXP (x, 0);
7145 }
7146
28633bbd
CZ
7147 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
7148 {
7149 gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0);
7150 return true;
7151 }
7152 return false;
526b7aee
SV
7153}
7154
526b7aee
SV
7155/* If possible, rewrite OP so that it refers to small data using
7156 explicit relocations. */
7157
7158rtx
7159arc_rewrite_small_data (rtx op)
7160{
7161 op = copy_insn (op);
6733978e
RS
7162 subrtx_ptr_iterator::array_type array;
7163 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
7164 {
7165 rtx *loc = *iter;
7166 if (arc_rewrite_small_data_p (*loc))
7167 {
7168 gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
7169 *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
7170 if (loc != &op)
7171 {
7172 if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
7173 ; /* OK. */
7174 else if (GET_CODE (op) == MEM
7175 && GET_CODE (XEXP (op, 0)) == PLUS
7176 && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
7177 *loc = force_reg (Pmode, *loc);
7178 else
7179 gcc_unreachable ();
7180 }
7181 iter.skip_subrtxes ();
7182 }
7183 else if (GET_CODE (*loc) == PLUS
7184 && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
7185 iter.skip_subrtxes ();
7186 }
526b7aee
SV
7187 return op;
7188}
7189
526b7aee
SV
7190/* Return true if OP refers to small data symbols directly, not through
7191 a PLUS. */
7192
7193bool
ef4bddc2 7194small_data_pattern (rtx op, machine_mode)
526b7aee 7195{
752ae22f
RS
7196 if (GET_CODE (op) == SEQUENCE)
7197 return false;
7198 subrtx_iterator::array_type array;
7199 FOR_EACH_SUBRTX (iter, array, op, ALL)
7200 {
7201 const_rtx x = *iter;
7202 if (GET_CODE (x) == PLUS
7203 && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
7204 iter.skip_subrtxes ();
7205 else if (arc_rewrite_small_data_p (x))
7206 return true;
7207 }
7208 return false;
526b7aee
SV
7209}
7210
7211/* Return true if OP is an acceptable memory operand for ARCompact
7212 16-bit gp-relative load instructions.
7213 op shd look like : [r26, symref@sda]
7214 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7215 */
7216/* volatile cache option still to be handled. */
7217
7218bool
ef4bddc2 7219compact_sda_memory_operand (rtx op, machine_mode mode)
526b7aee
SV
7220{
7221 rtx addr;
7222 int size;
7223
7224 /* Eliminate non-memory operations. */
7225 if (GET_CODE (op) != MEM)
7226 return false;
7227
7228 if (mode == VOIDmode)
7229 mode = GET_MODE (op);
7230
7231 size = GET_MODE_SIZE (mode);
7232
7233 /* dword operations really put out 2 instructions, so eliminate them. */
7234 if (size > UNITS_PER_WORD)
7235 return false;
7236
7237 /* Decode the address now. */
7238 addr = XEXP (op, 0);
7239
7240 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
7241}
7242
7243/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7244
7245void
7246arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
7247 unsigned HOST_WIDE_INT size,
7248 unsigned HOST_WIDE_INT align,
7249 unsigned HOST_WIDE_INT globalize_p)
7250{
7251 int in_small_data = arc_in_small_data_p (decl);
7252
7253 if (in_small_data)
7254 switch_to_section (get_named_section (NULL, ".sbss", 0));
7255 /* named_section (0,".sbss",0); */
7256 else
7257 switch_to_section (bss_section);
7258
7259 if (globalize_p)
7260 (*targetm.asm_out.globalize_label) (stream, name);
7261
7262 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
7263 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
7264 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
7265 ASM_OUTPUT_LABEL (stream, name);
7266
7267 if (size != 0)
7268 ASM_OUTPUT_SKIP (stream, size);
7269}
7270
526b7aee
SV
7271static bool
7272arc_preserve_reload_p (rtx in)
7273{
7274 return (GET_CODE (in) == PLUS
7275 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
7276 && CONST_INT_P (XEXP (in, 1))
7277 && !((INTVAL (XEXP (in, 1)) & 511)));
7278}
7279
7280int
ef4bddc2 7281arc_register_move_cost (machine_mode,
526b7aee
SV
7282 enum reg_class from_class, enum reg_class to_class)
7283{
7284 /* The ARC600 has no bypass for extension registers, hence a nop might be
7285 needed to be inserted after a write so that reads are safe. */
7286 if (TARGET_ARC600)
7287 {
7288 if (to_class == MPY_WRITABLE_CORE_REGS)
7289 return 3;
7290 /* Instructions modifying LP_COUNT need 4 additional cycles before
7291 the register will actually contain the value. */
7292 else if (to_class == LPCOUNT_REG)
7293 return 6;
7294 else if (to_class == WRITABLE_CORE_REGS)
7295 return 6;
7296 }
7297
7298 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7299 if (TARGET_ARC700
7300 && (from_class == LPCOUNT_REG || from_class == ALL_CORE_REGS
7301 || from_class == WRITABLE_CORE_REGS))
7302 return 8;
7303
7304 /* Force an attempt to 'mov Dy,Dx' to spill. */
c4014855 7305 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
526b7aee
SV
7306 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
7307 return 100;
7308
7309 return 2;
7310}
7311
7312/* Emit code for an addsi3 instruction with OPERANDS.
7313 COND_P indicates if this will use conditional execution.
7314 Return the length of the instruction.
7315 If OUTPUT_P is false, don't actually output the instruction, just return
7316 its length. */
7317int
7318arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
7319{
3bbe0b82 7320 char format[35];
526b7aee
SV
7321
7322 int match = operands_match_p (operands[0], operands[1]);
7323 int match2 = operands_match_p (operands[0], operands[2]);
7324 int intval = (REG_P (operands[2]) ? 1
7325 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
7326 int neg_intval = -intval;
7327 int short_0 = satisfies_constraint_Rcq (operands[0]);
7328 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
7329 int ret = 0;
7330
7331#define ADDSI_OUTPUT1(FORMAT) do {\
7332 if (output_p) \
7333 output_asm_insn (FORMAT, operands);\
7334 return ret; \
7335} while (0)
7336#define ADDSI_OUTPUT(LIST) do {\
7337 if (output_p) \
7338 sprintf LIST;\
7339 ADDSI_OUTPUT1 (format);\
7340 return ret; \
7341} while (0)
7342
7343 /* First try to emit a 16 bit insn. */
7344 ret = 2;
7345 if (!cond_p
7346 /* If we are actually about to output this insn, don't try a 16 bit
7347 variant if we already decided that we don't want that
7348 (I.e. we upsized this insn to align some following insn.)
7349 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7350 but add1 r0,sp,35 doesn't. */
7351 && (!output_p || (get_attr_length (current_output_insn) & 2)))
7352 {
7353 if (short_p
7354 && (REG_P (operands[2])
7355 ? (match || satisfies_constraint_Rcq (operands[2]))
7356 : (unsigned) intval <= (match ? 127 : 7)))
7357 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7358 if (short_0 && REG_P (operands[1]) && match2)
7359 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7360 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
7361 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
7362 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7363
7364 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
7365 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
7366 && match && !(neg_intval & ~124)))
7367 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7368 }
7369
7370 /* Now try to emit a 32 bit insn without long immediate. */
7371 ret = 4;
7372 if (!match && match2 && REG_P (operands[1]))
7373 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7374 if (match || !cond_p)
7375 {
7376 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
7377 int range_factor = neg_intval & intval;
7378 int shift;
7379
c419f71c 7380 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
526b7aee
SV
7381 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7382
7383 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7384 same size, do, so - the insn latency is lower. */
7385 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7386 0x800 is not. */
7387 if ((intval >= 0 && intval <= limit)
7388 || (intval == -0x800 && limit == 0x7ff))
7389 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7390 else if ((intval < 0 && neg_intval <= limit)
7391 || (intval == 0x800 && limit == 0x7ff))
7392 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7393 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
7394 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
7395 gcc_assert ((((1 << shift) - 1) & intval) == 0);
7396 if (((intval < 0 && intval != -0x4000)
7397 /* sub[123] is slower than add_s / sub, only use it if it
7398 avoids a long immediate. */
7399 && neg_intval <= limit << shift)
7400 || (intval == 0x4000 && limit == 0x7ff))
7401 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
7402 shift, neg_intval >> shift));
7403 else if ((intval >= 0 && intval <= limit << shift)
7404 || (intval == -0x4000 && limit == 0x7ff))
7405 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
7406 }
7407 /* Try to emit a 16 bit opcode with long immediate. */
7408 ret = 6;
7409 if (short_p && match)
7410 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7411
7412 /* We have to use a 32 bit opcode, and with a long immediate. */
7413 ret = 8;
7414 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7415}
7416
7417/* Emit code for an commutative_cond_exec instruction with OPERANDS.
7418 Return the length of the instruction.
7419 If OUTPUT_P is false, don't actually output the instruction, just return
7420 its length. */
7421int
7422arc_output_commutative_cond_exec (rtx *operands, bool output_p)
7423{
7424 enum rtx_code commutative_op = GET_CODE (operands[3]);
7425 const char *pat = NULL;
7426
7427 /* Canonical rtl should not have a constant in the first operand position. */
7428 gcc_assert (!CONSTANT_P (operands[1]));
7429
7430 switch (commutative_op)
7431 {
7432 case AND:
7433 if (satisfies_constraint_C1p (operands[2]))
7434 pat = "bmsk%? %0,%1,%Z2";
fc1c2d04
CZ
7435 else if (satisfies_constraint_C2p (operands[2]))
7436 {
7437 operands[2] = GEN_INT ((~INTVAL (operands[2])));
7438 pat = "bmskn%? %0,%1,%Z2";
7439 }
526b7aee
SV
7440 else if (satisfies_constraint_Ccp (operands[2]))
7441 pat = "bclr%? %0,%1,%M2";
7442 else if (satisfies_constraint_CnL (operands[2]))
7443 pat = "bic%? %0,%1,%n2-1";
7444 break;
7445 case IOR:
7446 if (satisfies_constraint_C0p (operands[2]))
7447 pat = "bset%? %0,%1,%z2";
7448 break;
7449 case XOR:
7450 if (satisfies_constraint_C0p (operands[2]))
7451 pat = "bxor%? %0,%1,%z2";
7452 break;
7453 case PLUS:
7454 return arc_output_addsi (operands, true, output_p);
7455 default: break;
7456 }
7457 if (output_p)
7458 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
7459 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
7460 return 4;
7461 return 8;
7462}
7463
7464/* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7465 Emit code and return an potentially modified address such that offsets
7466 up to SIZE are can be added to yield a legitimate address.
7467 if REUSE is set, ADDR is a register that may be modified. */
7468
7469static rtx
7470force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
7471{
7472 rtx base = addr;
7473 rtx offs = const0_rtx;
7474
7475 if (GET_CODE (base) == PLUS)
7476 {
7477 offs = XEXP (base, 1);
7478 base = XEXP (base, 0);
7479 }
7480 if (!REG_P (base)
7481 || (REGNO (base) != STACK_POINTER_REGNUM
7482 && REGNO_PTR_FRAME_P (REGNO (addr)))
7483 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
7484 || !SMALL_INT (INTVAL (offs) + size))
7485 {
7486 if (reuse)
7487 emit_insn (gen_add2_insn (addr, offs));
7488 else
7489 addr = copy_to_mode_reg (Pmode, addr);
7490 }
7491 return addr;
7492}
7493
d34a0fdc
CZ
7494/* Like move_by_pieces, but take account of load latency, and actual
7495 offset ranges. Return true on success. */
526b7aee
SV
7496
7497bool
7498arc_expand_movmem (rtx *operands)
7499{
7500 rtx dst = operands[0];
7501 rtx src = operands[1];
7502 rtx dst_addr, src_addr;
7503 HOST_WIDE_INT size;
7504 int align = INTVAL (operands[3]);
7505 unsigned n_pieces;
7506 int piece = align;
7507 rtx store[2];
7508 rtx tmpx[2];
7509 int i;
7510
7511 if (!CONST_INT_P (operands[2]))
7512 return false;
7513 size = INTVAL (operands[2]);
7514 /* move_by_pieces_ninsns is static, so we can't use it. */
7515 if (align >= 4)
d34a0fdc
CZ
7516 {
7517 if (TARGET_LL64)
7518 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
7519 else
7520 n_pieces = (size + 2) / 4U + (size & 1);
7521 }
526b7aee
SV
7522 else if (align == 2)
7523 n_pieces = (size + 1) / 2U;
7524 else
7525 n_pieces = size;
7526 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
7527 return false;
d34a0fdc
CZ
7528 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7529 possible. */
7530 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
7531 piece = 8;
7532 else if (piece > 4)
526b7aee
SV
7533 piece = 4;
7534 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
7535 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
7536 store[0] = store[1] = NULL_RTX;
7537 tmpx[0] = tmpx[1] = NULL_RTX;
7538 for (i = 0; size > 0; i ^= 1, size -= piece)
7539 {
7540 rtx tmp;
ef4bddc2 7541 machine_mode mode;
526b7aee 7542
d34a0fdc
CZ
7543 while (piece > size)
7544 piece >>= 1;
526b7aee
SV
7545 mode = smallest_mode_for_size (piece * BITS_PER_UNIT, MODE_INT);
7546 /* If we don't re-use temporaries, the scheduler gets carried away,
7547 and the register pressure gets unnecessarily high. */
7548 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
7549 tmp = tmpx[i];
7550 else
7551 tmpx[i] = tmp = gen_reg_rtx (mode);
7552 dst_addr = force_offsettable (dst_addr, piece, 1);
7553 src_addr = force_offsettable (src_addr, piece, 1);
7554 if (store[i])
7555 emit_insn (store[i]);
7556 emit_move_insn (tmp, change_address (src, mode, src_addr));
7557 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
7558 dst_addr = plus_constant (Pmode, dst_addr, piece);
7559 src_addr = plus_constant (Pmode, src_addr, piece);
7560 }
7561 if (store[i])
7562 emit_insn (store[i]);
7563 if (store[i^1])
7564 emit_insn (store[i^1]);
7565 return true;
7566}
7567
7568/* Prepare operands for move in MODE. Return true iff the move has
7569 been emitted. */
7570
7571bool
ef4bddc2 7572prepare_move_operands (rtx *operands, machine_mode mode)
526b7aee
SV
7573{
7574 /* We used to do this only for MODE_INT Modes, but addresses to floating
7575 point variables may well be in the small data section. */
28633bbd
CZ
7576 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
7577 operands[0] = arc_rewrite_small_data (operands[0]);
7578
7579 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
526b7aee 7580 {
28633bbd 7581 prepare_pic_move (operands, SImode);
526b7aee 7582
28633bbd
CZ
7583 /* Disable any REG_EQUALs associated with the symref
7584 otherwise the optimization pass undoes the work done
7585 here and references the variable directly. */
7586 }
7587
7588 if (GET_CODE (operands[0]) != MEM
7589 && !TARGET_NO_SDATA_SET
7590 && small_data_pattern (operands[1], Pmode))
7591 {
7592 /* This is to take care of address calculations involving sdata
7593 variables. */
7594 operands[1] = arc_rewrite_small_data (operands[1]);
7595
7596 emit_insn (gen_rtx_SET (operands[0],operands[1]));
7597 /* ??? This note is useless, since it only restates the set itself.
7598 We should rather use the original SYMBOL_REF. However, there is
7599 the problem that we are lying to the compiler about these
7600 SYMBOL_REFs to start with. symbol@sda should be encoded specially
7601 so that we can tell it apart from an actual symbol. */
7602 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7603
7604 /* Take care of the REG_EQUAL note that will be attached to mark the
7605 output reg equal to the initial symbol_ref after this code is
7606 executed. */
7607 emit_move_insn (operands[0], operands[0]);
7608 return true;
526b7aee
SV
7609 }
7610
7611 if (MEM_P (operands[0])
7612 && !(reload_in_progress || reload_completed))
7613 {
7614 operands[1] = force_reg (mode, operands[1]);
7615 if (!move_dest_operand (operands[0], mode))
7616 {
7617 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7618 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
7619 except that we can't use that function because it is static. */
7620 rtx pat = change_address (operands[0], mode, addr);
7621 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7622 operands[0] = pat;
7623 }
7624 if (!cse_not_expected)
7625 {
7626 rtx pat = XEXP (operands[0], 0);
7627
7628 pat = arc_legitimize_address_0 (pat, pat, mode);
7629 if (pat)
7630 {
7631 pat = change_address (operands[0], mode, pat);
7632 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7633 operands[0] = pat;
7634 }
7635 }
7636 }
7637
7638 if (MEM_P (operands[1]) && !cse_not_expected)
7639 {
7640 rtx pat = XEXP (operands[1], 0);
7641
7642 pat = arc_legitimize_address_0 (pat, pat, mode);
7643 if (pat)
7644 {
7645 pat = change_address (operands[1], mode, pat);
7646 MEM_COPY_ATTRIBUTES (pat, operands[1]);
7647 operands[1] = pat;
7648 }
7649 }
7650
7651 return false;
7652}
7653
7654/* Prepare OPERANDS for an extension using CODE to OMODE.
7655 Return true iff the move has been emitted. */
7656
7657bool
7658prepare_extend_operands (rtx *operands, enum rtx_code code,
ef4bddc2 7659 machine_mode omode)
526b7aee
SV
7660{
7661 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
7662 {
7663 /* This is to take care of address calculations involving sdata
7664 variables. */
7665 operands[1]
7666 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
f7df4a84 7667 emit_insn (gen_rtx_SET (operands[0], operands[1]));
526b7aee
SV
7668 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7669
7670 /* Take care of the REG_EQUAL note that will be attached to mark the
7671 output reg equal to the initial extension after this code is
7672 executed. */
7673 emit_move_insn (operands[0], operands[0]);
7674 return true;
7675 }
7676 return false;
7677}
7678
7679/* Output a library call to a function called FNAME that has been arranged
7680 to be local to any dso. */
7681
7682const char *
7683arc_output_libcall (const char *fname)
7684{
7685 unsigned len = strlen (fname);
7686 static char buf[64];
7687
7688 gcc_assert (len < sizeof buf - 35);
7689 if (TARGET_LONG_CALLS_SET
7690 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
7691 {
7692 if (flag_pic)
f5e336b1 7693 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
526b7aee
SV
7694 else
7695 sprintf (buf, "jl%%! @%s", fname);
7696 }
7697 else
7698 sprintf (buf, "bl%%!%%* @%s", fname);
7699 return buf;
7700}
7701
7702/* Return the SImode highpart of the DImode value IN. */
7703
7704rtx
7705disi_highpart (rtx in)
7706{
7707 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
7708}
7709
526b7aee
SV
7710/* Return length adjustment for INSN.
7711 For ARC600:
7712 A write to a core reg greater or equal to 32 must not be immediately
7713 followed by a use. Anticipate the length requirement to insert a nop
7714 between PRED and SUCC to prevent a hazard. */
7715
7716static int
647d790d 7717arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee
SV
7718{
7719 if (!TARGET_ARC600)
7720 return 0;
7721 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
7722 in front of SUCC anyway, so there will be separation between PRED and
7723 SUCC. */
7724 if (recog_memoized (succ) == CODE_FOR_doloop_end_i
7725 && LABEL_P (prev_nonnote_insn (succ)))
7726 return 0;
7727 if (recog_memoized (succ) == CODE_FOR_doloop_begin_i)
7728 return 0;
7729 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
647d790d 7730 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
526b7aee 7731 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
647d790d 7732 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
526b7aee
SV
7733 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7734 || recog_memoized (pred) == CODE_FOR_umul_600
7735 || recog_memoized (pred) == CODE_FOR_mac_600
7736 || recog_memoized (pred) == CODE_FOR_mul64_600
7737 || recog_memoized (pred) == CODE_FOR_mac64_600
7738 || recog_memoized (pred) == CODE_FOR_umul64_600
7739 || recog_memoized (pred) == CODE_FOR_umac64_600)
7740 return 0;
36cc6254
RS
7741 subrtx_iterator::array_type array;
7742 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7743 {
7744 const_rtx x = *iter;
7745 switch (GET_CODE (x))
7746 {
7747 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7748 break;
7749 default:
7750 /* This is also fine for PRE/POST_MODIFY, because they
7751 contain a SET. */
7752 continue;
7753 }
7754 rtx dest = XEXP (x, 0);
7755 /* Check if this sets a an extension register. N.B. we use 61 for the
7756 condition codes, which is definitely not an extension register. */
7757 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7758 /* Check if the same register is used by the PAT. */
7759 && (refers_to_regno_p
7760 (REGNO (dest),
7761 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7762 PATTERN (succ), 0)))
7763 return 4;
7764 }
7765 return 0;
526b7aee
SV
7766}
7767
f50bb868
CZ
7768/* Given a rtx, check if it is an assembly instruction or not. */
7769
7770static int
7771arc_asm_insn_p (rtx x)
7772{
7773 int i, j;
7774
7775 if (x == 0)
7776 return 0;
7777
7778 switch (GET_CODE (x))
7779 {
7780 case ASM_OPERANDS:
7781 case ASM_INPUT:
7782 return 1;
7783
7784 case SET:
7785 return arc_asm_insn_p (SET_SRC (x));
7786
7787 case PARALLEL:
7788 j = 0;
7789 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
7790 j += arc_asm_insn_p (XVECEXP (x, 0, i));
7791 if ( j > 0)
7792 return 1;
7793 break;
7794
7795 default:
7796 break;
7797 }
7798
7799 return 0;
7800}
7801
7802/* We might have a CALL to a non-returning function before a loop end.
7803 ??? Although the manual says that's OK (the target is outside the
7804 loop, and the loop counter unused there), the assembler barfs on
7805 this for ARC600, so we must insert a nop before such a call too.
7806 For ARC700, and ARCv2 is not allowed to have the last ZOL
7807 instruction a jump to a location where lp_count is modified. */
7808
7809static bool
7810arc_loop_hazard (rtx_insn *pred, rtx_insn *succ)
7811{
7812 rtx_insn *jump = NULL;
a30c5ca4 7813 rtx label_rtx = NULL_RTX;
f50bb868
CZ
7814 rtx_insn *label = NULL;
7815 basic_block succ_bb;
7816
7817 if (recog_memoized (succ) != CODE_FOR_doloop_end_i)
7818 return false;
7819
7820 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
7821 (i.e., jump/call) as the last instruction of a ZOL. */
7822 if (TARGET_ARC600 || TARGET_HS)
7823 if (JUMP_P (pred) || CALL_P (pred)
7824 || arc_asm_insn_p (PATTERN (pred))
7825 || GET_CODE (PATTERN (pred)) == SEQUENCE)
7826 return true;
7827
7828 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
7829 instruction a jump to a location where lp_count is modified. */
7830
7831 /* Phase 2a: Dig for the jump instruction. */
7832 if (JUMP_P (pred))
7833 jump = pred;
7834 else if (GET_CODE (PATTERN (pred)) == SEQUENCE
7835 && JUMP_P (XVECEXP (PATTERN (pred), 0, 0)))
f857b8ef 7836 jump = as_a <rtx_insn *> (XVECEXP (PATTERN (pred), 0, 0));
f50bb868
CZ
7837 else
7838 return false;
7839
f50bb868
CZ
7840 /* Phase 2b: Make sure is not a millicode jump. */
7841 if ((GET_CODE (PATTERN (jump)) == PARALLEL)
7842 && (XVECEXP (PATTERN (jump), 0, 0) == ret_rtx))
7843 return false;
7844
a30c5ca4
AB
7845 label_rtx = JUMP_LABEL (jump);
7846 if (!label_rtx)
7847 return false;
7848
7849 /* Phase 2c: Make sure is not a return. */
7850 if (ANY_RETURN_P (label_rtx))
f50bb868
CZ
7851 return false;
7852
7853 /* Pahse 2d: Go to the target of the jump and check for aliveness of
7854 LP_COUNT register. */
a30c5ca4 7855 label = safe_as_a <rtx_insn *> (label_rtx);
f50bb868
CZ
7856 succ_bb = BLOCK_FOR_INSN (label);
7857 if (!succ_bb)
7858 {
7859 gcc_assert (NEXT_INSN (label));
7860 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label)))
7861 succ_bb = NOTE_BASIC_BLOCK (NEXT_INSN (label));
7862 else
7863 succ_bb = BLOCK_FOR_INSN (NEXT_INSN (label));
7864 }
7865
7866 if (succ_bb && REGNO_REG_SET_P (df_get_live_out (succ_bb), LP_COUNT))
7867 return true;
7868
7869 return false;
7870}
7871
526b7aee
SV
7872/* For ARC600:
7873 A write to a core reg greater or equal to 32 must not be immediately
7874 followed by a use. Anticipate the length requirement to insert a nop
7875 between PRED and SUCC to prevent a hazard. */
7876
7877int
647d790d 7878arc_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee 7879{
526b7aee
SV
7880 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7881 return 0;
f50bb868
CZ
7882
7883 if (arc_loop_hazard (pred, succ))
526b7aee 7884 return 4;
f50bb868
CZ
7885
7886 if (TARGET_ARC600)
7887 return arc600_corereg_hazard (pred, succ);
7888
7889 return 0;
526b7aee
SV
7890}
7891
7892/* Return length adjustment for INSN. */
7893
7894int
647d790d 7895arc_adjust_insn_length (rtx_insn *insn, int len, bool)
526b7aee
SV
7896{
7897 if (!INSN_P (insn))
7898 return len;
7899 /* We already handle sequences by ignoring the delay sequence flag. */
7900 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
7901 return len;
7902
7903 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
7904 the ZOL mechanism only triggers when advancing to the end address,
7905 so if there's a label at the end of a ZOL, we need to insert a nop.
7906 The ARC600 ZOL also has extra restrictions on jumps at the end of a
7907 loop. */
7908 if (recog_memoized (insn) == CODE_FOR_doloop_end_i)
7909 {
b3458f61 7910 rtx_insn *prev = prev_nonnote_insn (insn);
526b7aee
SV
7911
7912 return ((LABEL_P (prev)
7913 || (TARGET_ARC600
7914 && (JUMP_P (prev)
7915 || CALL_P (prev) /* Could be a noreturn call. */
7916 || (NONJUMP_INSN_P (prev)
7917 && GET_CODE (PATTERN (prev)) == SEQUENCE))))
7918 ? len + 4 : len);
7919 }
7920
7921 /* Check for return with but one preceding insn since function
7922 start / call. */
7923 if (TARGET_PAD_RETURN
7924 && JUMP_P (insn)
7925 && GET_CODE (PATTERN (insn)) != ADDR_VEC
7926 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
7927 && get_attr_type (insn) == TYPE_RETURN)
7928 {
84034c69 7929 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
7930
7931 if (!prev || !(prev = prev_active_insn (prev))
7932 || ((NONJUMP_INSN_P (prev)
7933 && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
7934 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
7935 NON_SIBCALL)
526b7aee
SV
7936 : CALL_ATTR (prev, NON_SIBCALL)))
7937 return len + 4;
7938 }
7939 if (TARGET_ARC600)
7940 {
b3458f61 7941 rtx_insn *succ = next_real_insn (insn);
526b7aee
SV
7942
7943 /* One the ARC600, a write to an extension register must be separated
7944 from a read. */
7945 if (succ && INSN_P (succ))
7946 len += arc600_corereg_hazard (insn, succ);
7947 }
7948
7949 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
7950 can go awry. */
7951 extract_constrain_insn_cached (insn);
7952
7953 return len;
7954}
7955
7956/* Values for length_sensitive. */
7957enum
7958{
7959 ARC_LS_NONE,// Jcc
7960 ARC_LS_25, // 25 bit offset, B
7961 ARC_LS_21, // 21 bit offset, Bcc
7962 ARC_LS_U13,// 13 bit unsigned offset, LP
7963 ARC_LS_10, // 10 bit offset, B_s, Beq_s, Bne_s
7964 ARC_LS_9, // 9 bit offset, BRcc
7965 ARC_LS_8, // 8 bit offset, BRcc_s
7966 ARC_LS_U7, // 7 bit unsigned offset, LPcc
7967 ARC_LS_7 // 7 bit offset, Bcc_s
7968};
7969
7970/* While the infrastructure patch is waiting for review, duplicate the
7971 struct definitions, to allow this file to compile. */
7972#if 1
7973typedef struct
7974{
7975 unsigned align_set;
7976 /* Cost as a branch / call target or call return address. */
7977 int target_cost;
7978 int fallthrough_cost;
7979 int branch_cost;
7980 int length;
7981 /* 0 for not length sensitive, 1 for largest offset range,
7982 * 2 for next smaller etc. */
7983 unsigned length_sensitive : 8;
7984 bool enabled;
7985} insn_length_variant_t;
7986
7987typedef struct insn_length_parameters_s
7988{
7989 int align_unit_log;
7990 int align_base_log;
7991 int max_variants;
647d790d 7992 int (*get_variants) (rtx_insn *, int, bool, bool, insn_length_variant_t *);
526b7aee
SV
7993} insn_length_parameters_t;
7994
7995static void
7996arc_insn_length_parameters (insn_length_parameters_t *ilp) ATTRIBUTE_UNUSED;
7997#endif
7998
7999static int
647d790d 8000arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
526b7aee
SV
8001 insn_length_variant_t *ilv)
8002{
8003 if (!NONDEBUG_INSN_P (insn))
8004 return 0;
8005 enum attr_type type;
8006 /* shorten_branches doesn't take optimize_size into account yet for the
8007 get_variants mechanism, so turn this off for now. */
8008 if (optimize_size)
8009 return 0;
647d790d 8010 if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
526b7aee
SV
8011 {
8012 /* The interaction of a short delay slot insn with a short branch is
8013 too weird for shorten_branches to piece together, so describe the
8014 entire SEQUENCE. */
647d790d 8015 rtx_insn *inner;
526b7aee 8016 if (TARGET_UPSIZE_DBR
84034c69 8017 && get_attr_length (pat->insn (1)) <= 2
647d790d 8018 && (((type = get_attr_type (inner = pat->insn (0)))
526b7aee
SV
8019 == TYPE_UNCOND_BRANCH)
8020 || type == TYPE_BRANCH)
8021 && get_attr_delay_slot_filled (inner) == DELAY_SLOT_FILLED_YES)
8022 {
8023 int n_variants
8024 = arc_get_insn_variants (inner, get_attr_length (inner), true,
8025 target_p, ilv+1);
8026 /* The short variant gets split into a higher-cost aligned
8027 and a lower cost unaligned variant. */
8028 gcc_assert (n_variants);
8029 gcc_assert (ilv[1].length_sensitive == ARC_LS_7
8030 || ilv[1].length_sensitive == ARC_LS_10);
8031 gcc_assert (ilv[1].align_set == 3);
8032 ilv[0] = ilv[1];
8033 ilv[0].align_set = 1;
8034 ilv[0].branch_cost += 1;
8035 ilv[1].align_set = 2;
8036 n_variants++;
8037 for (int i = 0; i < n_variants; i++)
8038 ilv[i].length += 2;
8039 /* In case an instruction with aligned size is wanted, and
8040 the short variants are unavailable / too expensive, add
8041 versions of long branch + long delay slot. */
8042 for (int i = 2, end = n_variants; i < end; i++, n_variants++)
8043 {
8044 ilv[n_variants] = ilv[i];
8045 ilv[n_variants].length += 2;
8046 }
8047 return n_variants;
8048 }
8049 return 0;
8050 }
8051 insn_length_variant_t *first_ilv = ilv;
8052 type = get_attr_type (insn);
8053 bool delay_filled
8054 = (get_attr_delay_slot_filled (insn) == DELAY_SLOT_FILLED_YES);
8055 int branch_align_cost = delay_filled ? 0 : 1;
8056 int branch_unalign_cost = delay_filled ? 0 : TARGET_UNALIGN_BRANCH ? 0 : 1;
8057 /* If the previous instruction is an sfunc call, this insn is always
8058 a target, even though the middle-end is unaware of this. */
8059 bool force_target = false;
b3458f61 8060 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8061 if (prev && arc_next_active_insn (prev, 0) == insn
8062 && ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8063 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8064 NON_SIBCALL)
526b7aee
SV
8065 : (CALL_ATTR (prev, NON_SIBCALL)
8066 && NEXT_INSN (PREV_INSN (prev)) == prev)))
8067 force_target = true;
8068
8069 switch (type)
8070 {
8071 case TYPE_BRCC:
8072 /* Short BRCC only comes in no-delay-slot version, and without limm */
8073 if (!delay_filled)
8074 {
8075 ilv->align_set = 3;
8076 ilv->length = 2;
8077 ilv->branch_cost = 1;
8078 ilv->enabled = (len == 2);
8079 ilv->length_sensitive = ARC_LS_8;
8080 ilv++;
8081 }
8082 /* Fall through. */
8083 case TYPE_BRCC_NO_DELAY_SLOT:
8084 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8085 (delay slot) scheduling purposes, but they are longer. */
8086 if (GET_CODE (PATTERN (insn)) == PARALLEL
8087 && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET)
8088 return 0;
8089 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8090 ilv->length = ((type == TYPE_BRCC) ? 4 : 8);
8091 ilv->align_set = 3;
8092 ilv->branch_cost = branch_align_cost;
8093 ilv->enabled = (len <= ilv->length);
8094 ilv->length_sensitive = ARC_LS_9;
8095 if ((target_p || force_target)
8096 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8097 {
8098 ilv[1] = *ilv;
8099 ilv->align_set = 1;
8100 ilv++;
8101 ilv->align_set = 2;
8102 ilv->target_cost = 1;
8103 ilv->branch_cost = branch_unalign_cost;
8104 }
8105 ilv++;
8106
8107 rtx op, op0;
8108 op = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
8109 op0 = XEXP (op, 0);
8110
8111 if (GET_CODE (op0) == ZERO_EXTRACT
8112 && satisfies_constraint_L (XEXP (op0, 2)))
8113 op0 = XEXP (op0, 0);
8114 if (satisfies_constraint_Rcq (op0))
8115 {
8116 ilv->length = ((type == TYPE_BRCC) ? 6 : 10);
8117 ilv->align_set = 3;
8118 ilv->branch_cost = 1 + branch_align_cost;
8119 ilv->fallthrough_cost = 1;
8120 ilv->enabled = true;
8121 ilv->length_sensitive = ARC_LS_21;
8122 if (!delay_filled && TARGET_UNALIGN_BRANCH)
8123 {
8124 ilv[1] = *ilv;
8125 ilv->align_set = 1;
8126 ilv++;
8127 ilv->align_set = 2;
8128 ilv->branch_cost = 1 + branch_unalign_cost;
8129 }
8130 ilv++;
8131 }
8132 ilv->length = ((type == TYPE_BRCC) ? 8 : 12);
8133 ilv->align_set = 3;
8134 ilv->branch_cost = 1 + branch_align_cost;
8135 ilv->fallthrough_cost = 1;
8136 ilv->enabled = true;
8137 ilv->length_sensitive = ARC_LS_21;
8138 if ((target_p || force_target)
8139 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8140 {
8141 ilv[1] = *ilv;
8142 ilv->align_set = 1;
8143 ilv++;
8144 ilv->align_set = 2;
8145 ilv->target_cost = 1;
8146 ilv->branch_cost = 1 + branch_unalign_cost;
8147 }
8148 ilv++;
8149 break;
8150
8151 case TYPE_SFUNC:
8152 ilv->length = 12;
8153 goto do_call;
8154 case TYPE_CALL_NO_DELAY_SLOT:
8155 ilv->length = 8;
8156 goto do_call;
8157 case TYPE_CALL:
8158 ilv->length = 4;
8159 ilv->length_sensitive
8160 = GET_CODE (PATTERN (insn)) == COND_EXEC ? ARC_LS_21 : ARC_LS_25;
8161 do_call:
8162 ilv->align_set = 3;
8163 ilv->fallthrough_cost = branch_align_cost;
8164 ilv->enabled = true;
8165 if ((target_p || force_target)
8166 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8167 {
8168 ilv[1] = *ilv;
8169 ilv->align_set = 1;
8170 ilv++;
8171 ilv->align_set = 2;
8172 ilv->target_cost = 1;
8173 ilv->fallthrough_cost = branch_unalign_cost;
8174 }
8175 ilv++;
8176 break;
8177 case TYPE_UNCOND_BRANCH:
8178 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8179 but that makes no difference at the moment. */
8180 ilv->length_sensitive = ARC_LS_7;
8181 ilv[1].length_sensitive = ARC_LS_25;
8182 goto do_branch;
8183 case TYPE_BRANCH:
8184 ilv->length_sensitive = ARC_LS_10;
8185 ilv[1].length_sensitive = ARC_LS_21;
8186 do_branch:
8187 ilv->align_set = 3;
8188 ilv->length = 2;
8189 ilv->branch_cost = branch_align_cost;
8190 ilv->enabled = (len == ilv->length);
8191 ilv++;
8192 ilv->length = 4;
8193 ilv->align_set = 3;
8194 ilv->branch_cost = branch_align_cost;
8195 ilv->enabled = true;
8196 if ((target_p || force_target)
8197 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8198 {
8199 ilv[1] = *ilv;
8200 ilv->align_set = 1;
8201 ilv++;
8202 ilv->align_set = 2;
8203 ilv->target_cost = 1;
8204 ilv->branch_cost = branch_unalign_cost;
8205 }
8206 ilv++;
8207 break;
8208 case TYPE_JUMP:
8209 return 0;
8210 default:
8211 /* For every short insn, there is generally also a long insn.
8212 trap_s is an exception. */
8213 if ((len & 2) == 0 || recog_memoized (insn) == CODE_FOR_trap_s)
8214 return 0;
8215 ilv->align_set = 3;
8216 ilv->length = len;
8217 ilv->enabled = 1;
8218 ilv++;
8219 ilv->align_set = 3;
8220 ilv->length = len + 2;
8221 ilv->enabled = 1;
8222 if (target_p || force_target)
8223 {
8224 ilv[1] = *ilv;
8225 ilv->align_set = 1;
8226 ilv++;
8227 ilv->align_set = 2;
8228 ilv->target_cost = 1;
8229 }
8230 ilv++;
8231 }
8232 /* If the previous instruction is an sfunc call, this insn is always
8233 a target, even though the middle-end is unaware of this.
8234 Therefore, if we have a call predecessor, transfer the target cost
8235 to the fallthrough and branch costs. */
8236 if (force_target)
8237 {
8238 for (insn_length_variant_t *p = first_ilv; p < ilv; p++)
8239 {
8240 p->fallthrough_cost += p->target_cost;
8241 p->branch_cost += p->target_cost;
8242 p->target_cost = 0;
8243 }
8244 }
8245
8246 return ilv - first_ilv;
8247}
8248
8249static void
8250arc_insn_length_parameters (insn_length_parameters_t *ilp)
8251{
8252 ilp->align_unit_log = 1;
8253 ilp->align_base_log = 1;
8254 ilp->max_variants = 7;
8255 ilp->get_variants = arc_get_insn_variants;
8256}
8257
8258/* Return a copy of COND from *STATEP, inverted if that is indicated by the
8259 CC field of *STATEP. */
8260
8261static rtx
8262arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8263{
8264 rtx cond = statep->cond;
8265 int raw_cc = get_arc_condition_code (cond);
8266 if (reverse)
8267 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8268
8269 if (statep->cc == raw_cc)
8270 return copy_rtx (cond);
8271
8272 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8273
ef4bddc2 8274 machine_mode ccm = GET_MODE (XEXP (cond, 0));
526b7aee
SV
8275 enum rtx_code code = reverse_condition (GET_CODE (cond));
8276 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8277 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8278
8279 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8280 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8281}
8282
bae56bbb
JR
8283/* Return version of PAT conditionalized with COND, which is part of INSN.
8284 ANNULLED indicates if INSN is an annulled delay-slot insn.
8285 Register further changes if necessary. */
8286static rtx
8287conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8288{
8289 /* For commutative operators, we generally prefer to have
8290 the first source match the destination. */
8291 if (GET_CODE (pat) == SET)
8292 {
8293 rtx src = SET_SRC (pat);
8294
8295 if (COMMUTATIVE_P (src))
8296 {
8297 rtx src0 = XEXP (src, 0);
8298 rtx src1 = XEXP (src, 1);
8299 rtx dst = SET_DEST (pat);
8300
8301 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8302 /* Leave add_n alone - the canonical form is to
8303 have the complex summand first. */
8304 && REG_P (src0))
f7df4a84 8305 pat = gen_rtx_SET (dst,
bae56bbb
JR
8306 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8307 src1, src0));
8308 }
8309 }
8310
8311 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8312 what to do with COND_EXEC. */
8313 if (RTX_FRAME_RELATED_P (insn))
8314 {
8315 /* If this is the delay slot insn of an anulled branch,
8316 dwarf2out.c:scan_trace understands the anulling semantics
8317 without the COND_EXEC. */
8318 gcc_assert (annulled);
8319 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8320 REG_NOTES (insn));
8321 validate_change (insn, &REG_NOTES (insn), note, 1);
8322 }
8323 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8324 return pat;
8325}
8326
526b7aee
SV
8327/* Use the ccfsm machinery to do if conversion. */
8328
8329static unsigned
8330arc_ifcvt (void)
8331{
8332 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8333 basic_block merge_bb = 0;
8334
8335 memset (statep, 0, sizeof *statep);
b3458f61 8336 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
526b7aee
SV
8337 {
8338 arc_ccfsm_advance (insn, statep);
8339
8340 switch (statep->state)
8341 {
8342 case 0:
8343 if (JUMP_P (insn))
8344 merge_bb = 0;
8345 break;
8346 case 1: case 2:
8347 {
8348 /* Deleted branch. */
8349 gcc_assert (!merge_bb);
8350 merge_bb = BLOCK_FOR_INSN (insn);
8351 basic_block succ_bb
8352 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn))));
8353 arc_ccfsm_post_advance (insn, statep);
53ea364f 8354 gcc_assert (!IN_RANGE (statep->state, 1, 2));
b3458f61 8355 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
526b7aee
SV
8356 if (seq != insn)
8357 {
8358 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8359 rtx pat = PATTERN (slot);
8360 if (INSN_ANNULLED_BRANCH_P (insn))
8361 {
8362 rtx cond
8363 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8364 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8365 }
8366 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8367 gcc_unreachable ();
8368 PUT_CODE (slot, NOTE);
8369 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8370 if (merge_bb && succ_bb)
8371 merge_blocks (merge_bb, succ_bb);
8372 }
8373 else if (merge_bb && succ_bb)
8374 {
8375 set_insn_deleted (insn);
8376 merge_blocks (merge_bb, succ_bb);
8377 }
8378 else
8379 {
8380 PUT_CODE (insn, NOTE);
8381 NOTE_KIND (insn) = NOTE_INSN_DELETED;
8382 }
8383 continue;
8384 }
8385 case 3:
8386 if (LABEL_P (insn)
8387 && statep->target_label == CODE_LABEL_NUMBER (insn))
8388 {
8389 arc_ccfsm_post_advance (insn, statep);
8390 basic_block succ_bb = BLOCK_FOR_INSN (insn);
8391 if (merge_bb && succ_bb)
8392 merge_blocks (merge_bb, succ_bb);
8393 else if (--LABEL_NUSES (insn) == 0)
8394 {
8395 const char *name = LABEL_NAME (insn);
8396 PUT_CODE (insn, NOTE);
8397 NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
8398 NOTE_DELETED_LABEL_NAME (insn) = name;
8399 }
8400 merge_bb = 0;
8401 continue;
8402 }
8403 /* Fall through. */
8404 case 4: case 5:
8405 if (!NONDEBUG_INSN_P (insn))
8406 break;
8407
8408 /* Conditionalized insn. */
8409
b3458f61
DM
8410 rtx_insn *prev, *pprev;
8411 rtx *patp, pat, cond;
bae56bbb 8412 bool annulled; annulled = false;
526b7aee
SV
8413
8414 /* If this is a delay slot insn in a non-annulled branch,
8415 don't conditionalize it. N.B., this should be fine for
8416 conditional return too. However, don't do this for
8417 unconditional branches, as these would be encountered when
8418 processing an 'else' part. */
8419 prev = PREV_INSN (insn);
8420 pprev = PREV_INSN (prev);
8421 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
bae56bbb
JR
8422 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8423 {
8424 if (!INSN_ANNULLED_BRANCH_P (prev))
8425 break;
8426 annulled = true;
8427 }
526b7aee
SV
8428
8429 patp = &PATTERN (insn);
8430 pat = *patp;
8431 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
8432 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
8433 {
8434 /* ??? don't conditionalize if all side effects are dead
8435 in the not-execute case. */
9bf218f9 8436
bae56bbb 8437 pat = conditionalize_nonjump (pat, cond, insn, annulled);
526b7aee
SV
8438 }
8439 else if (simplejump_p (insn))
8440 {
8441 patp = &SET_SRC (pat);
8442 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
8443 }
8444 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
8445 {
8446 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
f7df4a84 8447 pat = gen_rtx_SET (pc_rtx, pat);
526b7aee
SV
8448 }
8449 else
8450 gcc_unreachable ();
8451 validate_change (insn, patp, pat, 1);
8452 if (!apply_change_group ())
8453 gcc_unreachable ();
8454 if (JUMP_P (insn))
8455 {
b3458f61 8456 rtx_insn *next = next_nonnote_insn (insn);
526b7aee
SV
8457 if (GET_CODE (next) == BARRIER)
8458 delete_insn (next);
8459 if (statep->state == 3)
8460 continue;
8461 }
8462 break;
8463 default:
8464 gcc_unreachable ();
8465 }
8466 arc_ccfsm_post_advance (insn, statep);
8467 }
8468 return 0;
8469}
8470
0bc69b81
JR
8471/* Find annulled delay insns and convert them to use the appropriate predicate.
8472 This allows branch shortening to size up these insns properly. */
8473
8474static unsigned
8475arc_predicate_delay_insns (void)
8476{
b3458f61 8477 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
0bc69b81
JR
8478 {
8479 rtx pat, jump, dlay, src, cond, *patp;
8480 int reverse;
8481
8482 if (!NONJUMP_INSN_P (insn)
8483 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
8484 continue;
8485 jump = XVECEXP (pat, 0, 0);
8486 dlay = XVECEXP (pat, 0, 1);
8487 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
8488 continue;
8489 /* If the branch insn does the annulling, leave the delay insn alone. */
8490 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
8491 continue;
8492 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8493 on the other path. */
8494 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
8495 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
8496 src = SET_SRC (PATTERN (jump));
8497 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
8498 cond = XEXP (src, 0);
8499 if (XEXP (src, 2) == pc_rtx)
8500 reverse = 0;
8501 else if (XEXP (src, 1) == pc_rtx)
8502 reverse = 1;
8503 else
8504 gcc_unreachable ();
9af539fe 8505 if (reverse != !INSN_FROM_TARGET_P (dlay))
0bc69b81 8506 {
ef4bddc2 8507 machine_mode ccm = GET_MODE (XEXP (cond, 0));
0bc69b81
JR
8508 enum rtx_code code = reverse_condition (GET_CODE (cond));
8509 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8510 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8511
8512 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
8513 copy_rtx (XEXP (cond, 0)),
8514 copy_rtx (XEXP (cond, 1)));
8515 }
8516 else
8517 cond = copy_rtx (cond);
8518 patp = &PATTERN (dlay);
8519 pat = *patp;
eeac7d15 8520 pat = conditionalize_nonjump (pat, cond, dlay, true);
0bc69b81
JR
8521 validate_change (dlay, patp, pat, 1);
8522 if (!apply_change_group ())
8523 gcc_unreachable ();
8524 }
8525 return 0;
8526}
8527
526b7aee
SV
8528/* For ARC600: If a write to a core reg >=32 appears in a delay slot
8529 (other than of a forward brcc), it creates a hazard when there is a read
8530 of the same register at the branch target. We can't know what is at the
8531 branch target of calls, and for branches, we don't really know before the
8532 end of delay slot scheduling, either. Not only can individual instruction
8533 be hoisted out into a delay slot, a basic block can also be emptied this
8534 way, and branch and/or fall through targets be redirected. Hence we don't
8535 want such writes in a delay slot. */
526b7aee
SV
8536
8537/* Return nonzreo iff INSN writes to an extension core register. */
8538
8539int
8540arc_write_ext_corereg (rtx insn)
8541{
24dbe738
RS
8542 subrtx_iterator::array_type array;
8543 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
8544 {
8545 const_rtx x = *iter;
8546 switch (GET_CODE (x))
8547 {
8548 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8549 break;
8550 default:
8551 /* This is also fine for PRE/POST_MODIFY, because they
8552 contain a SET. */
8553 continue;
8554 }
8555 const_rtx dest = XEXP (x, 0);
8556 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
8557 return 1;
8558 }
8559 return 0;
526b7aee
SV
8560}
8561
8562/* This is like the hook, but returns NULL when it can't / won't generate
8563 a legitimate address. */
8564
8565static rtx
8566arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 8567 machine_mode mode)
526b7aee
SV
8568{
8569 rtx addr, inner;
8570
8571 if (flag_pic && SYMBOLIC_CONST (x))
8572 (x) = arc_legitimize_pic_address (x, 0);
8573 addr = x;
8574 if (GET_CODE (addr) == CONST)
8575 addr = XEXP (addr, 0);
8576 if (GET_CODE (addr) == PLUS
8577 && CONST_INT_P (XEXP (addr, 1))
8578 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
8579 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
8580 || (REG_P (XEXP (addr, 0))
8581 && (INTVAL (XEXP (addr, 1)) & 252))))
8582 {
8583 HOST_WIDE_INT offs, upper;
8584 int size = GET_MODE_SIZE (mode);
8585
8586 offs = INTVAL (XEXP (addr, 1));
8587 upper = (offs + 256 * size) & ~511 * size;
8588 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
8589#if 0 /* ??? this produces worse code for EEMBC idctrn01 */
8590 if (GET_CODE (x) == CONST)
8591 inner = gen_rtx_CONST (Pmode, inner);
8592#endif
8593 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
8594 x = addr;
8595 }
8596 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
8597 x = force_reg (Pmode, x);
ef4bddc2 8598 if (memory_address_p ((machine_mode) mode, x))
526b7aee
SV
8599 return x;
8600 return NULL_RTX;
8601}
8602
8603static rtx
ef4bddc2 8604arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
526b7aee 8605{
28633bbd
CZ
8606 if (GET_CODE (orig_x) == SYMBOL_REF)
8607 {
8608 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
8609 if (model != 0)
8610 return arc_legitimize_tls_address (orig_x, model);
8611 }
8612
526b7aee
SV
8613 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
8614
8615 if (new_x)
8616 return new_x;
8617 return orig_x;
8618}
8619
8620static rtx
8621arc_delegitimize_address_0 (rtx x)
8622{
f5e336b1 8623 rtx u, gp, p;
526b7aee
SV
8624
8625 if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
8626 {
f5e336b1
CZ
8627 if (XINT (u, 1) == ARC_UNSPEC_GOT
8628 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)
526b7aee
SV
8629 return XVECEXP (u, 0, 0);
8630 }
f5e336b1
CZ
8631 else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS
8632 && GET_CODE (u = XEXP (p, 0)) == UNSPEC
8633 && (XINT (u, 1) == ARC_UNSPEC_GOT
8634 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC))
8635 return gen_rtx_CONST
8636 (GET_MODE (x),
8637 gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1)));
526b7aee
SV
8638 else if (GET_CODE (x) == PLUS
8639 && ((REG_P (gp = XEXP (x, 0))
8640 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8641 || (GET_CODE (gp) == CONST
8642 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8643 && XINT (u, 1) == ARC_UNSPEC_GOT
8644 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8645 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8646 && GET_CODE (XEXP (x, 1)) == CONST
8647 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8648 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8649 return XVECEXP (u, 0, 0);
8650 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
8651 && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
8652 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8653 || (GET_CODE (gp) == CONST
8654 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8655 && XINT (u, 1) == ARC_UNSPEC_GOT
8656 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8657 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8658 && GET_CODE (XEXP (x, 1)) == CONST
8659 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8660 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8661 return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
8662 XVECEXP (u, 0, 0));
8663 else if (GET_CODE (x) == PLUS
8664 && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
8665 return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
8666 return NULL_RTX;
8667}
8668
8669static rtx
8670arc_delegitimize_address (rtx x)
8671{
8672 rtx orig_x = x = delegitimize_mem_from_attrs (x);
8673 if (GET_CODE (x) == MEM)
8674 x = XEXP (x, 0);
8675 x = arc_delegitimize_address_0 (x);
8676 if (x)
8677 {
8678 if (MEM_P (orig_x))
8679 x = replace_equiv_address_nv (orig_x, x);
8680 return x;
8681 }
8682 return orig_x;
8683}
8684
8685/* Return a REG rtx for acc1. N.B. the gcc-internal representation may
8686 differ from the hardware register number in order to allow the generic
8687 code to correctly split the concatenation of acc1 and acc2. */
8688
8689rtx
8690gen_acc1 (void)
8691{
8692 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
8693}
8694
8695/* Return a REG rtx for acc2. N.B. the gcc-internal representation may
8696 differ from the hardware register number in order to allow the generic
8697 code to correctly split the concatenation of acc1 and acc2. */
8698
8699rtx
8700gen_acc2 (void)
8701{
8702 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
8703}
8704
8705/* Return a REG rtx for mlo. N.B. the gcc-internal representation may
8706 differ from the hardware register number in order to allow the generic
8707 code to correctly split the concatenation of mhi and mlo. */
8708
8709rtx
8710gen_mlo (void)
8711{
8712 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
8713}
8714
8715/* Return a REG rtx for mhi. N.B. the gcc-internal representation may
8716 differ from the hardware register number in order to allow the generic
8717 code to correctly split the concatenation of mhi and mlo. */
8718
8719rtx
8720gen_mhi (void)
8721{
8722 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
8723}
8724
8725/* FIXME: a parameter should be added, and code added to final.c,
8726 to reproduce this functionality in shorten_branches. */
8727#if 0
8728/* Return nonzero iff BRANCH should be unaligned if possible by upsizing
8729 a previous instruction. */
8730int
8731arc_unalign_branch_p (rtx branch)
8732{
8733 rtx note;
8734
8735 if (!TARGET_UNALIGN_BRANCH)
8736 return 0;
8737 /* Do not do this if we have a filled delay slot. */
8738 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
4654c0cf 8739 && !NEXT_INSN (branch)->deleted ())
526b7aee
SV
8740 return 0;
8741 note = find_reg_note (branch, REG_BR_PROB, 0);
8742 return (!note
8743 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
8744 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
8745}
8746#endif
8747
8748/* When estimating sizes during arc_reorg, when optimizing for speed, there
8749 are three reasons why we need to consider branches to be length 6:
8750 - annull-false delay slot insns are implemented using conditional execution,
8751 thus preventing short insn formation where used.
8752 - for ARC600: annul-true delay slot insns are implemented where possible
8753 using conditional execution, preventing short insn formation where used.
8754 - for ARC700: likely or somewhat likely taken branches are made long and
8755 unaligned if possible to avoid branch penalty. */
8756
8757bool
8758arc_branch_size_unknown_p (void)
8759{
8760 return !optimize_size && arc_reorg_in_progress;
8761}
8762
8763/* We are about to output a return insn. Add padding if necessary to avoid
8764 a mispredict. A return could happen immediately after the function
8765 start, but after a call we know that there will be at least a blink
8766 restore. */
8767
8768void
8769arc_pad_return (void)
8770{
fa7af581 8771 rtx_insn *insn = current_output_insn;
b3458f61 8772 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8773 int want_long;
8774
8775 if (!prev)
8776 {
8777 fputs ("\tnop_s\n", asm_out_file);
8778 cfun->machine->unalign ^= 2;
8779 want_long = 1;
8780 }
8781 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
8782 because after a call, we'd have to restore blink first. */
8783 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
8784 return;
8785 else
8786 {
8787 want_long = (get_attr_length (prev) == 2);
8788 prev = prev_active_insn (prev);
8789 }
8790 if (!prev
8791 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8792 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8793 NON_SIBCALL)
526b7aee
SV
8794 : CALL_ATTR (prev, NON_SIBCALL)))
8795 {
8796 if (want_long)
8797 cfun->machine->size_reason
8798 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
8799 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
8800 {
8801 cfun->machine->size_reason
8802 = "Long unaligned jump avoids non-delay slot penalty";
8803 want_long = 1;
8804 }
8805 /* Disgorge delay insn, if there is any, and it may be moved. */
8806 if (final_sequence
8807 /* ??? Annulled would be OK if we can and do conditionalize
8808 the delay slot insn accordingly. */
8809 && !INSN_ANNULLED_BRANCH_P (insn)
8810 && (get_attr_cond (insn) != COND_USE
8811 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
8812 XVECEXP (final_sequence, 0, 1))))
8813 {
b3458f61 8814 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
526b7aee
SV
8815 gcc_assert (!prev_real_insn (insn)
8816 || !arc_hazard (prev_real_insn (insn), prev));
8817 cfun->machine->force_short_suffix = !want_long;
8818 rtx save_pred = current_insn_predicate;
8819 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
8820 cfun->machine->force_short_suffix = -1;
4654c0cf 8821 prev->set_deleted ();
526b7aee
SV
8822 current_output_insn = insn;
8823 current_insn_predicate = save_pred;
8824 }
8825 else if (want_long)
8826 fputs ("\tnop\n", asm_out_file);
8827 else
8828 {
8829 fputs ("\tnop_s\n", asm_out_file);
8830 cfun->machine->unalign ^= 2;
8831 }
8832 }
8833 return;
8834}
8835
8836/* The usual; we set up our machine_function data. */
8837
8838static struct machine_function *
8839arc_init_machine_status (void)
8840{
8841 struct machine_function *machine;
766090c2 8842 machine = ggc_cleared_alloc<machine_function> ();
526b7aee
SV
8843 machine->fn_type = ARC_FUNCTION_UNKNOWN;
8844 machine->force_short_suffix = -1;
8845
8846 return machine;
8847}
8848
8849/* Implements INIT_EXPANDERS. We just set up to call the above
8850 function. */
8851
8852void
8853arc_init_expanders (void)
8854{
8855 init_machine_status = arc_init_machine_status;
8856}
8857
8858/* Check if OP is a proper parallel of a millicode call pattern. OFFSET
8859 indicates a number of elements to ignore - that allows to have a
8860 sibcall pattern that starts with (return). LOAD_P is zero for store
8861 multiple (for prologues), and one for load multiples (for epilogues),
8862 and two for load multiples where no final clobber of blink is required.
8863 We also skip the first load / store element since this is supposed to
8864 be checked in the instruction pattern. */
8865
8866int
8867arc_check_millicode (rtx op, int offset, int load_p)
8868{
8869 int len = XVECLEN (op, 0) - offset;
8870 int i;
8871
8872 if (load_p == 2)
8873 {
8874 if (len < 2 || len > 13)
8875 return 0;
8876 load_p = 1;
8877 }
8878 else
8879 {
8880 rtx elt = XVECEXP (op, 0, --len);
8881
8882 if (GET_CODE (elt) != CLOBBER
8883 || !REG_P (XEXP (elt, 0))
8884 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
8885 || len < 3 || len > 13)
8886 return 0;
8887 }
8888 for (i = 1; i < len; i++)
8889 {
8890 rtx elt = XVECEXP (op, 0, i + offset);
8891 rtx reg, mem, addr;
8892
8893 if (GET_CODE (elt) != SET)
8894 return 0;
8895 mem = XEXP (elt, load_p);
8896 reg = XEXP (elt, 1-load_p);
8897 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
8898 return 0;
8899 addr = XEXP (mem, 0);
8900 if (GET_CODE (addr) != PLUS
8901 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
8902 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
8903 return 0;
8904 }
8905 return 1;
8906}
8907
8908/* Accessor functions for cfun->machine->unalign. */
8909
8910int
8911arc_get_unalign (void)
8912{
8913 return cfun->machine->unalign;
8914}
8915
8916void
8917arc_clear_unalign (void)
8918{
8919 if (cfun)
8920 cfun->machine->unalign = 0;
8921}
8922
8923void
8924arc_toggle_unalign (void)
8925{
8926 cfun->machine->unalign ^= 2;
8927}
8928
8929/* Operands 0..2 are the operands of a addsi which uses a 12 bit
8930 constant in operand 2, but which would require a LIMM because of
8931 operand mismatch.
8932 operands 3 and 4 are new SET_SRCs for operands 0. */
8933
8934void
8935split_addsi (rtx *operands)
8936{
8937 int val = INTVAL (operands[2]);
8938
8939 /* Try for two short insns first. Lengths being equal, we prefer
8940 expansions with shorter register lifetimes. */
8941 if (val > 127 && val <= 255
8942 && satisfies_constraint_Rcq (operands[0]))
8943 {
8944 operands[3] = operands[2];
8945 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8946 }
8947 else
8948 {
8949 operands[3] = operands[1];
8950 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
8951 }
8952}
8953
8954/* Operands 0..2 are the operands of a subsi which uses a 12 bit
8955 constant in operand 1, but which would require a LIMM because of
8956 operand mismatch.
8957 operands 3 and 4 are new SET_SRCs for operands 0. */
8958
8959void
8960split_subsi (rtx *operands)
8961{
8962 int val = INTVAL (operands[1]);
8963
8964 /* Try for two short insns first. Lengths being equal, we prefer
8965 expansions with shorter register lifetimes. */
8966 if (satisfies_constraint_Rcq (operands[0])
8967 && satisfies_constraint_Rcq (operands[2]))
8968 {
8969 if (val >= -31 && val <= 127)
8970 {
8971 operands[3] = gen_rtx_NEG (SImode, operands[2]);
8972 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8973 return;
8974 }
8975 else if (val >= 0 && val < 255)
8976 {
8977 operands[3] = operands[1];
8978 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
8979 return;
8980 }
8981 }
8982 /* If the destination is not an ARCompact16 register, we might
8983 still have a chance to make a short insn if the source is;
8984 we need to start with a reg-reg move for this. */
8985 operands[3] = operands[2];
8986 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
8987}
8988
8989/* Handle DOUBLE_REGS uses.
8990 Operand 0: destination register
8991 Operand 1: source register */
8992
d34a0fdc 8993static bool
526b7aee
SV
8994arc_process_double_reg_moves (rtx *operands)
8995{
8996 rtx dest = operands[0];
8997 rtx src = operands[1];
526b7aee
SV
8998
8999 enum usesDxState { none, srcDx, destDx, maxDx };
9000 enum usesDxState state = none;
9001
9002 if (refers_to_regno_p (40, 44, src, 0))
9003 state = srcDx;
9004 if (refers_to_regno_p (40, 44, dest, 0))
9005 {
9006 /* Via arc_register_move_cost, we should never see D,D moves. */
9007 gcc_assert (state == none);
9008 state = destDx;
9009 }
9010
9011 if (state == none)
d34a0fdc 9012 return false;
526b7aee
SV
9013
9014 if (state == srcDx)
9015 {
9016 /* Without the LR insn, we need to split this into a
9017 sequence of insns which will use the DEXCLx and DADDHxy
9018 insns to be able to read the Dx register in question. */
9019 if (TARGET_DPFP_DISABLE_LRSR)
9020 {
9021 /* gen *movdf_insn_nolrsr */
f7df4a84 9022 rtx set = gen_rtx_SET (dest, src);
526b7aee
SV
9023 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9024 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9025 }
9026 else
9027 {
9028 /* When we have 'mov D, r' or 'mov D, D' then get the target
9029 register pair for use with LR insn. */
7d81a567
CZ
9030 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9031 TARGET_BIG_ENDIAN ? 0 : 4);
9032 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9033 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee
SV
9034
9035 /* Produce the two LR insns to get the high and low parts. */
f7df4a84 9036 emit_insn (gen_rtx_SET (destHigh,
c69899f0
CZ
9037 gen_rtx_UNSPEC_VOLATILE (Pmode,
9038 gen_rtvec (1, src),
9039 VUNSPEC_ARC_LR_HIGH)));
f7df4a84 9040 emit_insn (gen_rtx_SET (destLow,
c69899f0
CZ
9041 gen_rtx_UNSPEC_VOLATILE (Pmode,
9042 gen_rtvec (1, src),
9043 VUNSPEC_ARC_LR)));
526b7aee
SV
9044 }
9045 }
9046 else if (state == destDx)
9047 {
9048 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9049 LR insn get the target register pair. */
7d81a567
CZ
9050 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9051 TARGET_BIG_ENDIAN ? 0 : 4);
9052 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9053 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee 9054
491483b0 9055 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
526b7aee
SV
9056 }
9057 else
9058 gcc_unreachable ();
9059
d34a0fdc 9060 return true;
526b7aee
SV
9061}
9062
9063/* operands 0..1 are the operands of a 64 bit move instruction.
9064 split it into two moves with operands 2/3 and 4/5. */
9065
d34a0fdc 9066void
526b7aee
SV
9067arc_split_move (rtx *operands)
9068{
ef4bddc2 9069 machine_mode mode = GET_MODE (operands[0]);
526b7aee
SV
9070 int i;
9071 int swap = 0;
9072 rtx xop[4];
526b7aee
SV
9073
9074 if (TARGET_DPFP)
9075 {
d34a0fdc
CZ
9076 if (arc_process_double_reg_moves (operands))
9077 return;
526b7aee
SV
9078 }
9079
d34a0fdc
CZ
9080 if (TARGET_LL64
9081 && ((memory_operand (operands[0], mode)
9082 && even_register_operand (operands[1], mode))
9083 || (memory_operand (operands[1], mode)
9084 && even_register_operand (operands[0], mode))))
9085 {
9086 emit_move_insn (operands[0], operands[1]);
9087 return;
9088 }
9089
00c072ae
CZ
9090 if (TARGET_PLUS_QMACW
9091 && GET_CODE (operands[1]) == CONST_VECTOR)
9092 {
9093 HOST_WIDE_INT intval0, intval1;
9094 if (GET_MODE (operands[1]) == V2SImode)
9095 {
9096 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9097 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9098 }
9099 else
9100 {
9101 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9102 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9103 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9104 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9105 }
9106 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9107 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9108 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9109 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9110 emit_move_insn (xop[0], xop[2]);
9111 emit_move_insn (xop[3], xop[1]);
9112 return;
9113 }
9114
526b7aee
SV
9115 for (i = 0; i < 2; i++)
9116 {
9117 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9118 {
9119 rtx addr = XEXP (operands[i], 0);
9120 rtx r, o;
9121 enum rtx_code code;
9122
9123 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9124 switch (GET_CODE (addr))
9125 {
9126 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9127 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9128 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9129 pre_modify:
9130 code = PRE_MODIFY;
9131 break;
9132 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9133 case POST_INC: o = GEN_INT (8); goto post_modify;
9134 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9135 post_modify:
9136 code = POST_MODIFY;
9137 swap = 2;
9138 break;
9139 default:
9140 gcc_unreachable ();
9141 }
9142 r = XEXP (addr, 0);
9143 xop[0+i] = adjust_automodify_address_nv
9144 (operands[i], SImode,
9145 gen_rtx_fmt_ee (code, Pmode, r,
9146 gen_rtx_PLUS (Pmode, r, o)),
9147 0);
9148 xop[2+i] = adjust_automodify_address_nv
9149 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9150 }
9151 else
9152 {
9153 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9154 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9155 }
9156 }
9157 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9158 {
9159 swap = 2;
9160 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9161 }
526b7aee 9162
d34a0fdc
CZ
9163 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9164 emit_move_insn (xop[2 - swap], xop[3 - swap]);
526b7aee 9165
526b7aee
SV
9166}
9167
9168/* Select between the instruction output templates s_tmpl (for short INSNs)
9169 and l_tmpl (for long INSNs). */
9170
9171const char *
b3458f61 9172arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
526b7aee
SV
9173{
9174 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9175
9176 extract_constrain_insn_cached (insn);
9177 return is_short ? s_tmpl : l_tmpl;
9178}
9179
9180/* Searches X for any reference to REGNO, returning the rtx of the
9181 reference found if any. Otherwise, returns NULL_RTX. */
9182
9183rtx
9184arc_regno_use_in (unsigned int regno, rtx x)
9185{
9186 const char *fmt;
9187 int i, j;
9188 rtx tem;
9189
c9bd6bcd 9190 if (REG_P (x) && refers_to_regno_p (regno, x))
526b7aee
SV
9191 return x;
9192
9193 fmt = GET_RTX_FORMAT (GET_CODE (x));
9194 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9195 {
9196 if (fmt[i] == 'e')
9197 {
9198 if ((tem = regno_use_in (regno, XEXP (x, i))))
9199 return tem;
9200 }
9201 else if (fmt[i] == 'E')
9202 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9203 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9204 return tem;
9205 }
9206
9207 return NULL_RTX;
9208}
9209
9210/* Return the integer value of the "type" attribute for INSN, or -1 if
9211 INSN can't have attributes. */
9212
9213int
84034c69 9214arc_attr_type (rtx_insn *insn)
526b7aee
SV
9215{
9216 if (NONJUMP_INSN_P (insn)
9217 ? (GET_CODE (PATTERN (insn)) == USE
9218 || GET_CODE (PATTERN (insn)) == CLOBBER)
9219 : JUMP_P (insn)
9220 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9221 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9222 : !CALL_P (insn))
9223 return -1;
9224 return get_attr_type (insn);
9225}
9226
9227/* Return true if insn sets the condition codes. */
9228
9229bool
84034c69 9230arc_sets_cc_p (rtx_insn *insn)
526b7aee 9231{
84034c69
DM
9232 if (NONJUMP_INSN_P (insn))
9233 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9234 insn = seq->insn (seq->len () - 1);
526b7aee
SV
9235 return arc_attr_type (insn) == TYPE_COMPARE;
9236}
9237
9238/* Return true if INSN is an instruction with a delay slot we may want
9239 to fill. */
9240
9241bool
b3458f61 9242arc_need_delay (rtx_insn *insn)
526b7aee 9243{
b3458f61 9244 rtx_insn *next;
526b7aee
SV
9245
9246 if (!flag_delayed_branch)
9247 return false;
9248 /* The return at the end of a function needs a delay slot. */
9249 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9250 && (!(next = next_active_insn (insn))
9251 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9252 && arc_attr_type (next) == TYPE_RETURN))
9253 && (!TARGET_PAD_RETURN
9254 || (prev_active_insn (insn)
9255 && prev_active_insn (prev_active_insn (insn))
9256 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9257 return true;
9258 if (NONJUMP_INSN_P (insn)
9259 ? (GET_CODE (PATTERN (insn)) == USE
9260 || GET_CODE (PATTERN (insn)) == CLOBBER
9261 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9262 : JUMP_P (insn)
9263 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9264 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9265 : !CALL_P (insn))
9266 return false;
9267 return num_delay_slots (insn) != 0;
9268}
9269
9270/* Return true if the scheduling pass(es) has/have already run,
9271 i.e. where possible, we should try to mitigate high latencies
9272 by different instruction selection. */
9273
9274bool
9275arc_scheduling_not_expected (void)
9276{
9277 return cfun->machine->arc_reorg_started;
9278}
9279
9280/* Oddly enough, sometimes we get a zero overhead loop that branch
9281 shortening doesn't think is a loop - observed with compile/pr24883.c
9282 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9283 alignment visible for branch shortening (we actually align the loop
9284 insn before it, but that is equivalent since the loop insn is 4 byte
9285 long.) */
9286
9287int
82082f65 9288arc_label_align (rtx_insn *label)
526b7aee
SV
9289{
9290 int loop_align = LOOP_ALIGN (LABEL);
9291
9292 if (loop_align > align_labels_log)
9293 {
b3458f61 9294 rtx_insn *prev = prev_nonnote_insn (label);
526b7aee
SV
9295
9296 if (prev && NONJUMP_INSN_P (prev)
9297 && GET_CODE (PATTERN (prev)) == PARALLEL
9298 && recog_memoized (prev) == CODE_FOR_doloop_begin_i)
9299 return loop_align;
9300 }
9301 /* Code has a minimum p2 alignment of 1, which we must restore after an
9302 ADDR_DIFF_VEC. */
9303 if (align_labels_log < 1)
9304 {
b3458f61 9305 rtx_insn *next = next_nonnote_nondebug_insn (label);
526b7aee
SV
9306 if (INSN_P (next) && recog_memoized (next) >= 0)
9307 return 1;
9308 }
9309 return align_labels_log;
9310}
9311
9312/* Return true if LABEL is in executable code. */
9313
9314bool
b32d5189 9315arc_text_label (rtx_insn *label)
526b7aee 9316{
b3458f61 9317 rtx_insn *next;
526b7aee
SV
9318
9319 /* ??? We use deleted labels like they were still there, see
9320 gcc.c-torture/compile/20000326-2.c . */
9321 gcc_assert (GET_CODE (label) == CODE_LABEL
9322 || (GET_CODE (label) == NOTE
9323 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9324 next = next_nonnote_insn (label);
9325 if (next)
9326 return (!JUMP_TABLE_DATA_P (next)
9327 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9328 else if (!PREV_INSN (label))
9329 /* ??? sometimes text labels get inserted very late, see
9330 gcc.dg/torture/stackalign/comp-goto-1.c */
9331 return true;
9332 return false;
9333}
9334
9335/* Return the size of the pretend args for DECL. */
9336
9337int
9338arc_decl_pretend_args (tree decl)
9339{
9340 /* struct function is in DECL_STRUCT_FUNCTION (decl), but no
9341 pretend_args there... See PR38391. */
9342 gcc_assert (decl == current_function_decl);
9343 return crtl->args.pretend_args_size;
9344}
9345
9346/* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9347 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
339ba33b 9348 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
526b7aee
SV
9349 to redirect two breqs. */
9350
9351static bool
c1ce59ab 9352arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
526b7aee
SV
9353{
9354 /* ??? get_attr_type is declared to take an rtx. */
c1ce59ab 9355 union { const rtx_insn *c; rtx_insn *r; } u;
526b7aee
SV
9356
9357 u.c = follower;
339ba33b 9358 if (CROSSING_JUMP_P (followee))
526b7aee
SV
9359 switch (get_attr_type (u.r))
9360 {
9361 case TYPE_BRCC:
9362 case TYPE_BRCC_NO_DELAY_SLOT:
9363 return false;
9364 default:
9365 return true;
9366 }
9367 return true;
9368}
9369
9370/* Implement EPILOGUE__USES.
9371 Return true if REGNO should be added to the deemed uses of the epilogue.
9372
9373 We use the return address
9374 arc_return_address_regs[arc_compute_function_type (cfun)] .
9375 But also, we have to make sure all the register restore instructions
9376 are known to be live in interrupt functions. */
9377
9378bool
9379arc_epilogue_uses (int regno)
9380{
28633bbd
CZ
9381 if (regno == arc_tp_regno)
9382 return true;
526b7aee
SV
9383 if (reload_completed)
9384 {
9385 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9386 {
9387 if (!fixed_regs[regno])
9388 return true;
9389 return regno == arc_return_address_regs[cfun->machine->fn_type];
9390 }
9391 else
9392 return regno == RETURN_ADDR_REGNUM;
9393 }
9394 else
9395 return regno == arc_return_address_regs[arc_compute_function_type (cfun)];
9396}
9397
28633bbd
CZ
9398/* Helper for EH_USES macro. */
9399
9400bool
9401arc_eh_uses (int regno)
9402{
9403 if (regno == arc_tp_regno)
9404 return true;
9405 return false;
9406}
9407
526b7aee
SV
9408#ifndef TARGET_NO_LRA
9409#define TARGET_NO_LRA !TARGET_LRA
9410#endif
9411
9412static bool
9413arc_lra_p (void)
9414{
9415 return !TARGET_NO_LRA;
9416}
9417
9418/* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9419 Rcq registers, because some insn are shorter with them. OTOH we already
9420 have separate alternatives for this purpose, and other insns don't
9421 mind, so maybe we should rather prefer the other registers?
9422 We need more data, and we can only get that if we allow people to
9423 try all options. */
9424static int
9425arc_register_priority (int r)
9426{
9427 switch (arc_lra_priority_tag)
9428 {
9429 case ARC_LRA_PRIORITY_NONE:
9430 return 0;
9431 case ARC_LRA_PRIORITY_NONCOMPACT:
9432 return ((((r & 7) ^ 4) - 4) & 15) != r;
9433 case ARC_LRA_PRIORITY_COMPACT:
9434 return ((((r & 7) ^ 4) - 4) & 15) == r;
9435 default:
9436 gcc_unreachable ();
9437 }
9438}
9439
9440static reg_class_t
ef4bddc2 9441arc_spill_class (reg_class_t /* orig_class */, machine_mode)
526b7aee
SV
9442{
9443 return GENERAL_REGS;
9444}
9445
9446bool
ef4bddc2 9447arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
526b7aee
SV
9448 int itype)
9449{
9450 rtx x = *p;
9451 enum reload_type type = (enum reload_type) itype;
9452
9453 if (GET_CODE (x) == PLUS
9454 && CONST_INT_P (XEXP (x, 1))
9455 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9456 || (REG_P (XEXP (x, 0))
9457 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9458 {
9459 int scale = GET_MODE_SIZE (mode);
9460 int shift;
9461 rtx index_rtx = XEXP (x, 1);
9462 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9463 rtx reg, sum, sum2;
9464
9465 if (scale > 4)
9466 scale = 4;
9467 if ((scale-1) & offset)
9468 scale = 1;
9469 shift = scale >> 1;
c419f71c
JL
9470 offset_base
9471 = ((offset + (256 << shift))
4e671509 9472 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
526b7aee
SV
9473 /* Sometimes the normal form does not suit DImode. We
9474 could avoid that by using smaller ranges, but that
9475 would give less optimized code when SImode is
9476 prevalent. */
9477 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9478 {
9479 int regno;
9480
9481 reg = XEXP (x, 0);
9482 regno = REGNO (reg);
9483 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9484
9485 if (reg_equiv_constant (regno))
9486 {
9487 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9488 offset_base);
9489 if (GET_CODE (sum2) == PLUS)
9490 sum2 = gen_rtx_CONST (Pmode, sum2);
9491 }
9492 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9493 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9494 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9495 type);
9496 return true;
9497 }
9498 }
9499 /* We must re-recognize what we created before. */
9500 else if (GET_CODE (x) == PLUS
9501 && GET_CODE (XEXP (x, 0)) == PLUS
9502 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9503 && REG_P (XEXP (XEXP (x, 0), 0))
9504 && CONST_INT_P (XEXP (x, 1)))
9505 {
9506 /* Because this address is so complex, we know it must have
9507 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9508 it is already unshared, and needs no further unsharing. */
9509 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9510 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
9511 return true;
9512 }
9513 return false;
9514}
9515
ad23f5d4
JG
9516/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9517
9518static bool
445d7826 9519arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
ad23f5d4
JG
9520 unsigned int align,
9521 enum by_pieces_operation op,
9522 bool speed_p)
9523{
9524 /* Let the movmem expander handle small block moves. */
9525 if (op == MOVE_BY_PIECES)
9526 return false;
9527
9528 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
9529}
9530
b8a64b7f
CZ
9531/* Emit a (pre) memory barrier around an atomic sequence according to
9532 MODEL. */
9533
9534static void
9535arc_pre_atomic_barrier (enum memmodel model)
9536{
9537 if (need_atomic_barrier_p (model, true))
9538 emit_insn (gen_memory_barrier ());
9539}
9540
9541/* Emit a (post) memory barrier around an atomic sequence according to
9542 MODEL. */
9543
9544static void
9545arc_post_atomic_barrier (enum memmodel model)
9546{
9547 if (need_atomic_barrier_p (model, false))
9548 emit_insn (gen_memory_barrier ());
9549}
9550
9551/* Expand a compare and swap pattern. */
9552
9553static void
9554emit_unlikely_jump (rtx insn)
9555{
9556 int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
9557
f370536c
TS
9558 rtx_insn *jump = emit_jump_insn (insn);
9559 add_int_reg_note (jump, REG_BR_PROB, very_unlikely);
b8a64b7f
CZ
9560}
9561
9562/* Expand code to perform a 8 or 16-bit compare and swap by doing
9563 32-bit compare and swap on the word containing the byte or
9564 half-word. The difference between a weak and a strong CAS is that
9565 the weak version may simply fail. The strong version relies on two
9566 loops, one checks if the SCOND op is succsfully or not, the other
9567 checks if the 32 bit accessed location which contains the 8 or 16
9568 bit datum is not changed by other thread. The first loop is
9569 implemented by the atomic_compare_and_swapsi_1 pattern. The second
9570 loops is implemented by this routine. */
9571
9572static void
9573arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
9574 rtx oldval, rtx newval, rtx weak,
9575 rtx mod_s, rtx mod_f)
9576{
9577 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
9578 rtx addr = gen_reg_rtx (Pmode);
9579 rtx off = gen_reg_rtx (SImode);
9580 rtx oldv = gen_reg_rtx (SImode);
9581 rtx newv = gen_reg_rtx (SImode);
9582 rtx oldvalue = gen_reg_rtx (SImode);
9583 rtx newvalue = gen_reg_rtx (SImode);
9584 rtx res = gen_reg_rtx (SImode);
9585 rtx resv = gen_reg_rtx (SImode);
9586 rtx memsi, val, mask, end_label, loop_label, cc, x;
9587 machine_mode mode;
9588 bool is_weak = (weak != const0_rtx);
9589
9590 /* Truncate the address. */
9591 emit_insn (gen_rtx_SET (addr,
9592 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
9593
9594 /* Compute the datum offset. */
9595 emit_insn (gen_rtx_SET (off,
9596 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
9597 if (TARGET_BIG_ENDIAN)
9598 emit_insn (gen_rtx_SET (off,
9599 gen_rtx_MINUS (SImode,
9600 (GET_MODE (mem) == QImode) ?
9601 GEN_INT (3) : GEN_INT (2), off)));
9602
9603 /* Normal read from truncated address. */
9604 memsi = gen_rtx_MEM (SImode, addr);
9605 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
9606 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
9607
9608 val = copy_to_reg (memsi);
9609
9610 /* Convert the offset in bits. */
9611 emit_insn (gen_rtx_SET (off,
9612 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
9613
9614 /* Get the proper mask. */
9615 if (GET_MODE (mem) == QImode)
9616 mask = force_reg (SImode, GEN_INT (0xff));
9617 else
9618 mask = force_reg (SImode, GEN_INT (0xffff));
9619
9620 emit_insn (gen_rtx_SET (mask,
9621 gen_rtx_ASHIFT (SImode, mask, off)));
9622
9623 /* Prepare the old and new values. */
9624 emit_insn (gen_rtx_SET (val,
9625 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
9626 val)));
9627
9628 oldval = gen_lowpart (SImode, oldval);
9629 emit_insn (gen_rtx_SET (oldv,
9630 gen_rtx_ASHIFT (SImode, oldval, off)));
9631
9632 newval = gen_lowpart_common (SImode, newval);
9633 emit_insn (gen_rtx_SET (newv,
9634 gen_rtx_ASHIFT (SImode, newval, off)));
9635
9636 emit_insn (gen_rtx_SET (oldv,
9637 gen_rtx_AND (SImode, oldv, mask)));
9638
9639 emit_insn (gen_rtx_SET (newv,
9640 gen_rtx_AND (SImode, newv, mask)));
9641
9642 if (!is_weak)
9643 {
9644 end_label = gen_label_rtx ();
9645 loop_label = gen_label_rtx ();
9646 emit_label (loop_label);
9647 }
9648
9649 /* Make the old and new values. */
9650 emit_insn (gen_rtx_SET (oldvalue,
9651 gen_rtx_IOR (SImode, oldv, val)));
9652
9653 emit_insn (gen_rtx_SET (newvalue,
9654 gen_rtx_IOR (SImode, newv, val)));
9655
9656 /* Try an 32bit atomic compare and swap. It clobbers the CC
9657 register. */
9658 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
9659 weak, mod_s, mod_f));
9660
9661 /* Regardless of the weakness of the operation, a proper boolean
9662 result needs to be provided. */
9663 x = gen_rtx_REG (CC_Zmode, CC_REG);
9664 x = gen_rtx_EQ (SImode, x, const0_rtx);
9665 emit_insn (gen_rtx_SET (bool_result, x));
9666
9667 if (!is_weak)
9668 {
9669 /* Check the results: if the atomic op is successfully the goto
9670 to end label. */
9671 x = gen_rtx_REG (CC_Zmode, CC_REG);
9672 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
9673 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9674 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
9675 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
9676
9677 /* Wait for the right moment when the accessed 32-bit location
9678 is stable. */
9679 emit_insn (gen_rtx_SET (resv,
9680 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
9681 res)));
9682 mode = SELECT_CC_MODE (NE, resv, val);
9683 cc = gen_rtx_REG (mode, CC_REG);
9684 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
9685
9686 /* Set the new value of the 32 bit location, proper masked. */
9687 emit_insn (gen_rtx_SET (val, resv));
9688
9689 /* Try again if location is unstable. Fall through if only
9690 scond op failed. */
9691 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
9692 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9693 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
9694 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9695
9696 emit_label (end_label);
9697 }
9698
9699 /* End: proper return the result for the given mode. */
9700 emit_insn (gen_rtx_SET (res,
9701 gen_rtx_AND (SImode, res, mask)));
9702
9703 emit_insn (gen_rtx_SET (res,
9704 gen_rtx_LSHIFTRT (SImode, res, off)));
9705
9706 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
9707}
9708
9709/* Helper function used by "atomic_compare_and_swap" expand
9710 pattern. */
9711
9712void
9713arc_expand_compare_and_swap (rtx operands[])
9714{
9715 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
9716 machine_mode mode;
9717
9718 bval = operands[0];
9719 rval = operands[1];
9720 mem = operands[2];
9721 oldval = operands[3];
9722 newval = operands[4];
9723 is_weak = operands[5];
9724 mod_s = operands[6];
9725 mod_f = operands[7];
9726 mode = GET_MODE (mem);
9727
9728 if (reg_overlap_mentioned_p (rval, oldval))
9729 oldval = copy_to_reg (oldval);
9730
9731 if (mode == SImode)
9732 {
9733 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
9734 is_weak, mod_s, mod_f));
9735 x = gen_rtx_REG (CC_Zmode, CC_REG);
9736 x = gen_rtx_EQ (SImode, x, const0_rtx);
9737 emit_insn (gen_rtx_SET (bval, x));
9738 }
9739 else
9740 {
9741 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
9742 is_weak, mod_s, mod_f);
9743 }
9744}
9745
9746/* Helper function used by the "atomic_compare_and_swapsi_1"
9747 pattern. */
9748
9749void
9750arc_split_compare_and_swap (rtx operands[])
9751{
9752 rtx rval, mem, oldval, newval;
9753 machine_mode mode;
9754 enum memmodel mod_s, mod_f;
9755 bool is_weak;
9756 rtx label1, label2, x, cond;
9757
9758 rval = operands[0];
9759 mem = operands[1];
9760 oldval = operands[2];
9761 newval = operands[3];
9762 is_weak = (operands[4] != const0_rtx);
9763 mod_s = (enum memmodel) INTVAL (operands[5]);
9764 mod_f = (enum memmodel) INTVAL (operands[6]);
9765 mode = GET_MODE (mem);
9766
9767 /* ARC atomic ops work only with 32-bit aligned memories. */
9768 gcc_assert (mode == SImode);
9769
9770 arc_pre_atomic_barrier (mod_s);
9771
9772 label1 = NULL_RTX;
9773 if (!is_weak)
9774 {
9775 label1 = gen_label_rtx ();
9776 emit_label (label1);
9777 }
9778 label2 = gen_label_rtx ();
9779
9780 /* Load exclusive. */
9781 emit_insn (gen_arc_load_exclusivesi (rval, mem));
9782
9783 /* Check if it is oldval. */
9784 mode = SELECT_CC_MODE (NE, rval, oldval);
9785 cond = gen_rtx_REG (mode, CC_REG);
9786 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
9787
9788 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9789 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9790 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
9791 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9792
9793 /* Exclusively store new item. Store clobbers CC reg. */
9794 emit_insn (gen_arc_store_exclusivesi (mem, newval));
9795
9796 if (!is_weak)
9797 {
9798 /* Check the result of the store. */
9799 cond = gen_rtx_REG (CC_Zmode, CC_REG);
9800 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9801 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9802 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
9803 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9804 }
9805
9806 if (mod_f != MEMMODEL_RELAXED)
9807 emit_label (label2);
9808
9809 arc_post_atomic_barrier (mod_s);
9810
9811 if (mod_f == MEMMODEL_RELAXED)
9812 emit_label (label2);
9813}
9814
9815/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
9816 to perform. MEM is the memory on which to operate. VAL is the second
9817 operand of the binary operator. BEFORE and AFTER are optional locations to
9818 return the value of MEM either before of after the operation. MODEL_RTX
9819 is a CONST_INT containing the memory model to use. */
9820
9821void
9822arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
9823 rtx orig_before, rtx orig_after, rtx model_rtx)
9824{
9825 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
9826 machine_mode mode = GET_MODE (mem);
9827 rtx label, x, cond;
9828 rtx before = orig_before, after = orig_after;
9829
9830 /* ARC atomic ops work only with 32-bit aligned memories. */
9831 gcc_assert (mode == SImode);
9832
9833 arc_pre_atomic_barrier (model);
9834
9835 label = gen_label_rtx ();
9836 emit_label (label);
9837 label = gen_rtx_LABEL_REF (VOIDmode, label);
9838
9839 if (before == NULL_RTX)
9840 before = gen_reg_rtx (mode);
9841
9842 if (after == NULL_RTX)
9843 after = gen_reg_rtx (mode);
9844
9845 /* Load exclusive. */
9846 emit_insn (gen_arc_load_exclusivesi (before, mem));
9847
9848 switch (code)
9849 {
9850 case NOT:
9851 x = gen_rtx_AND (mode, before, val);
9852 emit_insn (gen_rtx_SET (after, x));
9853 x = gen_rtx_NOT (mode, after);
9854 emit_insn (gen_rtx_SET (after, x));
9855 break;
9856
9857 case MINUS:
9858 if (CONST_INT_P (val))
9859 {
9860 val = GEN_INT (-INTVAL (val));
9861 code = PLUS;
9862 }
9863
9864 /* FALLTHRU. */
9865 default:
9866 x = gen_rtx_fmt_ee (code, mode, before, val);
9867 emit_insn (gen_rtx_SET (after, x));
9868 break;
9869 }
9870
9871 /* Exclusively store new item. Store clobbers CC reg. */
9872 emit_insn (gen_arc_store_exclusivesi (mem, after));
9873
9874 /* Check the result of the store. */
9875 cond = gen_rtx_REG (CC_Zmode, CC_REG);
9876 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9877 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9878 label, pc_rtx);
9879 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9880
9881 arc_post_atomic_barrier (model);
9882}
9883
bf9e9dc5
CZ
9884/* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
9885
9886static bool
9887arc_no_speculation_in_delay_slots_p ()
9888{
9889 return true;
9890}
9891
d34a0fdc
CZ
9892/* Return a parallel of registers to represent where to find the
9893 register pieces if required, otherwise NULL_RTX. */
9894
9895static rtx
9896arc_dwarf_register_span (rtx rtl)
9897{
cd1e4d41 9898 machine_mode mode = GET_MODE (rtl);
d34a0fdc
CZ
9899 unsigned regno;
9900 rtx p;
9901
9902 if (GET_MODE_SIZE (mode) != 8)
9903 return NULL_RTX;
9904
9905 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
9906 regno = REGNO (rtl);
9907 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
9908 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
9909
9910 return p;
9911}
9912
28633bbd
CZ
9913/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
9914 resource.h doesn't include the required header files. */
fc1c2d04 9915
28633bbd
CZ
9916bool
9917insn_is_tls_gd_dispatch (rtx_insn *insn)
9918{
9919 return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
9920}
d34a0fdc 9921
fc1c2d04
CZ
9922/* Return true if OP is an acceptable memory operand for ARCompact
9923 16-bit load instructions of MODE.
9924
9925 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
9926 non scaled instructions.
9927
9928 SCALED: TRUE if address can be scaled. */
9929
9930bool
9931compact_memory_operand_p (rtx op, machine_mode mode,
9932 bool av2short, bool scaled)
9933{
9934 rtx addr, plus0, plus1;
9935 int size, off;
9936
9937 /* Eliminate non-memory operations. */
9938 if (GET_CODE (op) != MEM)
9939 return 0;
9940
9941 /* .di instructions have no 16-bit form. */
9942 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
9943 return false;
9944
9945 if (mode == VOIDmode)
9946 mode = GET_MODE (op);
9947
9948 size = GET_MODE_SIZE (mode);
9949
9950 /* dword operations really put out 2 instructions, so eliminate
9951 them. */
9952 if (size > UNITS_PER_WORD)
9953 return false;
9954
9955 /* Decode the address now. */
9956 addr = XEXP (op, 0);
9957 switch (GET_CODE (addr))
9958 {
9959 case REG:
9960 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
9961 || COMPACT_GP_REG_P (REGNO (addr))
9962 || (SP_REG_P (REGNO (addr)) && (size != 2)));
9963 case PLUS:
9964 plus0 = XEXP (addr, 0);
9965 plus1 = XEXP (addr, 1);
9966
9967 if ((GET_CODE (plus0) == REG)
9968 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9969 || COMPACT_GP_REG_P (REGNO (plus0)))
9970 && ((GET_CODE (plus1) == REG)
9971 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
9972 || COMPACT_GP_REG_P (REGNO (plus1)))))
9973 {
9974 return !av2short;
9975 }
9976
9977 if ((GET_CODE (plus0) == REG)
9978 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9979 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
9980 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
9981 && (GET_CODE (plus1) == CONST_INT))
9982 {
9983 bool valid = false;
9984
9985 off = INTVAL (plus1);
9986
9987 /* Negative offset is not supported in 16-bit load/store insns. */
9988 if (off < 0)
9989 return 0;
9990
9991 /* Only u5 immediates allowed in code density instructions. */
9992 if (av2short)
9993 {
9994 switch (size)
9995 {
9996 case 1:
9997 return false;
9998 case 2:
9999 /* This is an ldh_s.x instruction, check the u6
10000 immediate. */
10001 if (COMPACT_GP_REG_P (REGNO (plus0)))
10002 valid = true;
10003 break;
10004 case 4:
10005 /* Only u5 immediates allowed in 32bit access code
10006 density instructions. */
10007 if (REGNO (plus0) <= 31)
10008 return ((off < 32) && (off % 4 == 0));
10009 break;
10010 default:
10011 return false;
10012 }
10013 }
10014 else
10015 if (COMPACT_GP_REG_P (REGNO (plus0)))
10016 valid = true;
10017
10018 if (valid)
10019 {
10020
10021 switch (size)
10022 {
10023 case 1:
10024 return (off < 32);
10025 case 2:
10026 /* The 6-bit constant get shifted to fit the real
10027 5-bits field. Check also for the alignment. */
10028 return ((off < 64) && (off % 2 == 0));
10029 case 4:
10030 return ((off < 128) && (off % 4 == 0));
10031 default:
10032 return false;
10033 }
10034 }
10035 }
10036
10037 if (REG_P (plus0) && CONST_INT_P (plus1)
10038 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10039 || SP_REG_P (REGNO (plus0)))
10040 && !av2short)
10041 {
10042 off = INTVAL (plus1);
10043 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10044 }
10045
10046 if ((GET_CODE (plus0) == MULT)
10047 && (GET_CODE (XEXP (plus0, 0)) == REG)
10048 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10049 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10050 && (GET_CODE (plus1) == REG)
10051 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10052 || COMPACT_GP_REG_P (REGNO (plus1))))
10053 return scaled;
10054 default:
10055 break ;
10056 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10057 for 16-bit load instructions. */
10058 }
10059 return false;
10060}
10061
526b7aee
SV
10062struct gcc_target targetm = TARGET_INITIALIZER;
10063
10064#include "gt-arc.h"