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