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