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