]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/arc.c
[multiple changes]
[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
267static enum machine_mode
268arc_preferred_simd_mode (enum machine_mode mode)
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 {
d34a0fdc
CZ
2350 enum machine_mode mode = SImode;
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:
5127 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
5128 break;
5129 }
28633bbd
CZ
5130 if (pcrel)
5131 fputs ("pcl,", file);
5132 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
5133 fputs (suffix, file);
5134 if (base)
5135 arc_output_pic_addr_const (file, base, code);
5136 break;
526b7aee
SV
5137
5138 default:
5139 output_operand_lossage ("invalid expression as operand");
5140 }
5141}
5142
5143#define SYMBOLIC_CONST(X) \
5144(GET_CODE (X) == SYMBOL_REF \
5145 || GET_CODE (X) == LABEL_REF \
5146 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5147
5148/* Emit insns to move operands[1] into operands[0]. */
5149
28633bbd
CZ
5150static void
5151prepare_pic_move (rtx *operands, machine_mode)
526b7aee 5152{
28633bbd
CZ
5153 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])
5154 && flag_pic)
526b7aee
SV
5155 operands[1] = force_reg (Pmode, operands[1]);
5156 else
28633bbd
CZ
5157 {
5158 rtx temp = (reload_in_progress ? operands[0]
5159 : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX);
5160 operands[1] = arc_legitimize_pic_address (operands[1], temp);
5161 }
526b7aee
SV
5162}
5163
5164
5165/* The function returning the number of words, at the beginning of an
5166 argument, must be put in registers. The returned value must be
5167 zero for arguments that are passed entirely in registers or that
5168 are entirely pushed on the stack.
5169
5170 On some machines, certain arguments must be passed partially in
5171 registers and partially in memory. On these machines, typically
5172 the first N words of arguments are passed in registers, and the
5173 rest on the stack. If a multi-word argument (a `double' or a
5174 structure) crosses that boundary, its first few words must be
5175 passed in registers and the rest must be pushed. This function
5176 tells the compiler when this occurs, and how many of the words
5177 should go in registers.
5178
5179 `FUNCTION_ARG' for these arguments should return the first register
5180 to be used by the caller for this argument; likewise
5181 `FUNCTION_INCOMING_ARG', for the called function.
5182
5183 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5184
5185/* If REGNO is the least arg reg available then what is the total number of arg
5186 regs available. */
5187#define GPR_REST_ARG_REGS(REGNO) \
5188 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5189
5190/* Since arc parm regs are contiguous. */
5191#define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5192
5193/* Implement TARGET_ARG_PARTIAL_BYTES. */
5194
5195static int
ef4bddc2 5196arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
526b7aee
SV
5197 tree type, bool named ATTRIBUTE_UNUSED)
5198{
5199 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5200 int bytes = (mode == BLKmode
5201 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5202 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5203 int arg_num = *cum;
5204 int ret;
5205
5206 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5207 ret = GPR_REST_ARG_REGS (arg_num);
5208
5209 /* ICEd at function.c:2361, and ret is copied to data->partial */
5210 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
5211
5212 return ret;
5213}
5214
526b7aee
SV
5215/* This function is used to control a function argument is passed in a
5216 register, and which register.
5217
5218 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5219 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5220 all of the previous arguments so far passed in registers; MODE, the
5221 machine mode of the argument; TYPE, the data type of the argument
5222 as a tree node or 0 if that is not known (which happens for C
5223 support library functions); and NAMED, which is 1 for an ordinary
5224 argument and 0 for nameless arguments that correspond to `...' in
5225 the called function's prototype.
5226
5227 The returned value should either be a `reg' RTX for the hard
5228 register in which to pass the argument, or zero to pass the
5229 argument on the stack.
5230
5231 For machines like the Vax and 68000, where normally all arguments
5232 are pushed, zero suffices as a definition.
5233
5234 The usual way to make the ANSI library `stdarg.h' work on a machine
5235 where some arguments are usually passed in registers, is to cause
5236 nameless arguments to be passed on the stack instead. This is done
5237 by making the function return 0 whenever NAMED is 0.
5238
5239 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5240 definition of this function to determine if this argument is of a
5241 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5242 is not defined and the function returns non-zero for such an
5243 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5244 defined, the argument will be computed in the stack and then loaded
5245 into a register.
5246
5247 The function is used to implement macro FUNCTION_ARG. */
5248/* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5249 and the rest are pushed. */
5250
5251static rtx
8f3304d0
CZ
5252arc_function_arg (cumulative_args_t cum_v,
5253 machine_mode mode,
5254 const_tree type ATTRIBUTE_UNUSED,
5255 bool named ATTRIBUTE_UNUSED)
526b7aee
SV
5256{
5257 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5258 int arg_num = *cum;
5259 rtx ret;
5260 const char *debstr ATTRIBUTE_UNUSED;
5261
5262 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5263 /* Return a marker for use in the call instruction. */
5264 if (mode == VOIDmode)
5265 {
5266 ret = const0_rtx;
5267 debstr = "<0>";
5268 }
5269 else if (GPR_REST_ARG_REGS (arg_num) > 0)
5270 {
5271 ret = gen_rtx_REG (mode, arg_num);
5272 debstr = reg_names [arg_num];
5273 }
5274 else
5275 {
5276 ret = NULL_RTX;
5277 debstr = "memory";
5278 }
5279 return ret;
5280}
5281
5282/* The function to update the summarizer variable *CUM to advance past
5283 an argument in the argument list. The values MODE, TYPE and NAMED
5284 describe that argument. Once this is done, the variable *CUM is
5285 suitable for analyzing the *following* argument with
5286 `FUNCTION_ARG', etc.
5287
5288 This function need not do anything if the argument in question was
5289 passed on the stack. The compiler knows how to track the amount of
5290 stack space used for arguments without any special help.
5291
5292 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5293/* For the ARC: the cum set here is passed on to function_arg where we
5294 look at its value and say which reg to use. Strategy: advance the
5295 regnumber here till we run out of arg regs, then set *cum to last
5296 reg. In function_arg, since *cum > last arg reg we would return 0
5297 and thus the arg will end up on the stack. For straddling args of
5298 course function_arg_partial_nregs will come into play. */
5299
5300static void
8f3304d0
CZ
5301arc_function_arg_advance (cumulative_args_t cum_v,
5302 machine_mode mode,
5303 const_tree type,
5304 bool named ATTRIBUTE_UNUSED)
526b7aee
SV
5305{
5306 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5307 int bytes = (mode == BLKmode
5308 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5309 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5310 int i;
5311
5312 if (words)
5313 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
5314 for (i = 0; i < words; i++)
5315 *cum = ARC_NEXT_ARG_REG (*cum);
5316
5317}
5318
5319/* Define how to find the value returned by a function.
5320 VALTYPE is the data type of the value (as a tree).
5321 If the precise function being called is known, FN_DECL_OR_TYPE is its
5322 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5323
5324static rtx
5325arc_function_value (const_tree valtype,
5326 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
5327 bool outgoing ATTRIBUTE_UNUSED)
5328{
ef4bddc2 5329 machine_mode mode = TYPE_MODE (valtype);
526b7aee
SV
5330 int unsignedp ATTRIBUTE_UNUSED;
5331
5332 unsignedp = TYPE_UNSIGNED (valtype);
5333 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
5334 PROMOTE_MODE (mode, unsignedp, valtype);
5335 return gen_rtx_REG (mode, 0);
5336}
5337
5338/* Returns the return address that is used by builtin_return_address. */
5339
5340rtx
5341arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
5342{
5343 if (count != 0)
5344 return const0_rtx;
5345
5346 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
5347}
5348
5349/* Nonzero if the constant value X is a legitimate general operand
5350 when generating PIC code. It is given that flag_pic is on and
5351 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
5352
5353bool
5354arc_legitimate_pic_operand_p (rtx x)
5355{
5356 return !arc_raw_symbolic_reference_mentioned_p (x, true);
5357}
5358
5359/* Determine if a given RTX is a valid constant. We already know this
5360 satisfies CONSTANT_P. */
5361
5362bool
28633bbd 5363arc_legitimate_constant_p (machine_mode mode, rtx x)
526b7aee 5364{
28633bbd
CZ
5365 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
5366 return false;
5367
5368 if (!flag_pic && mode != Pmode)
526b7aee
SV
5369 return true;
5370
5371 switch (GET_CODE (x))
5372 {
5373 case CONST:
5374 x = XEXP (x, 0);
5375
5376 if (GET_CODE (x) == PLUS)
5377 {
28633bbd
CZ
5378 if (flag_pic
5379 ? GET_CODE (XEXP (x, 1)) != CONST_INT
5380 : !arc_legitimate_constant_p (mode, XEXP (x, 1)))
526b7aee
SV
5381 return false;
5382 x = XEXP (x, 0);
5383 }
5384
5385 /* Only some unspecs are valid as "constants". */
5386 if (GET_CODE (x) == UNSPEC)
5387 switch (XINT (x, 1))
5388 {
5389 case ARC_UNSPEC_PLT:
5390 case ARC_UNSPEC_GOTOFF:
5391 case ARC_UNSPEC_GOT:
28633bbd
CZ
5392 case UNSPEC_TLS_GD:
5393 case UNSPEC_TLS_IE:
5394 case UNSPEC_TLS_OFF:
526b7aee
SV
5395 case UNSPEC_PROF:
5396 return true;
5397
5398 default:
5399 gcc_unreachable ();
5400 }
5401
5402 /* We must have drilled down to a symbol. */
5403 if (arc_raw_symbolic_reference_mentioned_p (x, false))
5404 return false;
5405
5406 /* Return true. */
5407 break;
5408
526b7aee 5409 case SYMBOL_REF:
28633bbd
CZ
5410 if (SYMBOL_REF_TLS_MODEL (x))
5411 return false;
5412 /* Fall through. */
5413 case LABEL_REF:
5414 if (flag_pic)
5415 return false;
5416 /* Fall through. */
526b7aee
SV
5417
5418 default:
5419 break;
5420 }
5421
5422 /* Otherwise we handle everything else in the move patterns. */
5423 return true;
5424}
5425
5426static bool
ef4bddc2 5427arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
526b7aee
SV
5428{
5429 if (RTX_OK_FOR_BASE_P (x, strict))
5430 return true;
5431 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, TARGET_INDEXED_LOADS, strict))
5432 return true;
5433 if (LEGITIMATE_SCALED_ADDRESS_P (mode, x, strict))
5434 return true;
5435 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
5436 return true;
5437 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
5438 return true;
28633bbd
CZ
5439
5440 /* When we compile for size avoid const (@sym + offset)
5441 addresses. */
5442 if (!flag_pic && optimize_size && !reload_completed
5443 && (GET_CODE (x) == CONST)
5444 && (GET_CODE (XEXP (x, 0)) == PLUS)
5445 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
5446 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
5447 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
526b7aee 5448 {
28633bbd
CZ
5449 rtx addend = XEXP (XEXP (x, 0), 1);
5450 gcc_assert (CONST_INT_P (addend));
5451 HOST_WIDE_INT offset = INTVAL (addend);
5452
5453 /* Allow addresses having a large offset to pass. Anyhow they
5454 will end in a limm. */
5455 return !(offset > -1024 && offset < 1020);
5456 }
5457
5458 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
5459 {
5460 if (flag_pic ? arc_legitimate_pic_addr_p (x)
5461 : arc_legitimate_constant_p (Pmode, x))
526b7aee
SV
5462 return true;
5463 }
5464 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
5465 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
5466 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
5467 return true;
5468 /* We're restricted here by the `st' insn. */
5469 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
5470 && GET_CODE (XEXP ((x), 1)) == PLUS
5471 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
5472 && LEGITIMATE_OFFSET_ADDRESS_P (QImode, XEXP (x, 1),
5473 TARGET_AUTO_MODIFY_REG, strict))
5474 return true;
5475 return false;
5476}
5477
5478/* Return true iff ADDR (a legitimate address expression)
5479 has an effect that depends on the machine mode it is used for. */
5480
5481static bool
5482arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
5483{
5484 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5485 which is valid for loads and stores, or a limm offset, which is valid for
5486 loads. */
5487 /* Scaled indices are scaled by the access mode; likewise for scaled
5488 offsets, which are needed for maximum offset stores. */
5489 if (GET_CODE (addr) == PLUS
5490 && (GET_CODE (XEXP ((addr), 0)) == MULT
5491 || (CONST_INT_P (XEXP ((addr), 1))
5492 && !SMALL_INT (INTVAL (XEXP ((addr), 1))))))
5493 return true;
5494 return false;
5495}
5496
5497/* Determine if it's legal to put X into the constant pool. */
5498
5499static bool
ef4bddc2 5500arc_cannot_force_const_mem (machine_mode mode, rtx x)
526b7aee
SV
5501{
5502 return !arc_legitimate_constant_p (mode, x);
5503}
5504
c69899f0
CZ
5505/* IDs for all the ARC builtins. */
5506
5507enum arc_builtin_id
5508 {
5509#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5510 ARC_BUILTIN_ ## NAME,
5511#include "builtins.def"
5512#undef DEF_BUILTIN
5513
5514 ARC_BUILTIN_COUNT
5515 };
5516
5517struct GTY(()) arc_builtin_description
5518{
5519 enum insn_code icode;
5520 int n_args;
5521 tree fndecl;
5522};
5523
5524static GTY(()) struct arc_builtin_description
5525arc_bdesc[ARC_BUILTIN_COUNT] =
5526{
5527#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5528 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
5529#include "builtins.def"
5530#undef DEF_BUILTIN
5531};
5532
5533/* Transform UP into lowercase and write the result to LO.
5534 You must provide enough space for LO. Return LO. */
5535
5536static char*
5537arc_tolower (char *lo, const char *up)
5538{
5539 char *lo0 = lo;
5540
5541 for (; *up; up++, lo++)
5542 *lo = TOLOWER (*up);
5543
5544 *lo = '\0';
5545
5546 return lo0;
5547}
5548
5549/* Implement `TARGET_BUILTIN_DECL'. */
526b7aee 5550
c69899f0
CZ
5551static tree
5552arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
5553{
5554 if (id < ARC_BUILTIN_COUNT)
5555 return arc_bdesc[id].fndecl;
526b7aee 5556
c69899f0
CZ
5557 return error_mark_node;
5558}
526b7aee
SV
5559
5560static void
5561arc_init_builtins (void)
5562{
00c072ae
CZ
5563 tree V4HI_type_node;
5564 tree V2SI_type_node;
5565 tree V2HI_type_node;
5566
5567 /* Vector types based on HS SIMD elements. */
5568 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
5569 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
5570 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
5571
c69899f0
CZ
5572 tree pcvoid_type_node
5573 = build_pointer_type (build_qualified_type (void_type_node,
5574 TYPE_QUAL_CONST));
5575 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
5576 V8HImode);
5577
5578 tree void_ftype_void
5579 = build_function_type_list (void_type_node, NULL_TREE);
5580 tree int_ftype_int
5581 = build_function_type_list (integer_type_node, integer_type_node,
5582 NULL_TREE);
5583 tree int_ftype_pcvoid_int
5584 = build_function_type_list (integer_type_node, pcvoid_type_node,
5585 integer_type_node, NULL_TREE);
5586 tree void_ftype_usint_usint
5587 = build_function_type_list (void_type_node, long_unsigned_type_node,
5588 long_unsigned_type_node, NULL_TREE);
5589 tree int_ftype_int_int
5590 = build_function_type_list (integer_type_node, integer_type_node,
5591 integer_type_node, NULL_TREE);
5592 tree usint_ftype_usint
5593 = build_function_type_list (long_unsigned_type_node,
5594 long_unsigned_type_node, NULL_TREE);
5595 tree void_ftype_usint
5596 = build_function_type_list (void_type_node, long_unsigned_type_node,
5597 NULL_TREE);
5598 tree int_ftype_void
5599 = build_function_type_list (integer_type_node, void_type_node,
5600 NULL_TREE);
5601 tree void_ftype_int
5602 = build_function_type_list (void_type_node, integer_type_node,
5603 NULL_TREE);
5604 tree int_ftype_short
5605 = build_function_type_list (integer_type_node, short_integer_type_node,
5606 NULL_TREE);
5607
5608 /* Old ARC SIMD types. */
5609 tree v8hi_ftype_v8hi_v8hi
5610 = build_function_type_list (V8HI_type_node, V8HI_type_node,
5611 V8HI_type_node, NULL_TREE);
5612 tree v8hi_ftype_v8hi_int
5613 = build_function_type_list (V8HI_type_node, V8HI_type_node,
5614 integer_type_node, NULL_TREE);
5615 tree v8hi_ftype_v8hi_int_int
5616 = build_function_type_list (V8HI_type_node, V8HI_type_node,
5617 integer_type_node, integer_type_node,
5618 NULL_TREE);
5619 tree void_ftype_v8hi_int_int
5620 = build_function_type_list (void_type_node, V8HI_type_node,
5621 integer_type_node, integer_type_node,
5622 NULL_TREE);
5623 tree void_ftype_v8hi_int_int_int
5624 = build_function_type_list (void_type_node, V8HI_type_node,
5625 integer_type_node, integer_type_node,
5626 integer_type_node, NULL_TREE);
5627 tree v8hi_ftype_int_int
5628 = build_function_type_list (V8HI_type_node, integer_type_node,
5629 integer_type_node, NULL_TREE);
5630 tree void_ftype_int_int
5631 = build_function_type_list (void_type_node, integer_type_node,
5632 integer_type_node, NULL_TREE);
5633 tree v8hi_ftype_v8hi
5634 = build_function_type_list (V8HI_type_node, V8HI_type_node,
5635 NULL_TREE);
00c072ae
CZ
5636 /* ARCv2 SIMD types. */
5637 tree long_ftype_v4hi_v4hi
5638 = build_function_type_list (long_long_integer_type_node,
5639 V4HI_type_node, V4HI_type_node, NULL_TREE);
5640 tree int_ftype_v2hi_v2hi
5641 = build_function_type_list (integer_type_node,
5642 V2HI_type_node, V2HI_type_node, NULL_TREE);
5643 tree v2si_ftype_v2hi_v2hi
5644 = build_function_type_list (V2SI_type_node,
5645 V2HI_type_node, V2HI_type_node, NULL_TREE);
5646 tree v2hi_ftype_v2hi_v2hi
5647 = build_function_type_list (V2HI_type_node,
5648 V2HI_type_node, V2HI_type_node, NULL_TREE);
5649 tree v2si_ftype_v2si_v2si
5650 = build_function_type_list (V2SI_type_node,
5651 V2SI_type_node, V2SI_type_node, NULL_TREE);
5652 tree v4hi_ftype_v4hi_v4hi
5653 = build_function_type_list (V4HI_type_node,
5654 V4HI_type_node, V4HI_type_node, NULL_TREE);
5655 tree long_ftype_v2si_v2hi
5656 = build_function_type_list (long_long_integer_type_node,
5657 V2SI_type_node, V2HI_type_node, NULL_TREE);
c69899f0
CZ
5658
5659 /* Add the builtins. */
5660#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5661 { \
5662 int id = ARC_BUILTIN_ ## NAME; \
5663 const char *Name = "__builtin_arc_" #NAME; \
5664 char *name = (char*) alloca (1 + strlen (Name)); \
5665 \
5666 gcc_assert (id < ARC_BUILTIN_COUNT); \
5667 if (MASK) \
5668 arc_bdesc[id].fndecl \
5669 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
5670 BUILT_IN_MD, NULL, NULL_TREE); \
5671 }
5672#include "builtins.def"
5673#undef DEF_BUILTIN
5674}
5675
5676/* Helper to expand __builtin_arc_aligned (void* val, int
5677 alignval). */
5678
5679static rtx
5680arc_expand_builtin_aligned (tree exp)
5681{
5682 tree arg0 = CALL_EXPR_ARG (exp, 0);
5683 tree arg1 = CALL_EXPR_ARG (exp, 1);
5684 fold (arg1);
5685 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5686 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5687
5688 if (!CONST_INT_P (op1))
5689 {
5690 /* If we can't fold the alignment to a constant integer
5691 whilst optimizing, this is probably a user error. */
5692 if (optimize)
5693 warning (0, "__builtin_arc_aligned with non-constant alignment");
5694 }
5695 else
5696 {
5697 HOST_WIDE_INT alignTest = INTVAL (op1);
5698 /* Check alignTest is positive, and a power of two. */
5699 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
5700 {
5701 error ("invalid alignment value for __builtin_arc_aligned");
5702 return NULL_RTX;
5703 }
5704
5705 if (CONST_INT_P (op0))
5706 {
5707 HOST_WIDE_INT pnt = INTVAL (op0);
5708
5709 if ((pnt & (alignTest - 1)) == 0)
5710 return const1_rtx;
5711 }
5712 else
5713 {
5714 unsigned align = get_pointer_alignment (arg0);
5715 unsigned numBits = alignTest * BITS_PER_UNIT;
5716
5717 if (align && align >= numBits)
5718 return const1_rtx;
5719 /* Another attempt to ascertain alignment. Check the type
5720 we are pointing to. */
5721 if (POINTER_TYPE_P (TREE_TYPE (arg0))
5722 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
5723 return const1_rtx;
5724 }
5725 }
5726
5727 /* Default to false. */
5728 return const0_rtx;
5729}
5730
5731/* Helper arc_expand_builtin, generates a pattern for the given icode
5732 and arguments. */
5733
5734static rtx_insn *
5735apply_GEN_FCN (enum insn_code icode, rtx *arg)
5736{
5737 switch (insn_data[icode].n_generator_args)
5738 {
5739 case 0:
5740 return GEN_FCN (icode) ();
5741 case 1:
5742 return GEN_FCN (icode) (arg[0]);
5743 case 2:
5744 return GEN_FCN (icode) (arg[0], arg[1]);
5745 case 3:
5746 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
5747 case 4:
5748 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
5749 case 5:
5750 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
5751 default:
5752 gcc_unreachable ();
5753 }
5754}
526b7aee
SV
5755
5756/* Expand an expression EXP that calls a built-in function,
5757 with result going to TARGET if that's convenient
5758 (and in mode MODE if that's convenient).
5759 SUBTARGET may be used as the target for computing one of EXP's operands.
5760 IGNORE is nonzero if the value is to be ignored. */
5761
5762static rtx
5763arc_expand_builtin (tree exp,
5764 rtx target,
c69899f0
CZ
5765 rtx subtarget ATTRIBUTE_UNUSED,
5766 machine_mode mode ATTRIBUTE_UNUSED,
5767 int ignore ATTRIBUTE_UNUSED)
5768{
5769 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
5770 unsigned int id = DECL_FUNCTION_CODE (fndecl);
5771 const struct arc_builtin_description *d = &arc_bdesc[id];
5772 int i, j, n_args = call_expr_nargs (exp);
5773 rtx pat = NULL_RTX;
5774 rtx xop[5];
5775 enum insn_code icode = d->icode;
5776 machine_mode tmode = insn_data[icode].operand[0].mode;
5777 int nonvoid;
5778 tree arg0;
5779 tree arg1;
5780 tree arg2;
5781 tree arg3;
5782 rtx op0;
5783 rtx op1;
5784 rtx op2;
5785 rtx op3;
5786 rtx op4;
ef4bddc2
RS
5787 machine_mode mode0;
5788 machine_mode mode1;
c69899f0
CZ
5789 machine_mode mode2;
5790 machine_mode mode3;
5791 machine_mode mode4;
526b7aee 5792
c69899f0
CZ
5793 if (id >= ARC_BUILTIN_COUNT)
5794 internal_error ("bad builtin fcode");
526b7aee 5795
c69899f0
CZ
5796 /* 1st part: Expand special builtins. */
5797 switch (id)
526b7aee
SV
5798 {
5799 case ARC_BUILTIN_NOP:
c69899f0 5800 emit_insn (gen_nopv ());
526b7aee
SV
5801 return NULL_RTX;
5802
c69899f0
CZ
5803 case ARC_BUILTIN_RTIE:
5804 case ARC_BUILTIN_SYNC:
5805 case ARC_BUILTIN_BRK:
5806 case ARC_BUILTIN_SWI:
5807 case ARC_BUILTIN_UNIMP_S:
5808 gcc_assert (icode != 0);
5809 emit_insn (GEN_FCN (icode) (const1_rtx));
5810 return NULL_RTX;
526b7aee 5811
c69899f0
CZ
5812 case ARC_BUILTIN_ALIGNED:
5813 return arc_expand_builtin_aligned (exp);
526b7aee 5814
c69899f0
CZ
5815 case ARC_BUILTIN_CLRI:
5816 target = gen_reg_rtx (SImode);
5817 emit_insn (gen_clri (target, const1_rtx));
526b7aee
SV
5818 return target;
5819
c69899f0
CZ
5820 case ARC_BUILTIN_TRAP_S:
5821 case ARC_BUILTIN_SLEEP:
526b7aee 5822 arg0 = CALL_EXPR_ARG (exp, 0);
c69899f0 5823 fold (arg0);
526b7aee 5824 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
526b7aee 5825
c69899f0
CZ
5826 if (!CONST_INT_P (op0) || !satisfies_constraint_L (op0))
5827 {
5828 error ("builtin operand should be an unsigned 6-bit value");
5829 return NULL_RTX;
5830 }
5831 gcc_assert (icode != 0);
5832 emit_insn (GEN_FCN (icode) (op0));
5833 return NULL_RTX;
526b7aee 5834
c69899f0
CZ
5835 case ARC_BUILTIN_VDORUN:
5836 case ARC_BUILTIN_VDIRUN:
526b7aee
SV
5837 arg0 = CALL_EXPR_ARG (exp, 0);
5838 arg1 = CALL_EXPR_ARG (exp, 1);
c69899f0
CZ
5839 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
5840 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
526b7aee 5841
c69899f0
CZ
5842 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
5843
5844 mode0 = insn_data[icode].operand[1].mode;
5845 mode1 = insn_data[icode].operand[2].mode;
526b7aee 5846
c69899f0 5847 if (!insn_data[icode].operand[1].predicate (op0, mode0))
526b7aee
SV
5848 op0 = copy_to_mode_reg (mode0, op0);
5849
c69899f0 5850 if (!insn_data[icode].operand[2].predicate (op1, mode1))
526b7aee
SV
5851 op1 = copy_to_mode_reg (mode1, op1);
5852
c69899f0
CZ
5853 pat = GEN_FCN (icode) (target, op0, op1);
5854 if (!pat)
5855 return NULL_RTX;
5856
5857 emit_insn (pat);
526b7aee
SV
5858 return NULL_RTX;
5859
c69899f0
CZ
5860 case ARC_BUILTIN_VDIWR:
5861 case ARC_BUILTIN_VDOWR:
526b7aee
SV
5862 arg0 = CALL_EXPR_ARG (exp, 0);
5863 arg1 = CALL_EXPR_ARG (exp, 1);
c69899f0
CZ
5864 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
5865 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
5866
5867 if (!CONST_INT_P (op0)
5868 || !(UNSIGNED_INT3 (INTVAL (op0))))
5869 error ("operand 1 should be an unsigned 3-bit immediate");
526b7aee 5870
526b7aee
SV
5871 mode1 = insn_data[icode].operand[1].mode;
5872
c69899f0
CZ
5873 if (icode == CODE_FOR_vdiwr_insn)
5874 target = gen_rtx_REG (SImode,
5875 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
5876 else if (icode == CODE_FOR_vdowr_insn)
5877 target = gen_rtx_REG (SImode,
5878 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
5879 else
5880 gcc_unreachable ();
526b7aee 5881
c69899f0 5882 if (!insn_data[icode].operand[2].predicate (op1, mode1))
526b7aee
SV
5883 op1 = copy_to_mode_reg (mode1, op1);
5884
c69899f0
CZ
5885 pat = GEN_FCN (icode) (target, op1);
5886 if (!pat)
5887 return NULL_RTX;
526b7aee 5888
c69899f0 5889 emit_insn (pat);
526b7aee
SV
5890 return NULL_RTX;
5891
c69899f0
CZ
5892 case ARC_BUILTIN_VASRW:
5893 case ARC_BUILTIN_VSR8:
5894 case ARC_BUILTIN_VSR8AW:
526b7aee 5895 arg0 = CALL_EXPR_ARG (exp, 0);
c69899f0
CZ
5896 arg1 = CALL_EXPR_ARG (exp, 1);
5897 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
5898 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
5899 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
5900
5901 target = gen_reg_rtx (V8HImode);
526b7aee 5902 mode0 = insn_data[icode].operand[1].mode;
c69899f0 5903 mode1 = insn_data[icode].operand[2].mode;
526b7aee 5904
c69899f0 5905 if (!insn_data[icode].operand[1].predicate (op0, mode0))
526b7aee
SV
5906 op0 = copy_to_mode_reg (mode0, op0);
5907
c69899f0
CZ
5908 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
5909 || !(UNSIGNED_INT3 (INTVAL (op1))))
5910 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
526b7aee 5911
c69899f0
CZ
5912 pat = GEN_FCN (icode) (target, op0, op1, op2);
5913 if (!pat)
5914 return NULL_RTX;
526b7aee 5915
c69899f0
CZ
5916 emit_insn (pat);
5917 return target;
526b7aee 5918
c69899f0
CZ
5919 case ARC_BUILTIN_VLD32WH:
5920 case ARC_BUILTIN_VLD32WL:
5921 case ARC_BUILTIN_VLD64:
5922 case ARC_BUILTIN_VLD32:
5923 rtx src_vreg;
5924 icode = d->icode;
5925 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
5926 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
5927 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
526b7aee 5928
c69899f0
CZ
5929 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
5930 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
5931 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
5932 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
526b7aee 5933
c69899f0
CZ
5934 /* target <- src vreg. */
5935 emit_insn (gen_move_insn (target, src_vreg));
526b7aee 5936
c69899f0
CZ
5937 /* target <- vec_concat: target, mem (Ib, u8). */
5938 mode0 = insn_data[icode].operand[3].mode;
5939 mode1 = insn_data[icode].operand[1].mode;
526b7aee 5940
c69899f0
CZ
5941 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
5942 || !(UNSIGNED_INT3 (INTVAL (op0))))
5943 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
526b7aee 5944
c69899f0
CZ
5945 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
5946 || !(UNSIGNED_INT8 (INTVAL (op1))))
5947 error ("operand 2 should be an unsigned 8-bit value");
526b7aee 5948
c69899f0
CZ
5949 pat = GEN_FCN (icode) (target, op1, op2, op0);
5950 if (!pat)
5951 return NULL_RTX;
526b7aee 5952
c69899f0
CZ
5953 emit_insn (pat);
5954 return target;
526b7aee 5955
c69899f0
CZ
5956 case ARC_BUILTIN_VLD64W:
5957 case ARC_BUILTIN_VLD128:
5958 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
5959 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
526b7aee 5960
c69899f0
CZ
5961 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
5962 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
5963 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
526b7aee 5964
c69899f0
CZ
5965 /* target <- src vreg. */
5966 target = gen_reg_rtx (V8HImode);
526b7aee 5967
c69899f0
CZ
5968 /* target <- vec_concat: target, mem (Ib, u8). */
5969 mode0 = insn_data[icode].operand[1].mode;
5970 mode1 = insn_data[icode].operand[2].mode;
5971 mode2 = insn_data[icode].operand[3].mode;
526b7aee 5972
c69899f0
CZ
5973 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
5974 || !(UNSIGNED_INT3 (INTVAL (op1))))
5975 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
526b7aee 5976
c69899f0
CZ
5977 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
5978 || !(UNSIGNED_INT8 (INTVAL (op2))))
5979 error ("operand 2 should be an unsigned 8-bit value");
526b7aee 5980
c69899f0 5981 pat = GEN_FCN (icode) (target, op0, op1, op2);
526b7aee 5982
c69899f0
CZ
5983 if (!pat)
5984 return NULL_RTX;
526b7aee 5985
c69899f0 5986 emit_insn (pat);
526b7aee
SV
5987 return target;
5988
c69899f0
CZ
5989 case ARC_BUILTIN_VST128:
5990 case ARC_BUILTIN_VST64:
5991 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
5992 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
5993 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
526b7aee 5994
c69899f0
CZ
5995 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
5996 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
5997 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
5998 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
526b7aee
SV
5999
6000 mode0 = insn_data[icode].operand[0].mode;
6001 mode1 = insn_data[icode].operand[1].mode;
c69899f0
CZ
6002 mode2 = insn_data[icode].operand[2].mode;
6003 mode3 = insn_data[icode].operand[3].mode;
526b7aee 6004
c69899f0
CZ
6005 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6006 || !(UNSIGNED_INT3 (INTVAL (op1))))
6007 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
526b7aee 6008
c69899f0
CZ
6009 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6010 || !(UNSIGNED_INT8 (INTVAL (op2))))
6011 error ("operand 3 should be an unsigned 8-bit value");
526b7aee 6012
c69899f0
CZ
6013 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6014 op3 = copy_to_mode_reg (mode3, op3);
526b7aee 6015
c69899f0
CZ
6016 pat = GEN_FCN (icode) (op0, op1, op2, op3);
6017 if (!pat)
6018 return NULL_RTX;
526b7aee 6019
c69899f0
CZ
6020 emit_insn (pat);
6021 return NULL_RTX;
526b7aee 6022
c69899f0
CZ
6023 case ARC_BUILTIN_VST16_N:
6024 case ARC_BUILTIN_VST32_N:
6025 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6026 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
6027 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
6028 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
526b7aee 6029
c69899f0
CZ
6030 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
6031 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6032 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6033 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6034 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
526b7aee
SV
6035
6036 mode0 = insn_data[icode].operand[0].mode;
c69899f0
CZ
6037 mode2 = insn_data[icode].operand[2].mode;
6038 mode3 = insn_data[icode].operand[3].mode;
6039 mode4 = insn_data[icode].operand[4].mode;
526b7aee 6040
c69899f0
CZ
6041 /* Do some correctness checks for the operands. */
6042 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
6043 || !(UNSIGNED_INT8 (INTVAL (op0))))
6044 error ("operand 4 should be an unsigned 8-bit value (0-255)");
526b7aee 6045
c69899f0
CZ
6046 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6047 || !(UNSIGNED_INT3 (INTVAL (op2))))
6048 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
526b7aee 6049
c69899f0
CZ
6050 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6051 op3 = copy_to_mode_reg (mode3, op3);
526b7aee 6052
c69899f0
CZ
6053 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
6054 || !(UNSIGNED_INT3 (INTVAL (op4))))
6055 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6056 else if (icode == CODE_FOR_vst32_n_insn
6057 && ((INTVAL (op4) % 2) != 0))
6058 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
526b7aee 6059
c69899f0
CZ
6060 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
6061 if (!pat)
6062 return NULL_RTX;
526b7aee 6063
c69899f0 6064 emit_insn (pat);
526b7aee
SV
6065 return NULL_RTX;
6066
c69899f0
CZ
6067 default:
6068 break;
6069 }
6070
6071 /* 2nd part: Expand regular builtins. */
6072 if (icode == 0)
6073 internal_error ("bad builtin fcode");
6074
6075 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6076 j = 0;
526b7aee 6077
c69899f0
CZ
6078 if (nonvoid)
6079 {
6080 if (target == NULL_RTX
6081 || GET_MODE (target) != tmode
6082 || !insn_data[icode].operand[0].predicate (target, tmode))
526b7aee 6083 {
c69899f0 6084 target = gen_reg_rtx (tmode);
526b7aee 6085 }
c69899f0
CZ
6086 xop[j++] = target;
6087 }
6088
6089 gcc_assert (n_args <= 4);
6090 for (i = 0; i < n_args; i++, j++)
6091 {
6092 tree arg = CALL_EXPR_ARG (exp, i);
6093 machine_mode mode = insn_data[icode].operand[j].mode;
6094 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
6095 machine_mode opmode = GET_MODE (op);
6096 char c = insn_data[icode].operand[j].constraint[0];
6097
6098 /* SIMD extension requires exact immediate operand match. */
6099 if ((id > ARC_BUILTIN_SIMD_BEGIN)
6100 && (id < ARC_BUILTIN_SIMD_END)
6101 && (c != 'v')
6102 && (c != 'r'))
526b7aee 6103 {
c69899f0
CZ
6104 if (!CONST_INT_P (op))
6105 error ("builtin requires an immediate for operand %d", j);
6106 switch (c)
526b7aee 6107 {
c69899f0
CZ
6108 case 'L':
6109 if (!satisfies_constraint_L (op))
6110 error ("operand %d should be a 6 bit unsigned immediate", j);
6111 break;
6112 case 'P':
6113 if (!satisfies_constraint_P (op))
6114 error ("operand %d should be a 8 bit unsigned immediate", j);
6115 break;
6116 case 'K':
6117 if (!satisfies_constraint_K (op))
6118 error ("operand %d should be a 3 bit unsigned immediate", j);
6119 break;
6120 default:
6121 error ("unknown builtin immediate operand type for operand %d",
6122 j);
526b7aee 6123 }
c69899f0 6124 }
526b7aee 6125
c69899f0
CZ
6126 if (CONST_INT_P (op))
6127 opmode = mode;
526b7aee 6128
c69899f0
CZ
6129 if ((opmode == SImode) && (mode == HImode))
6130 {
6131 opmode = HImode;
6132 op = gen_lowpart (HImode, op);
526b7aee
SV
6133 }
6134
c69899f0
CZ
6135 /* In case the insn wants input operands in modes different from
6136 the result, abort. */
6137 gcc_assert (opmode == mode || opmode == VOIDmode);
526b7aee 6138
c69899f0
CZ
6139 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
6140 op = copy_to_mode_reg (mode, op);
6141
6142 xop[j] = op;
526b7aee
SV
6143 }
6144
c69899f0
CZ
6145 pat = apply_GEN_FCN (icode, xop);
6146 if (pat == NULL_RTX)
6147 return NULL_RTX;
6148
6149 emit_insn (pat);
6150
6151 if (nonvoid)
6152 return target;
6153 else
6154 return const0_rtx;
526b7aee
SV
6155}
6156
6157/* Returns true if the operands[opno] is a valid compile-time constant to be
6158 used as register number in the code for builtins. Else it flags an error
6159 and returns false. */
6160
6161bool
6162check_if_valid_regno_const (rtx *operands, int opno)
6163{
6164
6165 switch (GET_CODE (operands[opno]))
6166 {
6167 case SYMBOL_REF :
6168 case CONST :
6169 case CONST_INT :
6170 return true;
6171 default:
6172 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6173 break;
6174 }
6175 return false;
6176}
6177
6178/* Check that after all the constant folding, whether the operand to
6179 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6180
6181bool
6182check_if_valid_sleep_operand (rtx *operands, int opno)
6183{
6184 switch (GET_CODE (operands[opno]))
6185 {
6186 case CONST :
6187 case CONST_INT :
6188 if( UNSIGNED_INT6 (INTVAL (operands[opno])))
6189 return true;
6190 default:
40fecdd6
JM
6191 fatal_error (input_location,
6192 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
526b7aee
SV
6193 break;
6194 }
6195 return false;
6196}
6197
6198/* Return true if it is ok to make a tail-call to DECL. */
6199
6200static bool
6201arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
6202 tree exp ATTRIBUTE_UNUSED)
6203{
6204 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6205 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
6206 return false;
6207
6208 /* Everything else is ok. */
6209 return true;
6210}
6211
6212/* Output code to add DELTA to the first argument, and then jump
6213 to FUNCTION. Used for C++ multiple inheritance. */
6214
6215static void
6216arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6217 HOST_WIDE_INT delta,
6218 HOST_WIDE_INT vcall_offset,
6219 tree function)
6220{
6221 int mi_delta = delta;
6222 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
6223 int shift = 0;
6224 int this_regno
6225 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
6226 rtx fnaddr;
6227
6228 if (mi_delta < 0)
6229 mi_delta = - mi_delta;
6230
6231 /* Add DELTA. When possible use a plain add, otherwise load it into
6232 a register first. */
6233
6234 while (mi_delta != 0)
6235 {
6236 if ((mi_delta & (3 << shift)) == 0)
6237 shift += 2;
6238 else
6239 {
6240 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
6241 mi_op, reg_names[this_regno], reg_names[this_regno],
6242 mi_delta & (0xff << shift));
6243 mi_delta &= ~(0xff << shift);
6244 shift += 8;
6245 }
6246 }
6247
6248 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6249 if (vcall_offset != 0)
6250 {
6251 /* ld r12,[this] --> temp = *this
6252 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6253 ld r12,[r12]
6254 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6255 asm_fprintf (file, "\tld\t%s, [%s]\n",
6256 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
dfca07ea 6257 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
526b7aee
SV
6258 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
6259 asm_fprintf (file, "\tld\t%s, [%s]\n",
6260 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
6261 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
6262 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
6263 }
6264
6265 fnaddr = XEXP (DECL_RTL (function), 0);
6266
6267 if (arc_is_longcall_p (fnaddr))
6268 fputs ("\tj\t", file);
6269 else
6270 fputs ("\tb\t", file);
6271 assemble_name (file, XSTR (fnaddr, 0));
6272 fputc ('\n', file);
6273}
6274
6275/* Return true if a 32 bit "long_call" should be generated for
6276 this calling SYM_REF. We generate a long_call if the function:
6277
6278 a. has an __attribute__((long call))
6279 or b. the -mlong-calls command line switch has been specified
6280
6281 However we do not generate a long call if the function has an
6282 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6283
6284 This function will be called by C fragments contained in the machine
6285 description file. */
6286
6287bool
6288arc_is_longcall_p (rtx sym_ref)
6289{
6290 if (GET_CODE (sym_ref) != SYMBOL_REF)
6291 return false;
6292
6293 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
6294 || (TARGET_LONG_CALLS_SET
6295 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
6296 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6297
6298}
6299
6300/* Likewise for short calls. */
6301
6302bool
6303arc_is_shortcall_p (rtx sym_ref)
6304{
6305 if (GET_CODE (sym_ref) != SYMBOL_REF)
6306 return false;
6307
6308 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
6309 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
6310 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
6311 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6312
6313}
6314
6315/* Emit profiling code for calling CALLEE. Return true if a special
6316 call pattern needs to be generated. */
6317
6318bool
6319arc_profile_call (rtx callee)
6320{
6321 rtx from = XEXP (DECL_RTL (current_function_decl), 0);
6322
6323 if (TARGET_UCB_MCOUNT)
6324 /* Profiling is done by instrumenting the callee. */
6325 return false;
6326
6327 if (CONSTANT_P (callee))
6328 {
6329 rtx count_ptr
6330 = gen_rtx_CONST (Pmode,
6331 gen_rtx_UNSPEC (Pmode,
6332 gen_rtvec (3, from, callee,
6333 CONST0_RTX (Pmode)),
6334 UNSPEC_PROF));
6335 rtx counter = gen_rtx_MEM (SImode, count_ptr);
6336 /* ??? The increment would better be done atomically, but as there is
6337 no proper hardware support, that would be too expensive. */
6338 emit_move_insn (counter,
6339 force_reg (SImode, plus_constant (SImode, counter, 1)));
6340 return false;
6341 }
6342 else
6343 {
6344 rtx count_list_ptr
6345 = gen_rtx_CONST (Pmode,
6346 gen_rtx_UNSPEC (Pmode,
6347 gen_rtvec (3, from, CONST0_RTX (Pmode),
6348 CONST0_RTX (Pmode)),
6349 UNSPEC_PROF));
6350 emit_move_insn (gen_rtx_REG (Pmode, 8), count_list_ptr);
6351 emit_move_insn (gen_rtx_REG (Pmode, 9), callee);
6352 return true;
6353 }
6354}
6355
6356/* Worker function for TARGET_RETURN_IN_MEMORY. */
6357
6358static bool
6359arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6360{
6361 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
6362 return true;
6363 else
6364 {
6365 HOST_WIDE_INT size = int_size_in_bytes (type);
f50bb868 6366 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
526b7aee
SV
6367 }
6368}
6369
6370
6371/* This was in rtlanal.c, and can go in there when we decide we want
6372 to submit the change for inclusion in the GCC tree. */
6373/* Like note_stores, but allow the callback to have side effects on the rtl
6374 (like the note_stores of yore):
6375 Call FUN on each register or MEM that is stored into or clobbered by X.
6376 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6377 ignored by note_stores, but passed to FUN.
6378 FUN may alter parts of the RTL.
6379
6380 FUN receives three arguments:
6381 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6382 2. the SET or CLOBBER rtx that does the store,
6383 3. the pointer DATA provided to note_stores.
6384
6385 If the item being stored in or clobbered is a SUBREG of a hard register,
6386 the SUBREG will be passed. */
6387
6388/* For now. */ static
6389void
6390walk_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
6391{
6392 int i;
6393
6394 if (GET_CODE (x) == COND_EXEC)
6395 x = COND_EXEC_CODE (x);
6396
6397 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
6398 {
6399 rtx dest = SET_DEST (x);
6400
6401 while ((GET_CODE (dest) == SUBREG
6402 && (!REG_P (SUBREG_REG (dest))
6403 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
6404 || GET_CODE (dest) == ZERO_EXTRACT
6405 || GET_CODE (dest) == STRICT_LOW_PART)
6406 dest = XEXP (dest, 0);
6407
6408 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6409 each of whose first operand is a register. */
6410 if (GET_CODE (dest) == PARALLEL)
6411 {
6412 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
6413 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
6414 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
6415 }
6416 else
6417 (*fun) (dest, x, data);
6418 }
6419
6420 else if (GET_CODE (x) == PARALLEL)
6421 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6422 walk_stores (XVECEXP (x, 0, i), fun, data);
6423}
6424
6425static bool
6426arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
ef4bddc2 6427 machine_mode mode ATTRIBUTE_UNUSED,
526b7aee
SV
6428 const_tree type,
6429 bool named ATTRIBUTE_UNUSED)
6430{
6431 return (type != 0
6432 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
6433 || TREE_ADDRESSABLE (type)));
6434}
6435
1d0216c8
RS
6436/* Implement TARGET_CAN_USE_DOLOOP_P. */
6437
6438static bool
807e902e 6439arc_can_use_doloop_p (const widest_int &iterations, const widest_int &,
1d0216c8
RS
6440 unsigned int loop_depth, bool entered_at_top)
6441{
6442 if (loop_depth > 1)
6443 return false;
6444 /* Setting up the loop with two sr instructions costs 6 cycles. */
6445 if (TARGET_ARC700
6446 && !entered_at_top
807e902e
KZ
6447 && wi::gtu_p (iterations, 0)
6448 && wi::leu_p (iterations, flag_pic ? 6 : 3))
1d0216c8
RS
6449 return false;
6450 return true;
6451}
526b7aee
SV
6452
6453/* NULL if INSN insn is valid within a low-overhead loop.
6454 Otherwise return why doloop cannot be applied. */
6455
6456static const char *
ac44248e 6457arc_invalid_within_doloop (const rtx_insn *insn)
526b7aee
SV
6458{
6459 if (CALL_P (insn))
6460 return "Function call in the loop.";
6461 return NULL;
6462}
6463
f50bb868
CZ
6464/* The same functionality as arc_hazard. It is called in machine
6465 reorg before any other optimization. Hence, the NOP size is taken
6466 into account when doing branch shortening. */
6467
6468static void
6469workaround_arc_anomaly (void)
6470{
6471 rtx_insn *insn, *succ0;
6472
6473 /* For any architecture: call arc_hazard here. */
6474 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6475 {
6476 succ0 = next_real_insn (insn);
6477 if (arc_hazard (insn, succ0))
6478 {
6479 emit_insn_before (gen_nopv (), succ0);
6480 }
6481 }
6482}
6483
526b7aee
SV
6484static int arc_reorg_in_progress = 0;
6485
6486/* ARC's machince specific reorg function. */
6487
6488static void
6489arc_reorg (void)
6490{
b3458f61
DM
6491 rtx_insn *insn;
6492 rtx pattern;
526b7aee
SV
6493 rtx pc_target;
6494 long offset;
6495 int changed;
6496
f50bb868
CZ
6497 workaround_arc_anomaly ();
6498
526b7aee
SV
6499 cfun->machine->arc_reorg_started = 1;
6500 arc_reorg_in_progress = 1;
6501
6502 /* Emit special sections for profiling. */
6503 if (crtl->profile)
6504 {
6505 section *save_text_section;
b3458f61 6506 rtx_insn *insn;
526b7aee
SV
6507 int size = get_max_uid () >> 4;
6508 htab_t htab = htab_create (size, unspec_prof_hash, unspec_prof_htab_eq,
6509 NULL);
6510
6511 save_text_section = in_section;
6512 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6513 if (NONJUMP_INSN_P (insn))
6514 walk_stores (PATTERN (insn), write_profile_sections, htab);
6515 if (htab_elements (htab))
6516 in_section = 0;
6517 switch_to_section (save_text_section);
6518 htab_delete (htab);
6519 }
6520
6521 /* Link up loop ends with their loop start. */
6522 {
6523 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6524 if (GET_CODE (insn) == JUMP_INSN
6525 && recog_memoized (insn) == CODE_FOR_doloop_end_i)
6526 {
b3458f61
DM
6527 rtx_insn *top_label
6528 = as_a <rtx_insn *> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0));
526b7aee 6529 rtx num = GEN_INT (CODE_LABEL_NUMBER (top_label));
b3458f61
DM
6530 rtx_insn *lp, *prev = prev_nonnote_insn (top_label);
6531 rtx_insn *lp_simple = NULL;
6532 rtx_insn *next = NULL;
526b7aee
SV
6533 rtx op0 = XEXP (XVECEXP (PATTERN (insn), 0, 1), 0);
6534 HOST_WIDE_INT loop_end_id
6535 = -INTVAL (XEXP (XVECEXP (PATTERN (insn), 0, 4), 0));
6536 int seen_label = 0;
6537
6538 for (lp = prev;
6539 (lp && NONJUMP_INSN_P (lp)
6540 && recog_memoized (lp) != CODE_FOR_doloop_begin_i);
6541 lp = prev_nonnote_insn (lp))
6542 ;
6543 if (!lp || !NONJUMP_INSN_P (lp)
6544 || dead_or_set_regno_p (lp, LP_COUNT))
6545 {
b3458f61 6546 for (prev = next = insn, lp = NULL ; prev || next;)
526b7aee
SV
6547 {
6548 if (prev)
6549 {
6550 if (NONJUMP_INSN_P (prev)
6551 && recog_memoized (prev) == CODE_FOR_doloop_begin_i
6552 && (INTVAL (XEXP (XVECEXP (PATTERN (prev), 0, 5), 0))
6553 == loop_end_id))
6554 {
6555 lp = prev;
6556 break;
6557 }
6558 else if (LABEL_P (prev))
6559 seen_label = 1;
6560 prev = prev_nonnote_insn (prev);
6561 }
6562 if (next)
6563 {
6564 if (NONJUMP_INSN_P (next)
6565 && recog_memoized (next) == CODE_FOR_doloop_begin_i
6566 && (INTVAL (XEXP (XVECEXP (PATTERN (next), 0, 5), 0))
6567 == loop_end_id))
6568 {
6569 lp = next;
6570 break;
6571 }
6572 next = next_nonnote_insn (next);
6573 }
6574 }
b3458f61 6575 prev = NULL;
526b7aee
SV
6576 }
6577 else
6578 lp_simple = lp;
6579 if (lp && !dead_or_set_regno_p (lp, LP_COUNT))
6580 {
6581 rtx begin_cnt = XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0);
6582 if (INTVAL (XEXP (XVECEXP (PATTERN (lp), 0, 4), 0)))
6583 /* The loop end insn has been duplicated. That can happen
6584 when there is a conditional block at the very end of
6585 the loop. */
6586 goto failure;
6587 /* If Register allocation failed to allocate to the right
6588 register, There is no point into teaching reload to
6589 fix this up with reloads, as that would cost more
6590 than using an ordinary core register with the
6591 doloop_fallback pattern. */
6592 if ((true_regnum (op0) != LP_COUNT || !REG_P (begin_cnt))
6593 /* Likewise, if the loop setup is evidently inside the loop,
6594 we loose. */
6595 || (!lp_simple && lp != next && !seen_label))
6596 {
6597 remove_insn (lp);
6598 goto failure;
6599 }
6600 /* It is common that the optimizers copy the loop count from
6601 another register, and doloop_begin_i is stuck with the
6602 source of the move. Making doloop_begin_i only accept "l"
6603 is nonsentical, as this then makes reload evict the pseudo
6604 used for the loop end. The underlying cause is that the
6605 optimizers don't understand that the register allocation for
6606 doloop_begin_i should be treated as part of the loop.
6607 Try to work around this problem by verifying the previous
6608 move exists. */
6609 if (true_regnum (begin_cnt) != LP_COUNT)
6610 {
b3458f61
DM
6611 rtx_insn *mov;
6612 rtx set, note;
526b7aee
SV
6613
6614 for (mov = prev_nonnote_insn (lp); mov;
6615 mov = prev_nonnote_insn (mov))
6616 {
6617 if (!NONJUMP_INSN_P (mov))
6618 mov = 0;
6619 else if ((set = single_set (mov))
6620 && rtx_equal_p (SET_SRC (set), begin_cnt)
6621 && rtx_equal_p (SET_DEST (set), op0))
6622 break;
6623 }
6624 if (mov)
6625 {
6626 XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0) = op0;
6627 note = find_regno_note (lp, REG_DEAD, REGNO (begin_cnt));
6628 if (note)
6629 remove_note (lp, note);
6630 }
6631 else
6632 {
6633 remove_insn (lp);
6634 goto failure;
6635 }
6636 }
6637 XEXP (XVECEXP (PATTERN (insn), 0, 4), 0) = num;
6638 XEXP (XVECEXP (PATTERN (lp), 0, 4), 0) = num;
6639 if (next == lp)
6640 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const2_rtx;
6641 else if (!lp_simple)
6642 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const1_rtx;
6643 else if (prev != lp)
6644 {
6645 remove_insn (lp);
6646 add_insn_after (lp, prev, NULL);
6647 }
6648 if (!lp_simple)
6649 {
6650 XEXP (XVECEXP (PATTERN (lp), 0, 7), 0)
6651 = gen_rtx_LABEL_REF (Pmode, top_label);
6652 add_reg_note (lp, REG_LABEL_OPERAND, top_label);
6653 LABEL_NUSES (top_label)++;
6654 }
6655 /* We can avoid tedious loop start / end setting for empty loops
6656 be merely setting the loop count to its final value. */
6657 if (next_active_insn (top_label) == insn)
6658 {
6659 rtx lc_set
f7df4a84 6660 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp), 0, 3), 0),
526b7aee
SV
6661 const0_rtx);
6662
b3458f61 6663 rtx_insn *lc_set_insn = emit_insn_before (lc_set, insn);
526b7aee
SV
6664 delete_insn (lp);
6665 delete_insn (insn);
b3458f61 6666 insn = lc_set_insn;
526b7aee
SV
6667 }
6668 /* If the loop is non-empty with zero length, we can't make it
6669 a zero-overhead loop. That can happen for empty asms. */
6670 else
6671 {
b3458f61 6672 rtx_insn *scan;
526b7aee
SV
6673
6674 for (scan = top_label;
6675 (scan && scan != insn
6676 && (!NONJUMP_INSN_P (scan) || !get_attr_length (scan)));
6677 scan = NEXT_INSN (scan));
6678 if (scan == insn)
6679 {
6680 remove_insn (lp);
6681 goto failure;
6682 }
6683 }
6684 }
6685 else
6686 {
6687 /* Sometimes the loop optimizer makes a complete hash of the
6688 loop. If it were only that the loop is not entered at the
6689 top, we could fix this up by setting LP_START with SR .
6690 However, if we can't find the loop begin were it should be,
6691 chances are that it does not even dominate the loop, but is
6692 inside the loop instead. Using SR there would kill
6693 performance.
6694 We use the doloop_fallback pattern here, which executes
6695 in two cycles on the ARC700 when predicted correctly. */
6696 failure:
6697 if (!REG_P (op0))
6698 {
6699 rtx op3 = XEXP (XVECEXP (PATTERN (insn), 0, 5), 0);
6700
6701 emit_insn_before (gen_move_insn (op3, op0), insn);
6702 PATTERN (insn)
6703 = gen_doloop_fallback_m (op3, JUMP_LABEL (insn), op0);
6704 }
6705 else
6706 XVEC (PATTERN (insn), 0)
6707 = gen_rtvec (2, XVECEXP (PATTERN (insn), 0, 0),
6708 XVECEXP (PATTERN (insn), 0, 1));
6709 INSN_CODE (insn) = -1;
6710 }
6711 }
6712 }
6713
6714/* FIXME: should anticipate ccfsm action, generate special patterns for
6715 to-be-deleted branches that have no delay slot and have at least the
6716 length of the size increase forced on other insns that are conditionalized.
6717 This can also have an insn_list inside that enumerates insns which are
6718 not actually conditionalized because the destinations are dead in the
6719 not-execute case.
6720 Could also tag branches that we want to be unaligned if they get no delay
6721 slot, or even ones that we don't want to do delay slot sheduling for
6722 because we can unalign them.
6723
6724 However, there are cases when conditional execution is only possible after
6725 delay slot scheduling:
6726
6727 - If a delay slot is filled with a nocond/set insn from above, the previous
6728 basic block can become elegible for conditional execution.
6729 - If a delay slot is filled with a nocond insn from the fall-through path,
6730 the branch with that delay slot can become eligble for conditional
6731 execution (however, with the same sort of data flow analysis that dbr
6732 does, we could have figured out before that we don't need to
6733 conditionalize this insn.)
6734 - If a delay slot insn is filled with an insn from the target, the
6735 target label gets its uses decremented (even deleted if falling to zero),
6736 thus possibly creating more condexec opportunities there.
6737 Therefore, we should still be prepared to apply condexec optimization on
6738 non-prepared branches if the size increase of conditionalized insns is no
6739 more than the size saved from eliminating the branch. An invocation option
6740 could also be used to reserve a bit of extra size for condbranches so that
6741 this'll work more often (could also test in arc_reorg if the block is
6742 'close enough' to be eligible for condexec to make this likely, and
6743 estimate required size increase). */
6744 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
6745 if (TARGET_NO_BRCC_SET)
6746 return;
6747
6748 do
6749 {
6750 init_insn_lengths();
6751 changed = 0;
6752
6753 if (optimize > 1 && !TARGET_NO_COND_EXEC)
6754 {
6755 arc_ifcvt ();
6756 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
6757 df_finish_pass ((flags & TODO_df_verify) != 0);
6758 }
6759
6760 /* Call shorten_branches to calculate the insn lengths. */
6761 shorten_branches (get_insns());
6762 cfun->machine->ccfsm_current_insn = NULL_RTX;
6763
6764 if (!INSN_ADDRESSES_SET_P())
40fecdd6 6765 fatal_error (input_location, "Insn addresses not set after shorten_branches");
526b7aee
SV
6766
6767 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6768 {
6769 rtx label;
6770 enum attr_type insn_type;
6771
6772 /* If a non-jump insn (or a casesi jump table), continue. */
6773 if (GET_CODE (insn) != JUMP_INSN ||
6774 GET_CODE (PATTERN (insn)) == ADDR_VEC
6775 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
6776 continue;
6777
6778 /* If we already have a brcc, note if it is suitable for brcc_s.
6779 Be a bit generous with the brcc_s range so that we can take
6780 advantage of any code shortening from delay slot scheduling. */
6781 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
6782 {
6783 rtx pat = PATTERN (insn);
6784 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
6785 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
6786
6787 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6788 if ((offset >= -140 && offset < 140)
6789 && rtx_equal_p (XEXP (op, 1), const0_rtx)
6790 && compact_register_operand (XEXP (op, 0), VOIDmode)
6791 && equality_comparison_operator (op, VOIDmode))
6792 PUT_MODE (*ccp, CC_Zmode);
6793 else if (GET_MODE (*ccp) == CC_Zmode)
6794 PUT_MODE (*ccp, CC_ZNmode);
6795 continue;
6796 }
6797 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
6798 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
6799 continue;
6800
6801 /* OK. so we have a jump insn. */
6802 /* We need to check that it is a bcc. */
6803 /* Bcc => set (pc) (if_then_else ) */
6804 pattern = PATTERN (insn);
6805 if (GET_CODE (pattern) != SET
6806 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
6807 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
6808 continue;
6809
6810 /* Now check if the jump is beyond the s9 range. */
339ba33b 6811 if (CROSSING_JUMP_P (insn))
526b7aee
SV
6812 continue;
6813 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6814
6815 if(offset > 253 || offset < -254)
6816 continue;
6817
6818 pc_target = SET_SRC (pattern);
6819
8f3304d0
CZ
6820 /* Avoid FPU instructions. */
6821 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
6822 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
6823 continue;
6824
526b7aee
SV
6825 /* Now go back and search for the set cc insn. */
6826
6827 label = XEXP (pc_target, 1);
6828
6829 {
b3458f61
DM
6830 rtx pat;
6831 rtx_insn *scan, *link_insn = NULL;
526b7aee
SV
6832
6833 for (scan = PREV_INSN (insn);
6834 scan && GET_CODE (scan) != CODE_LABEL;
6835 scan = PREV_INSN (scan))
6836 {
6837 if (! INSN_P (scan))
6838 continue;
6839 pat = PATTERN (scan);
6840 if (GET_CODE (pat) == SET
6841 && cc_register (SET_DEST (pat), VOIDmode))
6842 {
6843 link_insn = scan;
6844 break;
6845 }
6846 }
8f3304d0 6847 if (!link_insn)
526b7aee
SV
6848 continue;
6849 else
6850 /* Check if this is a data dependency. */
6851 {
6852 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
6853 rtx cmp0, cmp1;
6854
6855 /* Ok this is the set cc. copy args here. */
6856 op = XEXP (pc_target, 0);
6857
6858 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
6859 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
6860 if (GET_CODE (op0) == ZERO_EXTRACT
6861 && XEXP (op0, 1) == const1_rtx
6862 && (GET_CODE (op) == EQ
6863 || GET_CODE (op) == NE))
6864 {
6865 /* btst / b{eq,ne} -> bbit{0,1} */
6866 op0 = XEXP (cmp0, 0);
6867 op1 = XEXP (cmp0, 2);
6868 }
6869 else if (!register_operand (op0, VOIDmode)
6870 || !general_operand (op1, VOIDmode))
6871 continue;
6872 /* Be careful not to break what cmpsfpx_raw is
6873 trying to create for checking equality of
6874 single-precision floats. */
6875 else if (TARGET_SPFP
6876 && GET_MODE (op0) == SFmode
6877 && GET_MODE (op1) == SFmode)
6878 continue;
6879
6880 /* None of the two cmp operands should be set between the
6881 cmp and the branch. */
6882 if (reg_set_between_p (op0, link_insn, insn))
6883 continue;
6884
6885 if (reg_set_between_p (op1, link_insn, insn))
6886 continue;
6887
6888 /* Since the MODE check does not work, check that this is
6889 CC reg's last set location before insn, and also no
6890 instruction between the cmp and branch uses the
6891 condition codes. */
6892 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
6893 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
6894 continue;
6895
6896 /* CC reg should be dead after insn. */
6897 if (!find_regno_note (insn, REG_DEAD, CC_REG))
6898 continue;
6899
6900 op = gen_rtx_fmt_ee (GET_CODE (op),
6901 GET_MODE (op), cmp0, cmp1);
6902 /* If we create a LIMM where there was none before,
6903 we only benefit if we can avoid a scheduling bubble
6904 for the ARC600. Otherwise, we'd only forgo chances
6905 at short insn generation, and risk out-of-range
6906 branches. */
6907 if (!brcc_nolimm_operator (op, VOIDmode)
6908 && !long_immediate_operand (op1, VOIDmode)
6909 && (TARGET_ARC700
6910 || next_active_insn (link_insn) != insn))
6911 continue;
6912
6913 /* Emit bbit / brcc (or brcc_s if possible).
6914 CC_Zmode indicates that brcc_s is possible. */
6915
6916 if (op0 != cmp0)
6917 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
6918 else if ((offset >= -140 && offset < 140)
6919 && rtx_equal_p (op1, const0_rtx)
6920 && compact_register_operand (op0, VOIDmode)
6921 && (GET_CODE (op) == EQ
6922 || GET_CODE (op) == NE))
6923 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
6924 else
6925 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
6926
6927 brcc_insn
6928 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
f7df4a84 6929 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
526b7aee
SV
6930 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
6931 brcc_insn
6932 = gen_rtx_PARALLEL
6933 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
6934 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
6935
6936 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
6937 note = find_reg_note (insn, REG_BR_PROB, 0);
6938 if (note)
6939 {
6940 XEXP (note, 1) = REG_NOTES (brcc_insn);
6941 REG_NOTES (brcc_insn) = note;
6942 }
6943 note = find_reg_note (link_insn, REG_DEAD, op0);
6944 if (note)
6945 {
6946 remove_note (link_insn, note);
6947 XEXP (note, 1) = REG_NOTES (brcc_insn);
6948 REG_NOTES (brcc_insn) = note;
6949 }
6950 note = find_reg_note (link_insn, REG_DEAD, op1);
6951 if (note)
6952 {
6953 XEXP (note, 1) = REG_NOTES (brcc_insn);
6954 REG_NOTES (brcc_insn) = note;
6955 }
6956
6957 changed = 1;
6958
6959 /* Delete the bcc insn. */
6960 set_insn_deleted (insn);
6961
6962 /* Delete the cmp insn. */
6963 set_insn_deleted (link_insn);
6964
6965 }
6966 }
6967 }
6968 /* Clear out insn_addresses. */
6969 INSN_ADDRESSES_FREE ();
6970
6971 } while (changed);
6972
6973 if (INSN_ADDRESSES_SET_P())
40fecdd6 6974 fatal_error (input_location, "insn addresses not freed");
526b7aee
SV
6975
6976 arc_reorg_in_progress = 0;
6977}
6978
6979 /* Check if the operands are valid for BRcc.d generation
6980 Valid Brcc.d patterns are
6981 Brcc.d b, c, s9
6982 Brcc.d b, u6, s9
6983
6984 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
6985 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
6986 does not have a delay slot
6987
6988 Assumed precondition: Second operand is either a register or a u6 value. */
6989
6990bool
6991valid_brcc_with_delay_p (rtx *operands)
6992{
6993 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
6994 return false;
6995 return brcc_nolimm_operator (operands[0], VOIDmode);
6996}
6997
6998/* ??? Hack. This should no really be here. See PR32143. */
6999static bool
7000arc_decl_anon_ns_mem_p (const_tree decl)
7001{
7002 while (1)
7003 {
7004 if (decl == NULL_TREE || decl == error_mark_node)
7005 return false;
7006 if (TREE_CODE (decl) == NAMESPACE_DECL
7007 && DECL_NAME (decl) == NULL_TREE)
7008 return true;
7009 /* Classes and namespaces inside anonymous namespaces have
7010 TREE_PUBLIC == 0, so we can shortcut the search. */
7011 else if (TYPE_P (decl))
7012 return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
7013 else if (TREE_CODE (decl) == NAMESPACE_DECL)
7014 return (TREE_PUBLIC (decl) == 0);
7015 else
7016 decl = DECL_CONTEXT (decl);
7017 }
7018}
7019
7020/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7021 access DECL using %gp_rel(...)($gp). */
7022
7023static bool
7024arc_in_small_data_p (const_tree decl)
7025{
7026 HOST_WIDE_INT size;
7027
7028 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
7029 return false;
7030
7031
7032 /* We don't yet generate small-data references for -mabicalls. See related
7033 -G handling in override_options. */
7034 if (TARGET_NO_SDATA_SET)
7035 return false;
7036
7037 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
7038 {
7039 const char *name;
7040
7041 /* Reject anything that isn't in a known small-data section. */
f961457f 7042 name = DECL_SECTION_NAME (decl);
526b7aee
SV
7043 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
7044 return false;
7045
7046 /* If a symbol is defined externally, the assembler will use the
7047 usual -G rules when deciding how to implement macros. */
7048 if (!DECL_EXTERNAL (decl))
7049 return true;
7050 }
7051 /* Only global variables go into sdata section for now. */
7052 else if (1)
7053 {
7054 /* Don't put constants into the small data section: we want them
7055 to be in ROM rather than RAM. */
7056 if (TREE_CODE (decl) != VAR_DECL)
7057 return false;
7058
7059 if (TREE_READONLY (decl)
7060 && !TREE_SIDE_EFFECTS (decl)
7061 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
7062 return false;
7063
7064 /* TREE_PUBLIC might change after the first call, because of the patch
7065 for PR19238. */
7066 if (default_binds_local_p_1 (decl, 1)
7067 || arc_decl_anon_ns_mem_p (decl))
7068 return false;
7069
7070 /* To ensure -mvolatile-cache works
7071 ld.di does not have a gp-relative variant. */
7072 if (TREE_THIS_VOLATILE (decl))
7073 return false;
7074 }
7075
7076 /* Disable sdata references to weak variables. */
7077 if (DECL_WEAK (decl))
7078 return false;
7079
7080 size = int_size_in_bytes (TREE_TYPE (decl));
7081
7082/* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7083/* return false; */
7084
7085 /* Allow only <=4B long data types into sdata. */
7086 return (size > 0 && size <= 4);
7087}
7088
7089/* Return true if X is a small data address that can be rewritten
7090 as a gp+symref. */
7091
7092static bool
752ae22f 7093arc_rewrite_small_data_p (const_rtx x)
526b7aee
SV
7094{
7095 if (GET_CODE (x) == CONST)
7096 x = XEXP (x, 0);
7097
7098 if (GET_CODE (x) == PLUS)
7099 {
7100 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
7101 x = XEXP (x, 0);
7102 }
7103
28633bbd
CZ
7104 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
7105 {
7106 gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0);
7107 return true;
7108 }
7109 return false;
526b7aee
SV
7110}
7111
526b7aee
SV
7112/* If possible, rewrite OP so that it refers to small data using
7113 explicit relocations. */
7114
7115rtx
7116arc_rewrite_small_data (rtx op)
7117{
7118 op = copy_insn (op);
6733978e
RS
7119 subrtx_ptr_iterator::array_type array;
7120 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
7121 {
7122 rtx *loc = *iter;
7123 if (arc_rewrite_small_data_p (*loc))
7124 {
7125 gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
7126 *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
7127 if (loc != &op)
7128 {
7129 if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
7130 ; /* OK. */
7131 else if (GET_CODE (op) == MEM
7132 && GET_CODE (XEXP (op, 0)) == PLUS
7133 && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
7134 *loc = force_reg (Pmode, *loc);
7135 else
7136 gcc_unreachable ();
7137 }
7138 iter.skip_subrtxes ();
7139 }
7140 else if (GET_CODE (*loc) == PLUS
7141 && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
7142 iter.skip_subrtxes ();
7143 }
526b7aee
SV
7144 return op;
7145}
7146
526b7aee
SV
7147/* Return true if OP refers to small data symbols directly, not through
7148 a PLUS. */
7149
7150bool
ef4bddc2 7151small_data_pattern (rtx op, machine_mode)
526b7aee 7152{
752ae22f
RS
7153 if (GET_CODE (op) == SEQUENCE)
7154 return false;
7155 subrtx_iterator::array_type array;
7156 FOR_EACH_SUBRTX (iter, array, op, ALL)
7157 {
7158 const_rtx x = *iter;
7159 if (GET_CODE (x) == PLUS
7160 && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
7161 iter.skip_subrtxes ();
7162 else if (arc_rewrite_small_data_p (x))
7163 return true;
7164 }
7165 return false;
526b7aee
SV
7166}
7167
7168/* Return true if OP is an acceptable memory operand for ARCompact
7169 16-bit gp-relative load instructions.
7170 op shd look like : [r26, symref@sda]
7171 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7172 */
7173/* volatile cache option still to be handled. */
7174
7175bool
ef4bddc2 7176compact_sda_memory_operand (rtx op, machine_mode mode)
526b7aee
SV
7177{
7178 rtx addr;
7179 int size;
7180
7181 /* Eliminate non-memory operations. */
7182 if (GET_CODE (op) != MEM)
7183 return false;
7184
7185 if (mode == VOIDmode)
7186 mode = GET_MODE (op);
7187
7188 size = GET_MODE_SIZE (mode);
7189
7190 /* dword operations really put out 2 instructions, so eliminate them. */
7191 if (size > UNITS_PER_WORD)
7192 return false;
7193
7194 /* Decode the address now. */
7195 addr = XEXP (op, 0);
7196
7197 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
7198}
7199
7200/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7201
7202void
7203arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
7204 unsigned HOST_WIDE_INT size,
7205 unsigned HOST_WIDE_INT align,
7206 unsigned HOST_WIDE_INT globalize_p)
7207{
7208 int in_small_data = arc_in_small_data_p (decl);
7209
7210 if (in_small_data)
7211 switch_to_section (get_named_section (NULL, ".sbss", 0));
7212 /* named_section (0,".sbss",0); */
7213 else
7214 switch_to_section (bss_section);
7215
7216 if (globalize_p)
7217 (*targetm.asm_out.globalize_label) (stream, name);
7218
7219 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
7220 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
7221 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
7222 ASM_OUTPUT_LABEL (stream, name);
7223
7224 if (size != 0)
7225 ASM_OUTPUT_SKIP (stream, size);
7226}
7227
526b7aee
SV
7228static bool
7229arc_preserve_reload_p (rtx in)
7230{
7231 return (GET_CODE (in) == PLUS
7232 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
7233 && CONST_INT_P (XEXP (in, 1))
7234 && !((INTVAL (XEXP (in, 1)) & 511)));
7235}
7236
7237int
ef4bddc2 7238arc_register_move_cost (machine_mode,
526b7aee
SV
7239 enum reg_class from_class, enum reg_class to_class)
7240{
7241 /* The ARC600 has no bypass for extension registers, hence a nop might be
7242 needed to be inserted after a write so that reads are safe. */
7243 if (TARGET_ARC600)
7244 {
7245 if (to_class == MPY_WRITABLE_CORE_REGS)
7246 return 3;
7247 /* Instructions modifying LP_COUNT need 4 additional cycles before
7248 the register will actually contain the value. */
7249 else if (to_class == LPCOUNT_REG)
7250 return 6;
7251 else if (to_class == WRITABLE_CORE_REGS)
7252 return 6;
7253 }
7254
7255 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7256 if (TARGET_ARC700
7257 && (from_class == LPCOUNT_REG || from_class == ALL_CORE_REGS
7258 || from_class == WRITABLE_CORE_REGS))
7259 return 8;
7260
7261 /* Force an attempt to 'mov Dy,Dx' to spill. */
7262 if (TARGET_ARC700 && TARGET_DPFP
7263 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
7264 return 100;
7265
7266 return 2;
7267}
7268
7269/* Emit code for an addsi3 instruction with OPERANDS.
7270 COND_P indicates if this will use conditional execution.
7271 Return the length of the instruction.
7272 If OUTPUT_P is false, don't actually output the instruction, just return
7273 its length. */
7274int
7275arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
7276{
7277 char format[32];
7278
7279 int match = operands_match_p (operands[0], operands[1]);
7280 int match2 = operands_match_p (operands[0], operands[2]);
7281 int intval = (REG_P (operands[2]) ? 1
7282 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
7283 int neg_intval = -intval;
7284 int short_0 = satisfies_constraint_Rcq (operands[0]);
7285 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
7286 int ret = 0;
7287
7288#define ADDSI_OUTPUT1(FORMAT) do {\
7289 if (output_p) \
7290 output_asm_insn (FORMAT, operands);\
7291 return ret; \
7292} while (0)
7293#define ADDSI_OUTPUT(LIST) do {\
7294 if (output_p) \
7295 sprintf LIST;\
7296 ADDSI_OUTPUT1 (format);\
7297 return ret; \
7298} while (0)
7299
7300 /* First try to emit a 16 bit insn. */
7301 ret = 2;
7302 if (!cond_p
7303 /* If we are actually about to output this insn, don't try a 16 bit
7304 variant if we already decided that we don't want that
7305 (I.e. we upsized this insn to align some following insn.)
7306 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7307 but add1 r0,sp,35 doesn't. */
7308 && (!output_p || (get_attr_length (current_output_insn) & 2)))
7309 {
7310 if (short_p
7311 && (REG_P (operands[2])
7312 ? (match || satisfies_constraint_Rcq (operands[2]))
7313 : (unsigned) intval <= (match ? 127 : 7)))
7314 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7315 if (short_0 && REG_P (operands[1]) && match2)
7316 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7317 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
7318 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
7319 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7320
7321 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
7322 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
7323 && match && !(neg_intval & ~124)))
7324 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7325 }
7326
7327 /* Now try to emit a 32 bit insn without long immediate. */
7328 ret = 4;
7329 if (!match && match2 && REG_P (operands[1]))
7330 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7331 if (match || !cond_p)
7332 {
7333 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
7334 int range_factor = neg_intval & intval;
7335 int shift;
7336
c419f71c 7337 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
526b7aee
SV
7338 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7339
7340 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7341 same size, do, so - the insn latency is lower. */
7342 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7343 0x800 is not. */
7344 if ((intval >= 0 && intval <= limit)
7345 || (intval == -0x800 && limit == 0x7ff))
7346 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7347 else if ((intval < 0 && neg_intval <= limit)
7348 || (intval == 0x800 && limit == 0x7ff))
7349 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7350 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
7351 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
7352 gcc_assert ((((1 << shift) - 1) & intval) == 0);
7353 if (((intval < 0 && intval != -0x4000)
7354 /* sub[123] is slower than add_s / sub, only use it if it
7355 avoids a long immediate. */
7356 && neg_intval <= limit << shift)
7357 || (intval == 0x4000 && limit == 0x7ff))
7358 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
7359 shift, neg_intval >> shift));
7360 else if ((intval >= 0 && intval <= limit << shift)
7361 || (intval == -0x4000 && limit == 0x7ff))
7362 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
7363 }
7364 /* Try to emit a 16 bit opcode with long immediate. */
7365 ret = 6;
7366 if (short_p && match)
7367 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7368
7369 /* We have to use a 32 bit opcode, and with a long immediate. */
7370 ret = 8;
7371 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7372}
7373
7374/* Emit code for an commutative_cond_exec instruction with OPERANDS.
7375 Return the length of the instruction.
7376 If OUTPUT_P is false, don't actually output the instruction, just return
7377 its length. */
7378int
7379arc_output_commutative_cond_exec (rtx *operands, bool output_p)
7380{
7381 enum rtx_code commutative_op = GET_CODE (operands[3]);
7382 const char *pat = NULL;
7383
7384 /* Canonical rtl should not have a constant in the first operand position. */
7385 gcc_assert (!CONSTANT_P (operands[1]));
7386
7387 switch (commutative_op)
7388 {
7389 case AND:
7390 if (satisfies_constraint_C1p (operands[2]))
7391 pat = "bmsk%? %0,%1,%Z2";
fc1c2d04
CZ
7392 else if (satisfies_constraint_C2p (operands[2]))
7393 {
7394 operands[2] = GEN_INT ((~INTVAL (operands[2])));
7395 pat = "bmskn%? %0,%1,%Z2";
7396 }
526b7aee
SV
7397 else if (satisfies_constraint_Ccp (operands[2]))
7398 pat = "bclr%? %0,%1,%M2";
7399 else if (satisfies_constraint_CnL (operands[2]))
7400 pat = "bic%? %0,%1,%n2-1";
7401 break;
7402 case IOR:
7403 if (satisfies_constraint_C0p (operands[2]))
7404 pat = "bset%? %0,%1,%z2";
7405 break;
7406 case XOR:
7407 if (satisfies_constraint_C0p (operands[2]))
7408 pat = "bxor%? %0,%1,%z2";
7409 break;
7410 case PLUS:
7411 return arc_output_addsi (operands, true, output_p);
7412 default: break;
7413 }
7414 if (output_p)
7415 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
7416 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
7417 return 4;
7418 return 8;
7419}
7420
7421/* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7422 Emit code and return an potentially modified address such that offsets
7423 up to SIZE are can be added to yield a legitimate address.
7424 if REUSE is set, ADDR is a register that may be modified. */
7425
7426static rtx
7427force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
7428{
7429 rtx base = addr;
7430 rtx offs = const0_rtx;
7431
7432 if (GET_CODE (base) == PLUS)
7433 {
7434 offs = XEXP (base, 1);
7435 base = XEXP (base, 0);
7436 }
7437 if (!REG_P (base)
7438 || (REGNO (base) != STACK_POINTER_REGNUM
7439 && REGNO_PTR_FRAME_P (REGNO (addr)))
7440 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
7441 || !SMALL_INT (INTVAL (offs) + size))
7442 {
7443 if (reuse)
7444 emit_insn (gen_add2_insn (addr, offs));
7445 else
7446 addr = copy_to_mode_reg (Pmode, addr);
7447 }
7448 return addr;
7449}
7450
d34a0fdc
CZ
7451/* Like move_by_pieces, but take account of load latency, and actual
7452 offset ranges. Return true on success. */
526b7aee
SV
7453
7454bool
7455arc_expand_movmem (rtx *operands)
7456{
7457 rtx dst = operands[0];
7458 rtx src = operands[1];
7459 rtx dst_addr, src_addr;
7460 HOST_WIDE_INT size;
7461 int align = INTVAL (operands[3]);
7462 unsigned n_pieces;
7463 int piece = align;
7464 rtx store[2];
7465 rtx tmpx[2];
7466 int i;
7467
7468 if (!CONST_INT_P (operands[2]))
7469 return false;
7470 size = INTVAL (operands[2]);
7471 /* move_by_pieces_ninsns is static, so we can't use it. */
7472 if (align >= 4)
d34a0fdc
CZ
7473 {
7474 if (TARGET_LL64)
7475 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
7476 else
7477 n_pieces = (size + 2) / 4U + (size & 1);
7478 }
526b7aee
SV
7479 else if (align == 2)
7480 n_pieces = (size + 1) / 2U;
7481 else
7482 n_pieces = size;
7483 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
7484 return false;
d34a0fdc
CZ
7485 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7486 possible. */
7487 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
7488 piece = 8;
7489 else if (piece > 4)
526b7aee
SV
7490 piece = 4;
7491 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
7492 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
7493 store[0] = store[1] = NULL_RTX;
7494 tmpx[0] = tmpx[1] = NULL_RTX;
7495 for (i = 0; size > 0; i ^= 1, size -= piece)
7496 {
7497 rtx tmp;
ef4bddc2 7498 machine_mode mode;
526b7aee 7499
d34a0fdc
CZ
7500 while (piece > size)
7501 piece >>= 1;
526b7aee
SV
7502 mode = smallest_mode_for_size (piece * BITS_PER_UNIT, MODE_INT);
7503 /* If we don't re-use temporaries, the scheduler gets carried away,
7504 and the register pressure gets unnecessarily high. */
7505 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
7506 tmp = tmpx[i];
7507 else
7508 tmpx[i] = tmp = gen_reg_rtx (mode);
7509 dst_addr = force_offsettable (dst_addr, piece, 1);
7510 src_addr = force_offsettable (src_addr, piece, 1);
7511 if (store[i])
7512 emit_insn (store[i]);
7513 emit_move_insn (tmp, change_address (src, mode, src_addr));
7514 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
7515 dst_addr = plus_constant (Pmode, dst_addr, piece);
7516 src_addr = plus_constant (Pmode, src_addr, piece);
7517 }
7518 if (store[i])
7519 emit_insn (store[i]);
7520 if (store[i^1])
7521 emit_insn (store[i^1]);
7522 return true;
7523}
7524
7525/* Prepare operands for move in MODE. Return true iff the move has
7526 been emitted. */
7527
7528bool
ef4bddc2 7529prepare_move_operands (rtx *operands, machine_mode mode)
526b7aee
SV
7530{
7531 /* We used to do this only for MODE_INT Modes, but addresses to floating
7532 point variables may well be in the small data section. */
28633bbd
CZ
7533 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
7534 operands[0] = arc_rewrite_small_data (operands[0]);
7535
7536 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
526b7aee 7537 {
28633bbd 7538 prepare_pic_move (operands, SImode);
526b7aee 7539
28633bbd
CZ
7540 /* Disable any REG_EQUALs associated with the symref
7541 otherwise the optimization pass undoes the work done
7542 here and references the variable directly. */
7543 }
7544
7545 if (GET_CODE (operands[0]) != MEM
7546 && !TARGET_NO_SDATA_SET
7547 && small_data_pattern (operands[1], Pmode))
7548 {
7549 /* This is to take care of address calculations involving sdata
7550 variables. */
7551 operands[1] = arc_rewrite_small_data (operands[1]);
7552
7553 emit_insn (gen_rtx_SET (operands[0],operands[1]));
7554 /* ??? This note is useless, since it only restates the set itself.
7555 We should rather use the original SYMBOL_REF. However, there is
7556 the problem that we are lying to the compiler about these
7557 SYMBOL_REFs to start with. symbol@sda should be encoded specially
7558 so that we can tell it apart from an actual symbol. */
7559 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7560
7561 /* Take care of the REG_EQUAL note that will be attached to mark the
7562 output reg equal to the initial symbol_ref after this code is
7563 executed. */
7564 emit_move_insn (operands[0], operands[0]);
7565 return true;
526b7aee
SV
7566 }
7567
7568 if (MEM_P (operands[0])
7569 && !(reload_in_progress || reload_completed))
7570 {
7571 operands[1] = force_reg (mode, operands[1]);
7572 if (!move_dest_operand (operands[0], mode))
7573 {
7574 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7575 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
7576 except that we can't use that function because it is static. */
7577 rtx pat = change_address (operands[0], mode, addr);
7578 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7579 operands[0] = pat;
7580 }
7581 if (!cse_not_expected)
7582 {
7583 rtx pat = XEXP (operands[0], 0);
7584
7585 pat = arc_legitimize_address_0 (pat, pat, mode);
7586 if (pat)
7587 {
7588 pat = change_address (operands[0], mode, pat);
7589 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7590 operands[0] = pat;
7591 }
7592 }
7593 }
7594
7595 if (MEM_P (operands[1]) && !cse_not_expected)
7596 {
7597 rtx pat = XEXP (operands[1], 0);
7598
7599 pat = arc_legitimize_address_0 (pat, pat, mode);
7600 if (pat)
7601 {
7602 pat = change_address (operands[1], mode, pat);
7603 MEM_COPY_ATTRIBUTES (pat, operands[1]);
7604 operands[1] = pat;
7605 }
7606 }
7607
7608 return false;
7609}
7610
7611/* Prepare OPERANDS for an extension using CODE to OMODE.
7612 Return true iff the move has been emitted. */
7613
7614bool
7615prepare_extend_operands (rtx *operands, enum rtx_code code,
ef4bddc2 7616 machine_mode omode)
526b7aee
SV
7617{
7618 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
7619 {
7620 /* This is to take care of address calculations involving sdata
7621 variables. */
7622 operands[1]
7623 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
f7df4a84 7624 emit_insn (gen_rtx_SET (operands[0], operands[1]));
526b7aee
SV
7625 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7626
7627 /* Take care of the REG_EQUAL note that will be attached to mark the
7628 output reg equal to the initial extension after this code is
7629 executed. */
7630 emit_move_insn (operands[0], operands[0]);
7631 return true;
7632 }
7633 return false;
7634}
7635
7636/* Output a library call to a function called FNAME that has been arranged
7637 to be local to any dso. */
7638
7639const char *
7640arc_output_libcall (const char *fname)
7641{
7642 unsigned len = strlen (fname);
7643 static char buf[64];
7644
7645 gcc_assert (len < sizeof buf - 35);
7646 if (TARGET_LONG_CALLS_SET
7647 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
7648 {
7649 if (flag_pic)
7650 sprintf (buf, "add r12,pcl,@%s-(.&-4)\n\tjl%%!%%* [r12]", fname);
7651 else
7652 sprintf (buf, "jl%%! @%s", fname);
7653 }
7654 else
7655 sprintf (buf, "bl%%!%%* @%s", fname);
7656 return buf;
7657}
7658
7659/* Return the SImode highpart of the DImode value IN. */
7660
7661rtx
7662disi_highpart (rtx in)
7663{
7664 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
7665}
7666
526b7aee
SV
7667/* Return length adjustment for INSN.
7668 For ARC600:
7669 A write to a core reg greater or equal to 32 must not be immediately
7670 followed by a use. Anticipate the length requirement to insert a nop
7671 between PRED and SUCC to prevent a hazard. */
7672
7673static int
647d790d 7674arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee
SV
7675{
7676 if (!TARGET_ARC600)
7677 return 0;
7678 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
7679 in front of SUCC anyway, so there will be separation between PRED and
7680 SUCC. */
7681 if (recog_memoized (succ) == CODE_FOR_doloop_end_i
7682 && LABEL_P (prev_nonnote_insn (succ)))
7683 return 0;
7684 if (recog_memoized (succ) == CODE_FOR_doloop_begin_i)
7685 return 0;
7686 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
647d790d 7687 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
526b7aee 7688 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
647d790d 7689 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
526b7aee
SV
7690 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7691 || recog_memoized (pred) == CODE_FOR_umul_600
7692 || recog_memoized (pred) == CODE_FOR_mac_600
7693 || recog_memoized (pred) == CODE_FOR_mul64_600
7694 || recog_memoized (pred) == CODE_FOR_mac64_600
7695 || recog_memoized (pred) == CODE_FOR_umul64_600
7696 || recog_memoized (pred) == CODE_FOR_umac64_600)
7697 return 0;
36cc6254
RS
7698 subrtx_iterator::array_type array;
7699 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7700 {
7701 const_rtx x = *iter;
7702 switch (GET_CODE (x))
7703 {
7704 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7705 break;
7706 default:
7707 /* This is also fine for PRE/POST_MODIFY, because they
7708 contain a SET. */
7709 continue;
7710 }
7711 rtx dest = XEXP (x, 0);
7712 /* Check if this sets a an extension register. N.B. we use 61 for the
7713 condition codes, which is definitely not an extension register. */
7714 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7715 /* Check if the same register is used by the PAT. */
7716 && (refers_to_regno_p
7717 (REGNO (dest),
7718 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7719 PATTERN (succ), 0)))
7720 return 4;
7721 }
7722 return 0;
526b7aee
SV
7723}
7724
f50bb868
CZ
7725/* Given a rtx, check if it is an assembly instruction or not. */
7726
7727static int
7728arc_asm_insn_p (rtx x)
7729{
7730 int i, j;
7731
7732 if (x == 0)
7733 return 0;
7734
7735 switch (GET_CODE (x))
7736 {
7737 case ASM_OPERANDS:
7738 case ASM_INPUT:
7739 return 1;
7740
7741 case SET:
7742 return arc_asm_insn_p (SET_SRC (x));
7743
7744 case PARALLEL:
7745 j = 0;
7746 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
7747 j += arc_asm_insn_p (XVECEXP (x, 0, i));
7748 if ( j > 0)
7749 return 1;
7750 break;
7751
7752 default:
7753 break;
7754 }
7755
7756 return 0;
7757}
7758
7759/* We might have a CALL to a non-returning function before a loop end.
7760 ??? Although the manual says that's OK (the target is outside the
7761 loop, and the loop counter unused there), the assembler barfs on
7762 this for ARC600, so we must insert a nop before such a call too.
7763 For ARC700, and ARCv2 is not allowed to have the last ZOL
7764 instruction a jump to a location where lp_count is modified. */
7765
7766static bool
7767arc_loop_hazard (rtx_insn *pred, rtx_insn *succ)
7768{
7769 rtx_insn *jump = NULL;
a30c5ca4 7770 rtx label_rtx = NULL_RTX;
f50bb868
CZ
7771 rtx_insn *label = NULL;
7772 basic_block succ_bb;
7773
7774 if (recog_memoized (succ) != CODE_FOR_doloop_end_i)
7775 return false;
7776
7777 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
7778 (i.e., jump/call) as the last instruction of a ZOL. */
7779 if (TARGET_ARC600 || TARGET_HS)
7780 if (JUMP_P (pred) || CALL_P (pred)
7781 || arc_asm_insn_p (PATTERN (pred))
7782 || GET_CODE (PATTERN (pred)) == SEQUENCE)
7783 return true;
7784
7785 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
7786 instruction a jump to a location where lp_count is modified. */
7787
7788 /* Phase 2a: Dig for the jump instruction. */
7789 if (JUMP_P (pred))
7790 jump = pred;
7791 else if (GET_CODE (PATTERN (pred)) == SEQUENCE
7792 && JUMP_P (XVECEXP (PATTERN (pred), 0, 0)))
7793 jump = as_a <rtx_insn *> XVECEXP (PATTERN (pred), 0, 0);
7794 else
7795 return false;
7796
f50bb868
CZ
7797 /* Phase 2b: Make sure is not a millicode jump. */
7798 if ((GET_CODE (PATTERN (jump)) == PARALLEL)
7799 && (XVECEXP (PATTERN (jump), 0, 0) == ret_rtx))
7800 return false;
7801
a30c5ca4
AB
7802 label_rtx = JUMP_LABEL (jump);
7803 if (!label_rtx)
7804 return false;
7805
7806 /* Phase 2c: Make sure is not a return. */
7807 if (ANY_RETURN_P (label_rtx))
f50bb868
CZ
7808 return false;
7809
7810 /* Pahse 2d: Go to the target of the jump and check for aliveness of
7811 LP_COUNT register. */
a30c5ca4 7812 label = safe_as_a <rtx_insn *> (label_rtx);
f50bb868
CZ
7813 succ_bb = BLOCK_FOR_INSN (label);
7814 if (!succ_bb)
7815 {
7816 gcc_assert (NEXT_INSN (label));
7817 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label)))
7818 succ_bb = NOTE_BASIC_BLOCK (NEXT_INSN (label));
7819 else
7820 succ_bb = BLOCK_FOR_INSN (NEXT_INSN (label));
7821 }
7822
7823 if (succ_bb && REGNO_REG_SET_P (df_get_live_out (succ_bb), LP_COUNT))
7824 return true;
7825
7826 return false;
7827}
7828
526b7aee
SV
7829/* For ARC600:
7830 A write to a core reg greater or equal to 32 must not be immediately
7831 followed by a use. Anticipate the length requirement to insert a nop
7832 between PRED and SUCC to prevent a hazard. */
7833
7834int
647d790d 7835arc_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee 7836{
526b7aee
SV
7837 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7838 return 0;
f50bb868
CZ
7839
7840 if (arc_loop_hazard (pred, succ))
526b7aee 7841 return 4;
f50bb868
CZ
7842
7843 if (TARGET_ARC600)
7844 return arc600_corereg_hazard (pred, succ);
7845
7846 return 0;
526b7aee
SV
7847}
7848
7849/* Return length adjustment for INSN. */
7850
7851int
647d790d 7852arc_adjust_insn_length (rtx_insn *insn, int len, bool)
526b7aee
SV
7853{
7854 if (!INSN_P (insn))
7855 return len;
7856 /* We already handle sequences by ignoring the delay sequence flag. */
7857 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
7858 return len;
7859
7860 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
7861 the ZOL mechanism only triggers when advancing to the end address,
7862 so if there's a label at the end of a ZOL, we need to insert a nop.
7863 The ARC600 ZOL also has extra restrictions on jumps at the end of a
7864 loop. */
7865 if (recog_memoized (insn) == CODE_FOR_doloop_end_i)
7866 {
b3458f61 7867 rtx_insn *prev = prev_nonnote_insn (insn);
526b7aee
SV
7868
7869 return ((LABEL_P (prev)
7870 || (TARGET_ARC600
7871 && (JUMP_P (prev)
7872 || CALL_P (prev) /* Could be a noreturn call. */
7873 || (NONJUMP_INSN_P (prev)
7874 && GET_CODE (PATTERN (prev)) == SEQUENCE))))
7875 ? len + 4 : len);
7876 }
7877
7878 /* Check for return with but one preceding insn since function
7879 start / call. */
7880 if (TARGET_PAD_RETURN
7881 && JUMP_P (insn)
7882 && GET_CODE (PATTERN (insn)) != ADDR_VEC
7883 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
7884 && get_attr_type (insn) == TYPE_RETURN)
7885 {
84034c69 7886 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
7887
7888 if (!prev || !(prev = prev_active_insn (prev))
7889 || ((NONJUMP_INSN_P (prev)
7890 && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
7891 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
7892 NON_SIBCALL)
526b7aee
SV
7893 : CALL_ATTR (prev, NON_SIBCALL)))
7894 return len + 4;
7895 }
7896 if (TARGET_ARC600)
7897 {
b3458f61 7898 rtx_insn *succ = next_real_insn (insn);
526b7aee
SV
7899
7900 /* One the ARC600, a write to an extension register must be separated
7901 from a read. */
7902 if (succ && INSN_P (succ))
7903 len += arc600_corereg_hazard (insn, succ);
7904 }
7905
7906 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
7907 can go awry. */
7908 extract_constrain_insn_cached (insn);
7909
7910 return len;
7911}
7912
7913/* Values for length_sensitive. */
7914enum
7915{
7916 ARC_LS_NONE,// Jcc
7917 ARC_LS_25, // 25 bit offset, B
7918 ARC_LS_21, // 21 bit offset, Bcc
7919 ARC_LS_U13,// 13 bit unsigned offset, LP
7920 ARC_LS_10, // 10 bit offset, B_s, Beq_s, Bne_s
7921 ARC_LS_9, // 9 bit offset, BRcc
7922 ARC_LS_8, // 8 bit offset, BRcc_s
7923 ARC_LS_U7, // 7 bit unsigned offset, LPcc
7924 ARC_LS_7 // 7 bit offset, Bcc_s
7925};
7926
7927/* While the infrastructure patch is waiting for review, duplicate the
7928 struct definitions, to allow this file to compile. */
7929#if 1
7930typedef struct
7931{
7932 unsigned align_set;
7933 /* Cost as a branch / call target or call return address. */
7934 int target_cost;
7935 int fallthrough_cost;
7936 int branch_cost;
7937 int length;
7938 /* 0 for not length sensitive, 1 for largest offset range,
7939 * 2 for next smaller etc. */
7940 unsigned length_sensitive : 8;
7941 bool enabled;
7942} insn_length_variant_t;
7943
7944typedef struct insn_length_parameters_s
7945{
7946 int align_unit_log;
7947 int align_base_log;
7948 int max_variants;
647d790d 7949 int (*get_variants) (rtx_insn *, int, bool, bool, insn_length_variant_t *);
526b7aee
SV
7950} insn_length_parameters_t;
7951
7952static void
7953arc_insn_length_parameters (insn_length_parameters_t *ilp) ATTRIBUTE_UNUSED;
7954#endif
7955
7956static int
647d790d 7957arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
526b7aee
SV
7958 insn_length_variant_t *ilv)
7959{
7960 if (!NONDEBUG_INSN_P (insn))
7961 return 0;
7962 enum attr_type type;
7963 /* shorten_branches doesn't take optimize_size into account yet for the
7964 get_variants mechanism, so turn this off for now. */
7965 if (optimize_size)
7966 return 0;
647d790d 7967 if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
526b7aee
SV
7968 {
7969 /* The interaction of a short delay slot insn with a short branch is
7970 too weird for shorten_branches to piece together, so describe the
7971 entire SEQUENCE. */
647d790d 7972 rtx_insn *inner;
526b7aee 7973 if (TARGET_UPSIZE_DBR
84034c69 7974 && get_attr_length (pat->insn (1)) <= 2
647d790d 7975 && (((type = get_attr_type (inner = pat->insn (0)))
526b7aee
SV
7976 == TYPE_UNCOND_BRANCH)
7977 || type == TYPE_BRANCH)
7978 && get_attr_delay_slot_filled (inner) == DELAY_SLOT_FILLED_YES)
7979 {
7980 int n_variants
7981 = arc_get_insn_variants (inner, get_attr_length (inner), true,
7982 target_p, ilv+1);
7983 /* The short variant gets split into a higher-cost aligned
7984 and a lower cost unaligned variant. */
7985 gcc_assert (n_variants);
7986 gcc_assert (ilv[1].length_sensitive == ARC_LS_7
7987 || ilv[1].length_sensitive == ARC_LS_10);
7988 gcc_assert (ilv[1].align_set == 3);
7989 ilv[0] = ilv[1];
7990 ilv[0].align_set = 1;
7991 ilv[0].branch_cost += 1;
7992 ilv[1].align_set = 2;
7993 n_variants++;
7994 for (int i = 0; i < n_variants; i++)
7995 ilv[i].length += 2;
7996 /* In case an instruction with aligned size is wanted, and
7997 the short variants are unavailable / too expensive, add
7998 versions of long branch + long delay slot. */
7999 for (int i = 2, end = n_variants; i < end; i++, n_variants++)
8000 {
8001 ilv[n_variants] = ilv[i];
8002 ilv[n_variants].length += 2;
8003 }
8004 return n_variants;
8005 }
8006 return 0;
8007 }
8008 insn_length_variant_t *first_ilv = ilv;
8009 type = get_attr_type (insn);
8010 bool delay_filled
8011 = (get_attr_delay_slot_filled (insn) == DELAY_SLOT_FILLED_YES);
8012 int branch_align_cost = delay_filled ? 0 : 1;
8013 int branch_unalign_cost = delay_filled ? 0 : TARGET_UNALIGN_BRANCH ? 0 : 1;
8014 /* If the previous instruction is an sfunc call, this insn is always
8015 a target, even though the middle-end is unaware of this. */
8016 bool force_target = false;
b3458f61 8017 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8018 if (prev && arc_next_active_insn (prev, 0) == insn
8019 && ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8020 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8021 NON_SIBCALL)
526b7aee
SV
8022 : (CALL_ATTR (prev, NON_SIBCALL)
8023 && NEXT_INSN (PREV_INSN (prev)) == prev)))
8024 force_target = true;
8025
8026 switch (type)
8027 {
8028 case TYPE_BRCC:
8029 /* Short BRCC only comes in no-delay-slot version, and without limm */
8030 if (!delay_filled)
8031 {
8032 ilv->align_set = 3;
8033 ilv->length = 2;
8034 ilv->branch_cost = 1;
8035 ilv->enabled = (len == 2);
8036 ilv->length_sensitive = ARC_LS_8;
8037 ilv++;
8038 }
8039 /* Fall through. */
8040 case TYPE_BRCC_NO_DELAY_SLOT:
8041 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8042 (delay slot) scheduling purposes, but they are longer. */
8043 if (GET_CODE (PATTERN (insn)) == PARALLEL
8044 && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET)
8045 return 0;
8046 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8047 ilv->length = ((type == TYPE_BRCC) ? 4 : 8);
8048 ilv->align_set = 3;
8049 ilv->branch_cost = branch_align_cost;
8050 ilv->enabled = (len <= ilv->length);
8051 ilv->length_sensitive = ARC_LS_9;
8052 if ((target_p || force_target)
8053 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8054 {
8055 ilv[1] = *ilv;
8056 ilv->align_set = 1;
8057 ilv++;
8058 ilv->align_set = 2;
8059 ilv->target_cost = 1;
8060 ilv->branch_cost = branch_unalign_cost;
8061 }
8062 ilv++;
8063
8064 rtx op, op0;
8065 op = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
8066 op0 = XEXP (op, 0);
8067
8068 if (GET_CODE (op0) == ZERO_EXTRACT
8069 && satisfies_constraint_L (XEXP (op0, 2)))
8070 op0 = XEXP (op0, 0);
8071 if (satisfies_constraint_Rcq (op0))
8072 {
8073 ilv->length = ((type == TYPE_BRCC) ? 6 : 10);
8074 ilv->align_set = 3;
8075 ilv->branch_cost = 1 + branch_align_cost;
8076 ilv->fallthrough_cost = 1;
8077 ilv->enabled = true;
8078 ilv->length_sensitive = ARC_LS_21;
8079 if (!delay_filled && TARGET_UNALIGN_BRANCH)
8080 {
8081 ilv[1] = *ilv;
8082 ilv->align_set = 1;
8083 ilv++;
8084 ilv->align_set = 2;
8085 ilv->branch_cost = 1 + branch_unalign_cost;
8086 }
8087 ilv++;
8088 }
8089 ilv->length = ((type == TYPE_BRCC) ? 8 : 12);
8090 ilv->align_set = 3;
8091 ilv->branch_cost = 1 + branch_align_cost;
8092 ilv->fallthrough_cost = 1;
8093 ilv->enabled = true;
8094 ilv->length_sensitive = ARC_LS_21;
8095 if ((target_p || force_target)
8096 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8097 {
8098 ilv[1] = *ilv;
8099 ilv->align_set = 1;
8100 ilv++;
8101 ilv->align_set = 2;
8102 ilv->target_cost = 1;
8103 ilv->branch_cost = 1 + branch_unalign_cost;
8104 }
8105 ilv++;
8106 break;
8107
8108 case TYPE_SFUNC:
8109 ilv->length = 12;
8110 goto do_call;
8111 case TYPE_CALL_NO_DELAY_SLOT:
8112 ilv->length = 8;
8113 goto do_call;
8114 case TYPE_CALL:
8115 ilv->length = 4;
8116 ilv->length_sensitive
8117 = GET_CODE (PATTERN (insn)) == COND_EXEC ? ARC_LS_21 : ARC_LS_25;
8118 do_call:
8119 ilv->align_set = 3;
8120 ilv->fallthrough_cost = branch_align_cost;
8121 ilv->enabled = true;
8122 if ((target_p || force_target)
8123 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8124 {
8125 ilv[1] = *ilv;
8126 ilv->align_set = 1;
8127 ilv++;
8128 ilv->align_set = 2;
8129 ilv->target_cost = 1;
8130 ilv->fallthrough_cost = branch_unalign_cost;
8131 }
8132 ilv++;
8133 break;
8134 case TYPE_UNCOND_BRANCH:
8135 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8136 but that makes no difference at the moment. */
8137 ilv->length_sensitive = ARC_LS_7;
8138 ilv[1].length_sensitive = ARC_LS_25;
8139 goto do_branch;
8140 case TYPE_BRANCH:
8141 ilv->length_sensitive = ARC_LS_10;
8142 ilv[1].length_sensitive = ARC_LS_21;
8143 do_branch:
8144 ilv->align_set = 3;
8145 ilv->length = 2;
8146 ilv->branch_cost = branch_align_cost;
8147 ilv->enabled = (len == ilv->length);
8148 ilv++;
8149 ilv->length = 4;
8150 ilv->align_set = 3;
8151 ilv->branch_cost = branch_align_cost;
8152 ilv->enabled = true;
8153 if ((target_p || force_target)
8154 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8155 {
8156 ilv[1] = *ilv;
8157 ilv->align_set = 1;
8158 ilv++;
8159 ilv->align_set = 2;
8160 ilv->target_cost = 1;
8161 ilv->branch_cost = branch_unalign_cost;
8162 }
8163 ilv++;
8164 break;
8165 case TYPE_JUMP:
8166 return 0;
8167 default:
8168 /* For every short insn, there is generally also a long insn.
8169 trap_s is an exception. */
8170 if ((len & 2) == 0 || recog_memoized (insn) == CODE_FOR_trap_s)
8171 return 0;
8172 ilv->align_set = 3;
8173 ilv->length = len;
8174 ilv->enabled = 1;
8175 ilv++;
8176 ilv->align_set = 3;
8177 ilv->length = len + 2;
8178 ilv->enabled = 1;
8179 if (target_p || force_target)
8180 {
8181 ilv[1] = *ilv;
8182 ilv->align_set = 1;
8183 ilv++;
8184 ilv->align_set = 2;
8185 ilv->target_cost = 1;
8186 }
8187 ilv++;
8188 }
8189 /* If the previous instruction is an sfunc call, this insn is always
8190 a target, even though the middle-end is unaware of this.
8191 Therefore, if we have a call predecessor, transfer the target cost
8192 to the fallthrough and branch costs. */
8193 if (force_target)
8194 {
8195 for (insn_length_variant_t *p = first_ilv; p < ilv; p++)
8196 {
8197 p->fallthrough_cost += p->target_cost;
8198 p->branch_cost += p->target_cost;
8199 p->target_cost = 0;
8200 }
8201 }
8202
8203 return ilv - first_ilv;
8204}
8205
8206static void
8207arc_insn_length_parameters (insn_length_parameters_t *ilp)
8208{
8209 ilp->align_unit_log = 1;
8210 ilp->align_base_log = 1;
8211 ilp->max_variants = 7;
8212 ilp->get_variants = arc_get_insn_variants;
8213}
8214
8215/* Return a copy of COND from *STATEP, inverted if that is indicated by the
8216 CC field of *STATEP. */
8217
8218static rtx
8219arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8220{
8221 rtx cond = statep->cond;
8222 int raw_cc = get_arc_condition_code (cond);
8223 if (reverse)
8224 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8225
8226 if (statep->cc == raw_cc)
8227 return copy_rtx (cond);
8228
8229 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8230
ef4bddc2 8231 machine_mode ccm = GET_MODE (XEXP (cond, 0));
526b7aee
SV
8232 enum rtx_code code = reverse_condition (GET_CODE (cond));
8233 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8234 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8235
8236 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8237 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8238}
8239
bae56bbb
JR
8240/* Return version of PAT conditionalized with COND, which is part of INSN.
8241 ANNULLED indicates if INSN is an annulled delay-slot insn.
8242 Register further changes if necessary. */
8243static rtx
8244conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8245{
8246 /* For commutative operators, we generally prefer to have
8247 the first source match the destination. */
8248 if (GET_CODE (pat) == SET)
8249 {
8250 rtx src = SET_SRC (pat);
8251
8252 if (COMMUTATIVE_P (src))
8253 {
8254 rtx src0 = XEXP (src, 0);
8255 rtx src1 = XEXP (src, 1);
8256 rtx dst = SET_DEST (pat);
8257
8258 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8259 /* Leave add_n alone - the canonical form is to
8260 have the complex summand first. */
8261 && REG_P (src0))
f7df4a84 8262 pat = gen_rtx_SET (dst,
bae56bbb
JR
8263 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8264 src1, src0));
8265 }
8266 }
8267
8268 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8269 what to do with COND_EXEC. */
8270 if (RTX_FRAME_RELATED_P (insn))
8271 {
8272 /* If this is the delay slot insn of an anulled branch,
8273 dwarf2out.c:scan_trace understands the anulling semantics
8274 without the COND_EXEC. */
8275 gcc_assert (annulled);
8276 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8277 REG_NOTES (insn));
8278 validate_change (insn, &REG_NOTES (insn), note, 1);
8279 }
8280 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8281 return pat;
8282}
8283
526b7aee
SV
8284/* Use the ccfsm machinery to do if conversion. */
8285
8286static unsigned
8287arc_ifcvt (void)
8288{
8289 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8290 basic_block merge_bb = 0;
8291
8292 memset (statep, 0, sizeof *statep);
b3458f61 8293 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
526b7aee
SV
8294 {
8295 arc_ccfsm_advance (insn, statep);
8296
8297 switch (statep->state)
8298 {
8299 case 0:
8300 if (JUMP_P (insn))
8301 merge_bb = 0;
8302 break;
8303 case 1: case 2:
8304 {
8305 /* Deleted branch. */
8306 gcc_assert (!merge_bb);
8307 merge_bb = BLOCK_FOR_INSN (insn);
8308 basic_block succ_bb
8309 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn))));
8310 arc_ccfsm_post_advance (insn, statep);
53ea364f 8311 gcc_assert (!IN_RANGE (statep->state, 1, 2));
b3458f61 8312 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
526b7aee
SV
8313 if (seq != insn)
8314 {
8315 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8316 rtx pat = PATTERN (slot);
8317 if (INSN_ANNULLED_BRANCH_P (insn))
8318 {
8319 rtx cond
8320 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8321 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8322 }
8323 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8324 gcc_unreachable ();
8325 PUT_CODE (slot, NOTE);
8326 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8327 if (merge_bb && succ_bb)
8328 merge_blocks (merge_bb, succ_bb);
8329 }
8330 else if (merge_bb && succ_bb)
8331 {
8332 set_insn_deleted (insn);
8333 merge_blocks (merge_bb, succ_bb);
8334 }
8335 else
8336 {
8337 PUT_CODE (insn, NOTE);
8338 NOTE_KIND (insn) = NOTE_INSN_DELETED;
8339 }
8340 continue;
8341 }
8342 case 3:
8343 if (LABEL_P (insn)
8344 && statep->target_label == CODE_LABEL_NUMBER (insn))
8345 {
8346 arc_ccfsm_post_advance (insn, statep);
8347 basic_block succ_bb = BLOCK_FOR_INSN (insn);
8348 if (merge_bb && succ_bb)
8349 merge_blocks (merge_bb, succ_bb);
8350 else if (--LABEL_NUSES (insn) == 0)
8351 {
8352 const char *name = LABEL_NAME (insn);
8353 PUT_CODE (insn, NOTE);
8354 NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
8355 NOTE_DELETED_LABEL_NAME (insn) = name;
8356 }
8357 merge_bb = 0;
8358 continue;
8359 }
8360 /* Fall through. */
8361 case 4: case 5:
8362 if (!NONDEBUG_INSN_P (insn))
8363 break;
8364
8365 /* Conditionalized insn. */
8366
b3458f61
DM
8367 rtx_insn *prev, *pprev;
8368 rtx *patp, pat, cond;
bae56bbb 8369 bool annulled; annulled = false;
526b7aee
SV
8370
8371 /* If this is a delay slot insn in a non-annulled branch,
8372 don't conditionalize it. N.B., this should be fine for
8373 conditional return too. However, don't do this for
8374 unconditional branches, as these would be encountered when
8375 processing an 'else' part. */
8376 prev = PREV_INSN (insn);
8377 pprev = PREV_INSN (prev);
8378 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
bae56bbb
JR
8379 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8380 {
8381 if (!INSN_ANNULLED_BRANCH_P (prev))
8382 break;
8383 annulled = true;
8384 }
526b7aee
SV
8385
8386 patp = &PATTERN (insn);
8387 pat = *patp;
8388 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
8389 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
8390 {
8391 /* ??? don't conditionalize if all side effects are dead
8392 in the not-execute case. */
9bf218f9 8393
bae56bbb 8394 pat = conditionalize_nonjump (pat, cond, insn, annulled);
526b7aee
SV
8395 }
8396 else if (simplejump_p (insn))
8397 {
8398 patp = &SET_SRC (pat);
8399 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
8400 }
8401 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
8402 {
8403 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
f7df4a84 8404 pat = gen_rtx_SET (pc_rtx, pat);
526b7aee
SV
8405 }
8406 else
8407 gcc_unreachable ();
8408 validate_change (insn, patp, pat, 1);
8409 if (!apply_change_group ())
8410 gcc_unreachable ();
8411 if (JUMP_P (insn))
8412 {
b3458f61 8413 rtx_insn *next = next_nonnote_insn (insn);
526b7aee
SV
8414 if (GET_CODE (next) == BARRIER)
8415 delete_insn (next);
8416 if (statep->state == 3)
8417 continue;
8418 }
8419 break;
8420 default:
8421 gcc_unreachable ();
8422 }
8423 arc_ccfsm_post_advance (insn, statep);
8424 }
8425 return 0;
8426}
8427
0bc69b81
JR
8428/* Find annulled delay insns and convert them to use the appropriate predicate.
8429 This allows branch shortening to size up these insns properly. */
8430
8431static unsigned
8432arc_predicate_delay_insns (void)
8433{
b3458f61 8434 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
0bc69b81
JR
8435 {
8436 rtx pat, jump, dlay, src, cond, *patp;
8437 int reverse;
8438
8439 if (!NONJUMP_INSN_P (insn)
8440 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
8441 continue;
8442 jump = XVECEXP (pat, 0, 0);
8443 dlay = XVECEXP (pat, 0, 1);
8444 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
8445 continue;
8446 /* If the branch insn does the annulling, leave the delay insn alone. */
8447 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
8448 continue;
8449 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8450 on the other path. */
8451 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
8452 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
8453 src = SET_SRC (PATTERN (jump));
8454 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
8455 cond = XEXP (src, 0);
8456 if (XEXP (src, 2) == pc_rtx)
8457 reverse = 0;
8458 else if (XEXP (src, 1) == pc_rtx)
8459 reverse = 1;
8460 else
8461 gcc_unreachable ();
9af539fe 8462 if (reverse != !INSN_FROM_TARGET_P (dlay))
0bc69b81 8463 {
ef4bddc2 8464 machine_mode ccm = GET_MODE (XEXP (cond, 0));
0bc69b81
JR
8465 enum rtx_code code = reverse_condition (GET_CODE (cond));
8466 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8467 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8468
8469 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
8470 copy_rtx (XEXP (cond, 0)),
8471 copy_rtx (XEXP (cond, 1)));
8472 }
8473 else
8474 cond = copy_rtx (cond);
8475 patp = &PATTERN (dlay);
8476 pat = *patp;
eeac7d15 8477 pat = conditionalize_nonjump (pat, cond, dlay, true);
0bc69b81
JR
8478 validate_change (dlay, patp, pat, 1);
8479 if (!apply_change_group ())
8480 gcc_unreachable ();
8481 }
8482 return 0;
8483}
8484
526b7aee
SV
8485/* For ARC600: If a write to a core reg >=32 appears in a delay slot
8486 (other than of a forward brcc), it creates a hazard when there is a read
8487 of the same register at the branch target. We can't know what is at the
8488 branch target of calls, and for branches, we don't really know before the
8489 end of delay slot scheduling, either. Not only can individual instruction
8490 be hoisted out into a delay slot, a basic block can also be emptied this
8491 way, and branch and/or fall through targets be redirected. Hence we don't
8492 want such writes in a delay slot. */
526b7aee
SV
8493
8494/* Return nonzreo iff INSN writes to an extension core register. */
8495
8496int
8497arc_write_ext_corereg (rtx insn)
8498{
24dbe738
RS
8499 subrtx_iterator::array_type array;
8500 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
8501 {
8502 const_rtx x = *iter;
8503 switch (GET_CODE (x))
8504 {
8505 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8506 break;
8507 default:
8508 /* This is also fine for PRE/POST_MODIFY, because they
8509 contain a SET. */
8510 continue;
8511 }
8512 const_rtx dest = XEXP (x, 0);
8513 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
8514 return 1;
8515 }
8516 return 0;
526b7aee
SV
8517}
8518
8519/* This is like the hook, but returns NULL when it can't / won't generate
8520 a legitimate address. */
8521
8522static rtx
8523arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 8524 machine_mode mode)
526b7aee
SV
8525{
8526 rtx addr, inner;
8527
8528 if (flag_pic && SYMBOLIC_CONST (x))
8529 (x) = arc_legitimize_pic_address (x, 0);
8530 addr = x;
8531 if (GET_CODE (addr) == CONST)
8532 addr = XEXP (addr, 0);
8533 if (GET_CODE (addr) == PLUS
8534 && CONST_INT_P (XEXP (addr, 1))
8535 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
8536 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
8537 || (REG_P (XEXP (addr, 0))
8538 && (INTVAL (XEXP (addr, 1)) & 252))))
8539 {
8540 HOST_WIDE_INT offs, upper;
8541 int size = GET_MODE_SIZE (mode);
8542
8543 offs = INTVAL (XEXP (addr, 1));
8544 upper = (offs + 256 * size) & ~511 * size;
8545 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
8546#if 0 /* ??? this produces worse code for EEMBC idctrn01 */
8547 if (GET_CODE (x) == CONST)
8548 inner = gen_rtx_CONST (Pmode, inner);
8549#endif
8550 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
8551 x = addr;
8552 }
8553 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
8554 x = force_reg (Pmode, x);
ef4bddc2 8555 if (memory_address_p ((machine_mode) mode, x))
526b7aee
SV
8556 return x;
8557 return NULL_RTX;
8558}
8559
8560static rtx
ef4bddc2 8561arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
526b7aee 8562{
28633bbd
CZ
8563 if (GET_CODE (orig_x) == SYMBOL_REF)
8564 {
8565 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
8566 if (model != 0)
8567 return arc_legitimize_tls_address (orig_x, model);
8568 }
8569
526b7aee
SV
8570 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
8571
8572 if (new_x)
8573 return new_x;
8574 return orig_x;
8575}
8576
8577static rtx
8578arc_delegitimize_address_0 (rtx x)
8579{
8580 rtx u, gp;
8581
8582 if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
8583 {
8584 if (XINT (u, 1) == ARC_UNSPEC_GOT)
8585 return XVECEXP (u, 0, 0);
8586 }
8587 else if (GET_CODE (x) == PLUS
8588 && ((REG_P (gp = XEXP (x, 0))
8589 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8590 || (GET_CODE (gp) == CONST
8591 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8592 && XINT (u, 1) == ARC_UNSPEC_GOT
8593 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8594 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8595 && GET_CODE (XEXP (x, 1)) == CONST
8596 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8597 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8598 return XVECEXP (u, 0, 0);
8599 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
8600 && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
8601 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8602 || (GET_CODE (gp) == CONST
8603 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8604 && XINT (u, 1) == ARC_UNSPEC_GOT
8605 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8606 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8607 && GET_CODE (XEXP (x, 1)) == CONST
8608 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8609 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8610 return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
8611 XVECEXP (u, 0, 0));
8612 else if (GET_CODE (x) == PLUS
8613 && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
8614 return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
8615 return NULL_RTX;
8616}
8617
8618static rtx
8619arc_delegitimize_address (rtx x)
8620{
8621 rtx orig_x = x = delegitimize_mem_from_attrs (x);
8622 if (GET_CODE (x) == MEM)
8623 x = XEXP (x, 0);
8624 x = arc_delegitimize_address_0 (x);
8625 if (x)
8626 {
8627 if (MEM_P (orig_x))
8628 x = replace_equiv_address_nv (orig_x, x);
8629 return x;
8630 }
8631 return orig_x;
8632}
8633
8634/* Return a REG rtx for acc1. N.B. the gcc-internal representation may
8635 differ from the hardware register number in order to allow the generic
8636 code to correctly split the concatenation of acc1 and acc2. */
8637
8638rtx
8639gen_acc1 (void)
8640{
8641 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
8642}
8643
8644/* Return a REG rtx for acc2. N.B. the gcc-internal representation may
8645 differ from the hardware register number in order to allow the generic
8646 code to correctly split the concatenation of acc1 and acc2. */
8647
8648rtx
8649gen_acc2 (void)
8650{
8651 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
8652}
8653
8654/* Return a REG rtx for mlo. N.B. the gcc-internal representation may
8655 differ from the hardware register number in order to allow the generic
8656 code to correctly split the concatenation of mhi and mlo. */
8657
8658rtx
8659gen_mlo (void)
8660{
8661 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
8662}
8663
8664/* Return a REG rtx for mhi. N.B. the gcc-internal representation may
8665 differ from the hardware register number in order to allow the generic
8666 code to correctly split the concatenation of mhi and mlo. */
8667
8668rtx
8669gen_mhi (void)
8670{
8671 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
8672}
8673
8674/* FIXME: a parameter should be added, and code added to final.c,
8675 to reproduce this functionality in shorten_branches. */
8676#if 0
8677/* Return nonzero iff BRANCH should be unaligned if possible by upsizing
8678 a previous instruction. */
8679int
8680arc_unalign_branch_p (rtx branch)
8681{
8682 rtx note;
8683
8684 if (!TARGET_UNALIGN_BRANCH)
8685 return 0;
8686 /* Do not do this if we have a filled delay slot. */
8687 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
4654c0cf 8688 && !NEXT_INSN (branch)->deleted ())
526b7aee
SV
8689 return 0;
8690 note = find_reg_note (branch, REG_BR_PROB, 0);
8691 return (!note
8692 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
8693 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
8694}
8695#endif
8696
8697/* When estimating sizes during arc_reorg, when optimizing for speed, there
8698 are three reasons why we need to consider branches to be length 6:
8699 - annull-false delay slot insns are implemented using conditional execution,
8700 thus preventing short insn formation where used.
8701 - for ARC600: annul-true delay slot insns are implemented where possible
8702 using conditional execution, preventing short insn formation where used.
8703 - for ARC700: likely or somewhat likely taken branches are made long and
8704 unaligned if possible to avoid branch penalty. */
8705
8706bool
8707arc_branch_size_unknown_p (void)
8708{
8709 return !optimize_size && arc_reorg_in_progress;
8710}
8711
8712/* We are about to output a return insn. Add padding if necessary to avoid
8713 a mispredict. A return could happen immediately after the function
8714 start, but after a call we know that there will be at least a blink
8715 restore. */
8716
8717void
8718arc_pad_return (void)
8719{
fa7af581 8720 rtx_insn *insn = current_output_insn;
b3458f61 8721 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8722 int want_long;
8723
8724 if (!prev)
8725 {
8726 fputs ("\tnop_s\n", asm_out_file);
8727 cfun->machine->unalign ^= 2;
8728 want_long = 1;
8729 }
8730 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
8731 because after a call, we'd have to restore blink first. */
8732 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
8733 return;
8734 else
8735 {
8736 want_long = (get_attr_length (prev) == 2);
8737 prev = prev_active_insn (prev);
8738 }
8739 if (!prev
8740 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8741 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8742 NON_SIBCALL)
526b7aee
SV
8743 : CALL_ATTR (prev, NON_SIBCALL)))
8744 {
8745 if (want_long)
8746 cfun->machine->size_reason
8747 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
8748 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
8749 {
8750 cfun->machine->size_reason
8751 = "Long unaligned jump avoids non-delay slot penalty";
8752 want_long = 1;
8753 }
8754 /* Disgorge delay insn, if there is any, and it may be moved. */
8755 if (final_sequence
8756 /* ??? Annulled would be OK if we can and do conditionalize
8757 the delay slot insn accordingly. */
8758 && !INSN_ANNULLED_BRANCH_P (insn)
8759 && (get_attr_cond (insn) != COND_USE
8760 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
8761 XVECEXP (final_sequence, 0, 1))))
8762 {
b3458f61 8763 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
526b7aee
SV
8764 gcc_assert (!prev_real_insn (insn)
8765 || !arc_hazard (prev_real_insn (insn), prev));
8766 cfun->machine->force_short_suffix = !want_long;
8767 rtx save_pred = current_insn_predicate;
8768 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
8769 cfun->machine->force_short_suffix = -1;
4654c0cf 8770 prev->set_deleted ();
526b7aee
SV
8771 current_output_insn = insn;
8772 current_insn_predicate = save_pred;
8773 }
8774 else if (want_long)
8775 fputs ("\tnop\n", asm_out_file);
8776 else
8777 {
8778 fputs ("\tnop_s\n", asm_out_file);
8779 cfun->machine->unalign ^= 2;
8780 }
8781 }
8782 return;
8783}
8784
8785/* The usual; we set up our machine_function data. */
8786
8787static struct machine_function *
8788arc_init_machine_status (void)
8789{
8790 struct machine_function *machine;
766090c2 8791 machine = ggc_cleared_alloc<machine_function> ();
526b7aee
SV
8792 machine->fn_type = ARC_FUNCTION_UNKNOWN;
8793 machine->force_short_suffix = -1;
8794
8795 return machine;
8796}
8797
8798/* Implements INIT_EXPANDERS. We just set up to call the above
8799 function. */
8800
8801void
8802arc_init_expanders (void)
8803{
8804 init_machine_status = arc_init_machine_status;
8805}
8806
8807/* Check if OP is a proper parallel of a millicode call pattern. OFFSET
8808 indicates a number of elements to ignore - that allows to have a
8809 sibcall pattern that starts with (return). LOAD_P is zero for store
8810 multiple (for prologues), and one for load multiples (for epilogues),
8811 and two for load multiples where no final clobber of blink is required.
8812 We also skip the first load / store element since this is supposed to
8813 be checked in the instruction pattern. */
8814
8815int
8816arc_check_millicode (rtx op, int offset, int load_p)
8817{
8818 int len = XVECLEN (op, 0) - offset;
8819 int i;
8820
8821 if (load_p == 2)
8822 {
8823 if (len < 2 || len > 13)
8824 return 0;
8825 load_p = 1;
8826 }
8827 else
8828 {
8829 rtx elt = XVECEXP (op, 0, --len);
8830
8831 if (GET_CODE (elt) != CLOBBER
8832 || !REG_P (XEXP (elt, 0))
8833 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
8834 || len < 3 || len > 13)
8835 return 0;
8836 }
8837 for (i = 1; i < len; i++)
8838 {
8839 rtx elt = XVECEXP (op, 0, i + offset);
8840 rtx reg, mem, addr;
8841
8842 if (GET_CODE (elt) != SET)
8843 return 0;
8844 mem = XEXP (elt, load_p);
8845 reg = XEXP (elt, 1-load_p);
8846 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
8847 return 0;
8848 addr = XEXP (mem, 0);
8849 if (GET_CODE (addr) != PLUS
8850 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
8851 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
8852 return 0;
8853 }
8854 return 1;
8855}
8856
8857/* Accessor functions for cfun->machine->unalign. */
8858
8859int
8860arc_get_unalign (void)
8861{
8862 return cfun->machine->unalign;
8863}
8864
8865void
8866arc_clear_unalign (void)
8867{
8868 if (cfun)
8869 cfun->machine->unalign = 0;
8870}
8871
8872void
8873arc_toggle_unalign (void)
8874{
8875 cfun->machine->unalign ^= 2;
8876}
8877
8878/* Operands 0..2 are the operands of a addsi which uses a 12 bit
8879 constant in operand 2, but which would require a LIMM because of
8880 operand mismatch.
8881 operands 3 and 4 are new SET_SRCs for operands 0. */
8882
8883void
8884split_addsi (rtx *operands)
8885{
8886 int val = INTVAL (operands[2]);
8887
8888 /* Try for two short insns first. Lengths being equal, we prefer
8889 expansions with shorter register lifetimes. */
8890 if (val > 127 && val <= 255
8891 && satisfies_constraint_Rcq (operands[0]))
8892 {
8893 operands[3] = operands[2];
8894 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8895 }
8896 else
8897 {
8898 operands[3] = operands[1];
8899 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
8900 }
8901}
8902
8903/* Operands 0..2 are the operands of a subsi which uses a 12 bit
8904 constant in operand 1, but which would require a LIMM because of
8905 operand mismatch.
8906 operands 3 and 4 are new SET_SRCs for operands 0. */
8907
8908void
8909split_subsi (rtx *operands)
8910{
8911 int val = INTVAL (operands[1]);
8912
8913 /* Try for two short insns first. Lengths being equal, we prefer
8914 expansions with shorter register lifetimes. */
8915 if (satisfies_constraint_Rcq (operands[0])
8916 && satisfies_constraint_Rcq (operands[2]))
8917 {
8918 if (val >= -31 && val <= 127)
8919 {
8920 operands[3] = gen_rtx_NEG (SImode, operands[2]);
8921 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8922 return;
8923 }
8924 else if (val >= 0 && val < 255)
8925 {
8926 operands[3] = operands[1];
8927 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
8928 return;
8929 }
8930 }
8931 /* If the destination is not an ARCompact16 register, we might
8932 still have a chance to make a short insn if the source is;
8933 we need to start with a reg-reg move for this. */
8934 operands[3] = operands[2];
8935 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
8936}
8937
8938/* Handle DOUBLE_REGS uses.
8939 Operand 0: destination register
8940 Operand 1: source register */
8941
d34a0fdc 8942static bool
526b7aee
SV
8943arc_process_double_reg_moves (rtx *operands)
8944{
8945 rtx dest = operands[0];
8946 rtx src = operands[1];
526b7aee
SV
8947
8948 enum usesDxState { none, srcDx, destDx, maxDx };
8949 enum usesDxState state = none;
8950
8951 if (refers_to_regno_p (40, 44, src, 0))
8952 state = srcDx;
8953 if (refers_to_regno_p (40, 44, dest, 0))
8954 {
8955 /* Via arc_register_move_cost, we should never see D,D moves. */
8956 gcc_assert (state == none);
8957 state = destDx;
8958 }
8959
8960 if (state == none)
d34a0fdc 8961 return false;
526b7aee
SV
8962
8963 if (state == srcDx)
8964 {
8965 /* Without the LR insn, we need to split this into a
8966 sequence of insns which will use the DEXCLx and DADDHxy
8967 insns to be able to read the Dx register in question. */
8968 if (TARGET_DPFP_DISABLE_LRSR)
8969 {
8970 /* gen *movdf_insn_nolrsr */
f7df4a84 8971 rtx set = gen_rtx_SET (dest, src);
526b7aee
SV
8972 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
8973 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
8974 }
8975 else
8976 {
8977 /* When we have 'mov D, r' or 'mov D, D' then get the target
8978 register pair for use with LR insn. */
7d81a567
CZ
8979 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
8980 TARGET_BIG_ENDIAN ? 0 : 4);
8981 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
8982 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee
SV
8983
8984 /* Produce the two LR insns to get the high and low parts. */
f7df4a84 8985 emit_insn (gen_rtx_SET (destHigh,
c69899f0
CZ
8986 gen_rtx_UNSPEC_VOLATILE (Pmode,
8987 gen_rtvec (1, src),
8988 VUNSPEC_ARC_LR_HIGH)));
f7df4a84 8989 emit_insn (gen_rtx_SET (destLow,
c69899f0
CZ
8990 gen_rtx_UNSPEC_VOLATILE (Pmode,
8991 gen_rtvec (1, src),
8992 VUNSPEC_ARC_LR)));
526b7aee
SV
8993 }
8994 }
8995 else if (state == destDx)
8996 {
8997 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
8998 LR insn get the target register pair. */
7d81a567
CZ
8999 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9000 TARGET_BIG_ENDIAN ? 0 : 4);
9001 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9002 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee
SV
9003
9004 emit_insn (gen_rtx_UNSPEC_VOLATILE (Pmode,
9005 gen_rtvec (3, dest, srcHigh, srcLow),
c69899f0 9006 VUNSPEC_ARC_DEXCL_NORES));
526b7aee
SV
9007
9008 }
9009 else
9010 gcc_unreachable ();
9011
d34a0fdc 9012 return true;
526b7aee
SV
9013}
9014
9015/* operands 0..1 are the operands of a 64 bit move instruction.
9016 split it into two moves with operands 2/3 and 4/5. */
9017
d34a0fdc 9018void
526b7aee
SV
9019arc_split_move (rtx *operands)
9020{
ef4bddc2 9021 machine_mode mode = GET_MODE (operands[0]);
526b7aee
SV
9022 int i;
9023 int swap = 0;
9024 rtx xop[4];
526b7aee
SV
9025
9026 if (TARGET_DPFP)
9027 {
d34a0fdc
CZ
9028 if (arc_process_double_reg_moves (operands))
9029 return;
526b7aee
SV
9030 }
9031
d34a0fdc
CZ
9032 if (TARGET_LL64
9033 && ((memory_operand (operands[0], mode)
9034 && even_register_operand (operands[1], mode))
9035 || (memory_operand (operands[1], mode)
9036 && even_register_operand (operands[0], mode))))
9037 {
9038 emit_move_insn (operands[0], operands[1]);
9039 return;
9040 }
9041
00c072ae
CZ
9042 if (TARGET_PLUS_QMACW
9043 && GET_CODE (operands[1]) == CONST_VECTOR)
9044 {
9045 HOST_WIDE_INT intval0, intval1;
9046 if (GET_MODE (operands[1]) == V2SImode)
9047 {
9048 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9049 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9050 }
9051 else
9052 {
9053 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9054 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9055 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9056 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9057 }
9058 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9059 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9060 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9061 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9062 emit_move_insn (xop[0], xop[2]);
9063 emit_move_insn (xop[3], xop[1]);
9064 return;
9065 }
9066
526b7aee
SV
9067 for (i = 0; i < 2; i++)
9068 {
9069 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9070 {
9071 rtx addr = XEXP (operands[i], 0);
9072 rtx r, o;
9073 enum rtx_code code;
9074
9075 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9076 switch (GET_CODE (addr))
9077 {
9078 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9079 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9080 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9081 pre_modify:
9082 code = PRE_MODIFY;
9083 break;
9084 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9085 case POST_INC: o = GEN_INT (8); goto post_modify;
9086 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9087 post_modify:
9088 code = POST_MODIFY;
9089 swap = 2;
9090 break;
9091 default:
9092 gcc_unreachable ();
9093 }
9094 r = XEXP (addr, 0);
9095 xop[0+i] = adjust_automodify_address_nv
9096 (operands[i], SImode,
9097 gen_rtx_fmt_ee (code, Pmode, r,
9098 gen_rtx_PLUS (Pmode, r, o)),
9099 0);
9100 xop[2+i] = adjust_automodify_address_nv
9101 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9102 }
9103 else
9104 {
9105 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9106 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9107 }
9108 }
9109 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9110 {
9111 swap = 2;
9112 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9113 }
526b7aee 9114
d34a0fdc
CZ
9115 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9116 emit_move_insn (xop[2 - swap], xop[3 - swap]);
526b7aee 9117
526b7aee
SV
9118}
9119
9120/* Select between the instruction output templates s_tmpl (for short INSNs)
9121 and l_tmpl (for long INSNs). */
9122
9123const char *
b3458f61 9124arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
526b7aee
SV
9125{
9126 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9127
9128 extract_constrain_insn_cached (insn);
9129 return is_short ? s_tmpl : l_tmpl;
9130}
9131
9132/* Searches X for any reference to REGNO, returning the rtx of the
9133 reference found if any. Otherwise, returns NULL_RTX. */
9134
9135rtx
9136arc_regno_use_in (unsigned int regno, rtx x)
9137{
9138 const char *fmt;
9139 int i, j;
9140 rtx tem;
9141
c9bd6bcd 9142 if (REG_P (x) && refers_to_regno_p (regno, x))
526b7aee
SV
9143 return x;
9144
9145 fmt = GET_RTX_FORMAT (GET_CODE (x));
9146 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9147 {
9148 if (fmt[i] == 'e')
9149 {
9150 if ((tem = regno_use_in (regno, XEXP (x, i))))
9151 return tem;
9152 }
9153 else if (fmt[i] == 'E')
9154 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9155 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9156 return tem;
9157 }
9158
9159 return NULL_RTX;
9160}
9161
9162/* Return the integer value of the "type" attribute for INSN, or -1 if
9163 INSN can't have attributes. */
9164
9165int
84034c69 9166arc_attr_type (rtx_insn *insn)
526b7aee
SV
9167{
9168 if (NONJUMP_INSN_P (insn)
9169 ? (GET_CODE (PATTERN (insn)) == USE
9170 || GET_CODE (PATTERN (insn)) == CLOBBER)
9171 : JUMP_P (insn)
9172 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9173 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9174 : !CALL_P (insn))
9175 return -1;
9176 return get_attr_type (insn);
9177}
9178
9179/* Return true if insn sets the condition codes. */
9180
9181bool
84034c69 9182arc_sets_cc_p (rtx_insn *insn)
526b7aee 9183{
84034c69
DM
9184 if (NONJUMP_INSN_P (insn))
9185 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9186 insn = seq->insn (seq->len () - 1);
526b7aee
SV
9187 return arc_attr_type (insn) == TYPE_COMPARE;
9188}
9189
9190/* Return true if INSN is an instruction with a delay slot we may want
9191 to fill. */
9192
9193bool
b3458f61 9194arc_need_delay (rtx_insn *insn)
526b7aee 9195{
b3458f61 9196 rtx_insn *next;
526b7aee
SV
9197
9198 if (!flag_delayed_branch)
9199 return false;
9200 /* The return at the end of a function needs a delay slot. */
9201 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9202 && (!(next = next_active_insn (insn))
9203 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9204 && arc_attr_type (next) == TYPE_RETURN))
9205 && (!TARGET_PAD_RETURN
9206 || (prev_active_insn (insn)
9207 && prev_active_insn (prev_active_insn (insn))
9208 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9209 return true;
9210 if (NONJUMP_INSN_P (insn)
9211 ? (GET_CODE (PATTERN (insn)) == USE
9212 || GET_CODE (PATTERN (insn)) == CLOBBER
9213 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9214 : JUMP_P (insn)
9215 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9216 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9217 : !CALL_P (insn))
9218 return false;
9219 return num_delay_slots (insn) != 0;
9220}
9221
9222/* Return true if the scheduling pass(es) has/have already run,
9223 i.e. where possible, we should try to mitigate high latencies
9224 by different instruction selection. */
9225
9226bool
9227arc_scheduling_not_expected (void)
9228{
9229 return cfun->machine->arc_reorg_started;
9230}
9231
9232/* Oddly enough, sometimes we get a zero overhead loop that branch
9233 shortening doesn't think is a loop - observed with compile/pr24883.c
9234 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9235 alignment visible for branch shortening (we actually align the loop
9236 insn before it, but that is equivalent since the loop insn is 4 byte
9237 long.) */
9238
9239int
9240arc_label_align (rtx label)
9241{
9242 int loop_align = LOOP_ALIGN (LABEL);
9243
9244 if (loop_align > align_labels_log)
9245 {
b3458f61 9246 rtx_insn *prev = prev_nonnote_insn (label);
526b7aee
SV
9247
9248 if (prev && NONJUMP_INSN_P (prev)
9249 && GET_CODE (PATTERN (prev)) == PARALLEL
9250 && recog_memoized (prev) == CODE_FOR_doloop_begin_i)
9251 return loop_align;
9252 }
9253 /* Code has a minimum p2 alignment of 1, which we must restore after an
9254 ADDR_DIFF_VEC. */
9255 if (align_labels_log < 1)
9256 {
b3458f61 9257 rtx_insn *next = next_nonnote_nondebug_insn (label);
526b7aee
SV
9258 if (INSN_P (next) && recog_memoized (next) >= 0)
9259 return 1;
9260 }
9261 return align_labels_log;
9262}
9263
9264/* Return true if LABEL is in executable code. */
9265
9266bool
b32d5189 9267arc_text_label (rtx_insn *label)
526b7aee 9268{
b3458f61 9269 rtx_insn *next;
526b7aee
SV
9270
9271 /* ??? We use deleted labels like they were still there, see
9272 gcc.c-torture/compile/20000326-2.c . */
9273 gcc_assert (GET_CODE (label) == CODE_LABEL
9274 || (GET_CODE (label) == NOTE
9275 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9276 next = next_nonnote_insn (label);
9277 if (next)
9278 return (!JUMP_TABLE_DATA_P (next)
9279 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9280 else if (!PREV_INSN (label))
9281 /* ??? sometimes text labels get inserted very late, see
9282 gcc.dg/torture/stackalign/comp-goto-1.c */
9283 return true;
9284 return false;
9285}
9286
9287/* Return the size of the pretend args for DECL. */
9288
9289int
9290arc_decl_pretend_args (tree decl)
9291{
9292 /* struct function is in DECL_STRUCT_FUNCTION (decl), but no
9293 pretend_args there... See PR38391. */
9294 gcc_assert (decl == current_function_decl);
9295 return crtl->args.pretend_args_size;
9296}
9297
9298/* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9299 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
339ba33b 9300 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
526b7aee
SV
9301 to redirect two breqs. */
9302
9303static bool
c1ce59ab 9304arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
526b7aee
SV
9305{
9306 /* ??? get_attr_type is declared to take an rtx. */
c1ce59ab 9307 union { const rtx_insn *c; rtx_insn *r; } u;
526b7aee
SV
9308
9309 u.c = follower;
339ba33b 9310 if (CROSSING_JUMP_P (followee))
526b7aee
SV
9311 switch (get_attr_type (u.r))
9312 {
9313 case TYPE_BRCC:
9314 case TYPE_BRCC_NO_DELAY_SLOT:
9315 return false;
9316 default:
9317 return true;
9318 }
9319 return true;
9320}
9321
9322/* Implement EPILOGUE__USES.
9323 Return true if REGNO should be added to the deemed uses of the epilogue.
9324
9325 We use the return address
9326 arc_return_address_regs[arc_compute_function_type (cfun)] .
9327 But also, we have to make sure all the register restore instructions
9328 are known to be live in interrupt functions. */
9329
9330bool
9331arc_epilogue_uses (int regno)
9332{
28633bbd
CZ
9333 if (regno == arc_tp_regno)
9334 return true;
526b7aee
SV
9335 if (reload_completed)
9336 {
9337 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9338 {
9339 if (!fixed_regs[regno])
9340 return true;
9341 return regno == arc_return_address_regs[cfun->machine->fn_type];
9342 }
9343 else
9344 return regno == RETURN_ADDR_REGNUM;
9345 }
9346 else
9347 return regno == arc_return_address_regs[arc_compute_function_type (cfun)];
9348}
9349
28633bbd
CZ
9350/* Helper for EH_USES macro. */
9351
9352bool
9353arc_eh_uses (int regno)
9354{
9355 if (regno == arc_tp_regno)
9356 return true;
9357 return false;
9358}
9359
526b7aee
SV
9360#ifndef TARGET_NO_LRA
9361#define TARGET_NO_LRA !TARGET_LRA
9362#endif
9363
9364static bool
9365arc_lra_p (void)
9366{
9367 return !TARGET_NO_LRA;
9368}
9369
9370/* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9371 Rcq registers, because some insn are shorter with them. OTOH we already
9372 have separate alternatives for this purpose, and other insns don't
9373 mind, so maybe we should rather prefer the other registers?
9374 We need more data, and we can only get that if we allow people to
9375 try all options. */
9376static int
9377arc_register_priority (int r)
9378{
9379 switch (arc_lra_priority_tag)
9380 {
9381 case ARC_LRA_PRIORITY_NONE:
9382 return 0;
9383 case ARC_LRA_PRIORITY_NONCOMPACT:
9384 return ((((r & 7) ^ 4) - 4) & 15) != r;
9385 case ARC_LRA_PRIORITY_COMPACT:
9386 return ((((r & 7) ^ 4) - 4) & 15) == r;
9387 default:
9388 gcc_unreachable ();
9389 }
9390}
9391
9392static reg_class_t
ef4bddc2 9393arc_spill_class (reg_class_t /* orig_class */, machine_mode)
526b7aee
SV
9394{
9395 return GENERAL_REGS;
9396}
9397
9398bool
ef4bddc2 9399arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
526b7aee
SV
9400 int itype)
9401{
9402 rtx x = *p;
9403 enum reload_type type = (enum reload_type) itype;
9404
9405 if (GET_CODE (x) == PLUS
9406 && CONST_INT_P (XEXP (x, 1))
9407 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9408 || (REG_P (XEXP (x, 0))
9409 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9410 {
9411 int scale = GET_MODE_SIZE (mode);
9412 int shift;
9413 rtx index_rtx = XEXP (x, 1);
9414 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9415 rtx reg, sum, sum2;
9416
9417 if (scale > 4)
9418 scale = 4;
9419 if ((scale-1) & offset)
9420 scale = 1;
9421 shift = scale >> 1;
c419f71c
JL
9422 offset_base
9423 = ((offset + (256 << shift))
4e671509 9424 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
526b7aee
SV
9425 /* Sometimes the normal form does not suit DImode. We
9426 could avoid that by using smaller ranges, but that
9427 would give less optimized code when SImode is
9428 prevalent. */
9429 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9430 {
9431 int regno;
9432
9433 reg = XEXP (x, 0);
9434 regno = REGNO (reg);
9435 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9436
9437 if (reg_equiv_constant (regno))
9438 {
9439 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9440 offset_base);
9441 if (GET_CODE (sum2) == PLUS)
9442 sum2 = gen_rtx_CONST (Pmode, sum2);
9443 }
9444 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9445 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9446 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9447 type);
9448 return true;
9449 }
9450 }
9451 /* We must re-recognize what we created before. */
9452 else if (GET_CODE (x) == PLUS
9453 && GET_CODE (XEXP (x, 0)) == PLUS
9454 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9455 && REG_P (XEXP (XEXP (x, 0), 0))
9456 && CONST_INT_P (XEXP (x, 1)))
9457 {
9458 /* Because this address is so complex, we know it must have
9459 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9460 it is already unshared, and needs no further unsharing. */
9461 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9462 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
9463 return true;
9464 }
9465 return false;
9466}
9467
ad23f5d4
JG
9468/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9469
9470static bool
445d7826 9471arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
ad23f5d4
JG
9472 unsigned int align,
9473 enum by_pieces_operation op,
9474 bool speed_p)
9475{
9476 /* Let the movmem expander handle small block moves. */
9477 if (op == MOVE_BY_PIECES)
9478 return false;
9479
9480 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
9481}
9482
b8a64b7f
CZ
9483/* Emit a (pre) memory barrier around an atomic sequence according to
9484 MODEL. */
9485
9486static void
9487arc_pre_atomic_barrier (enum memmodel model)
9488{
9489 if (need_atomic_barrier_p (model, true))
9490 emit_insn (gen_memory_barrier ());
9491}
9492
9493/* Emit a (post) memory barrier around an atomic sequence according to
9494 MODEL. */
9495
9496static void
9497arc_post_atomic_barrier (enum memmodel model)
9498{
9499 if (need_atomic_barrier_p (model, false))
9500 emit_insn (gen_memory_barrier ());
9501}
9502
9503/* Expand a compare and swap pattern. */
9504
9505static void
9506emit_unlikely_jump (rtx insn)
9507{
9508 int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
9509
9510 insn = emit_jump_insn (insn);
9511 add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
9512}
9513
9514/* Expand code to perform a 8 or 16-bit compare and swap by doing
9515 32-bit compare and swap on the word containing the byte or
9516 half-word. The difference between a weak and a strong CAS is that
9517 the weak version may simply fail. The strong version relies on two
9518 loops, one checks if the SCOND op is succsfully or not, the other
9519 checks if the 32 bit accessed location which contains the 8 or 16
9520 bit datum is not changed by other thread. The first loop is
9521 implemented by the atomic_compare_and_swapsi_1 pattern. The second
9522 loops is implemented by this routine. */
9523
9524static void
9525arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
9526 rtx oldval, rtx newval, rtx weak,
9527 rtx mod_s, rtx mod_f)
9528{
9529 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
9530 rtx addr = gen_reg_rtx (Pmode);
9531 rtx off = gen_reg_rtx (SImode);
9532 rtx oldv = gen_reg_rtx (SImode);
9533 rtx newv = gen_reg_rtx (SImode);
9534 rtx oldvalue = gen_reg_rtx (SImode);
9535 rtx newvalue = gen_reg_rtx (SImode);
9536 rtx res = gen_reg_rtx (SImode);
9537 rtx resv = gen_reg_rtx (SImode);
9538 rtx memsi, val, mask, end_label, loop_label, cc, x;
9539 machine_mode mode;
9540 bool is_weak = (weak != const0_rtx);
9541
9542 /* Truncate the address. */
9543 emit_insn (gen_rtx_SET (addr,
9544 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
9545
9546 /* Compute the datum offset. */
9547 emit_insn (gen_rtx_SET (off,
9548 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
9549 if (TARGET_BIG_ENDIAN)
9550 emit_insn (gen_rtx_SET (off,
9551 gen_rtx_MINUS (SImode,
9552 (GET_MODE (mem) == QImode) ?
9553 GEN_INT (3) : GEN_INT (2), off)));
9554
9555 /* Normal read from truncated address. */
9556 memsi = gen_rtx_MEM (SImode, addr);
9557 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
9558 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
9559
9560 val = copy_to_reg (memsi);
9561
9562 /* Convert the offset in bits. */
9563 emit_insn (gen_rtx_SET (off,
9564 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
9565
9566 /* Get the proper mask. */
9567 if (GET_MODE (mem) == QImode)
9568 mask = force_reg (SImode, GEN_INT (0xff));
9569 else
9570 mask = force_reg (SImode, GEN_INT (0xffff));
9571
9572 emit_insn (gen_rtx_SET (mask,
9573 gen_rtx_ASHIFT (SImode, mask, off)));
9574
9575 /* Prepare the old and new values. */
9576 emit_insn (gen_rtx_SET (val,
9577 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
9578 val)));
9579
9580 oldval = gen_lowpart (SImode, oldval);
9581 emit_insn (gen_rtx_SET (oldv,
9582 gen_rtx_ASHIFT (SImode, oldval, off)));
9583
9584 newval = gen_lowpart_common (SImode, newval);
9585 emit_insn (gen_rtx_SET (newv,
9586 gen_rtx_ASHIFT (SImode, newval, off)));
9587
9588 emit_insn (gen_rtx_SET (oldv,
9589 gen_rtx_AND (SImode, oldv, mask)));
9590
9591 emit_insn (gen_rtx_SET (newv,
9592 gen_rtx_AND (SImode, newv, mask)));
9593
9594 if (!is_weak)
9595 {
9596 end_label = gen_label_rtx ();
9597 loop_label = gen_label_rtx ();
9598 emit_label (loop_label);
9599 }
9600
9601 /* Make the old and new values. */
9602 emit_insn (gen_rtx_SET (oldvalue,
9603 gen_rtx_IOR (SImode, oldv, val)));
9604
9605 emit_insn (gen_rtx_SET (newvalue,
9606 gen_rtx_IOR (SImode, newv, val)));
9607
9608 /* Try an 32bit atomic compare and swap. It clobbers the CC
9609 register. */
9610 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
9611 weak, mod_s, mod_f));
9612
9613 /* Regardless of the weakness of the operation, a proper boolean
9614 result needs to be provided. */
9615 x = gen_rtx_REG (CC_Zmode, CC_REG);
9616 x = gen_rtx_EQ (SImode, x, const0_rtx);
9617 emit_insn (gen_rtx_SET (bool_result, x));
9618
9619 if (!is_weak)
9620 {
9621 /* Check the results: if the atomic op is successfully the goto
9622 to end label. */
9623 x = gen_rtx_REG (CC_Zmode, CC_REG);
9624 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
9625 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9626 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
9627 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
9628
9629 /* Wait for the right moment when the accessed 32-bit location
9630 is stable. */
9631 emit_insn (gen_rtx_SET (resv,
9632 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
9633 res)));
9634 mode = SELECT_CC_MODE (NE, resv, val);
9635 cc = gen_rtx_REG (mode, CC_REG);
9636 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
9637
9638 /* Set the new value of the 32 bit location, proper masked. */
9639 emit_insn (gen_rtx_SET (val, resv));
9640
9641 /* Try again if location is unstable. Fall through if only
9642 scond op failed. */
9643 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
9644 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9645 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
9646 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9647
9648 emit_label (end_label);
9649 }
9650
9651 /* End: proper return the result for the given mode. */
9652 emit_insn (gen_rtx_SET (res,
9653 gen_rtx_AND (SImode, res, mask)));
9654
9655 emit_insn (gen_rtx_SET (res,
9656 gen_rtx_LSHIFTRT (SImode, res, off)));
9657
9658 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
9659}
9660
9661/* Helper function used by "atomic_compare_and_swap" expand
9662 pattern. */
9663
9664void
9665arc_expand_compare_and_swap (rtx operands[])
9666{
9667 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
9668 machine_mode mode;
9669
9670 bval = operands[0];
9671 rval = operands[1];
9672 mem = operands[2];
9673 oldval = operands[3];
9674 newval = operands[4];
9675 is_weak = operands[5];
9676 mod_s = operands[6];
9677 mod_f = operands[7];
9678 mode = GET_MODE (mem);
9679
9680 if (reg_overlap_mentioned_p (rval, oldval))
9681 oldval = copy_to_reg (oldval);
9682
9683 if (mode == SImode)
9684 {
9685 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
9686 is_weak, mod_s, mod_f));
9687 x = gen_rtx_REG (CC_Zmode, CC_REG);
9688 x = gen_rtx_EQ (SImode, x, const0_rtx);
9689 emit_insn (gen_rtx_SET (bval, x));
9690 }
9691 else
9692 {
9693 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
9694 is_weak, mod_s, mod_f);
9695 }
9696}
9697
9698/* Helper function used by the "atomic_compare_and_swapsi_1"
9699 pattern. */
9700
9701void
9702arc_split_compare_and_swap (rtx operands[])
9703{
9704 rtx rval, mem, oldval, newval;
9705 machine_mode mode;
9706 enum memmodel mod_s, mod_f;
9707 bool is_weak;
9708 rtx label1, label2, x, cond;
9709
9710 rval = operands[0];
9711 mem = operands[1];
9712 oldval = operands[2];
9713 newval = operands[3];
9714 is_weak = (operands[4] != const0_rtx);
9715 mod_s = (enum memmodel) INTVAL (operands[5]);
9716 mod_f = (enum memmodel) INTVAL (operands[6]);
9717 mode = GET_MODE (mem);
9718
9719 /* ARC atomic ops work only with 32-bit aligned memories. */
9720 gcc_assert (mode == SImode);
9721
9722 arc_pre_atomic_barrier (mod_s);
9723
9724 label1 = NULL_RTX;
9725 if (!is_weak)
9726 {
9727 label1 = gen_label_rtx ();
9728 emit_label (label1);
9729 }
9730 label2 = gen_label_rtx ();
9731
9732 /* Load exclusive. */
9733 emit_insn (gen_arc_load_exclusivesi (rval, mem));
9734
9735 /* Check if it is oldval. */
9736 mode = SELECT_CC_MODE (NE, rval, oldval);
9737 cond = gen_rtx_REG (mode, CC_REG);
9738 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
9739
9740 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9741 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9742 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
9743 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9744
9745 /* Exclusively store new item. Store clobbers CC reg. */
9746 emit_insn (gen_arc_store_exclusivesi (mem, newval));
9747
9748 if (!is_weak)
9749 {
9750 /* Check the result of the store. */
9751 cond = gen_rtx_REG (CC_Zmode, CC_REG);
9752 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9753 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9754 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
9755 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9756 }
9757
9758 if (mod_f != MEMMODEL_RELAXED)
9759 emit_label (label2);
9760
9761 arc_post_atomic_barrier (mod_s);
9762
9763 if (mod_f == MEMMODEL_RELAXED)
9764 emit_label (label2);
9765}
9766
9767/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
9768 to perform. MEM is the memory on which to operate. VAL is the second
9769 operand of the binary operator. BEFORE and AFTER are optional locations to
9770 return the value of MEM either before of after the operation. MODEL_RTX
9771 is a CONST_INT containing the memory model to use. */
9772
9773void
9774arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
9775 rtx orig_before, rtx orig_after, rtx model_rtx)
9776{
9777 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
9778 machine_mode mode = GET_MODE (mem);
9779 rtx label, x, cond;
9780 rtx before = orig_before, after = orig_after;
9781
9782 /* ARC atomic ops work only with 32-bit aligned memories. */
9783 gcc_assert (mode == SImode);
9784
9785 arc_pre_atomic_barrier (model);
9786
9787 label = gen_label_rtx ();
9788 emit_label (label);
9789 label = gen_rtx_LABEL_REF (VOIDmode, label);
9790
9791 if (before == NULL_RTX)
9792 before = gen_reg_rtx (mode);
9793
9794 if (after == NULL_RTX)
9795 after = gen_reg_rtx (mode);
9796
9797 /* Load exclusive. */
9798 emit_insn (gen_arc_load_exclusivesi (before, mem));
9799
9800 switch (code)
9801 {
9802 case NOT:
9803 x = gen_rtx_AND (mode, before, val);
9804 emit_insn (gen_rtx_SET (after, x));
9805 x = gen_rtx_NOT (mode, after);
9806 emit_insn (gen_rtx_SET (after, x));
9807 break;
9808
9809 case MINUS:
9810 if (CONST_INT_P (val))
9811 {
9812 val = GEN_INT (-INTVAL (val));
9813 code = PLUS;
9814 }
9815
9816 /* FALLTHRU. */
9817 default:
9818 x = gen_rtx_fmt_ee (code, mode, before, val);
9819 emit_insn (gen_rtx_SET (after, x));
9820 break;
9821 }
9822
9823 /* Exclusively store new item. Store clobbers CC reg. */
9824 emit_insn (gen_arc_store_exclusivesi (mem, after));
9825
9826 /* Check the result of the store. */
9827 cond = gen_rtx_REG (CC_Zmode, CC_REG);
9828 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9829 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9830 label, pc_rtx);
9831 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9832
9833 arc_post_atomic_barrier (model);
9834}
9835
bf9e9dc5
CZ
9836/* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
9837
9838static bool
9839arc_no_speculation_in_delay_slots_p ()
9840{
9841 return true;
9842}
9843
d34a0fdc
CZ
9844/* Return a parallel of registers to represent where to find the
9845 register pieces if required, otherwise NULL_RTX. */
9846
9847static rtx
9848arc_dwarf_register_span (rtx rtl)
9849{
9850 enum machine_mode mode = GET_MODE (rtl);
9851 unsigned regno;
9852 rtx p;
9853
9854 if (GET_MODE_SIZE (mode) != 8)
9855 return NULL_RTX;
9856
9857 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
9858 regno = REGNO (rtl);
9859 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
9860 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
9861
9862 return p;
9863}
9864
28633bbd
CZ
9865/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
9866 resource.h doesn't include the required header files. */
fc1c2d04 9867
28633bbd
CZ
9868bool
9869insn_is_tls_gd_dispatch (rtx_insn *insn)
9870{
9871 return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
9872}
d34a0fdc 9873
fc1c2d04
CZ
9874/* Return true if OP is an acceptable memory operand for ARCompact
9875 16-bit load instructions of MODE.
9876
9877 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
9878 non scaled instructions.
9879
9880 SCALED: TRUE if address can be scaled. */
9881
9882bool
9883compact_memory_operand_p (rtx op, machine_mode mode,
9884 bool av2short, bool scaled)
9885{
9886 rtx addr, plus0, plus1;
9887 int size, off;
9888
9889 /* Eliminate non-memory operations. */
9890 if (GET_CODE (op) != MEM)
9891 return 0;
9892
9893 /* .di instructions have no 16-bit form. */
9894 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
9895 return false;
9896
9897 if (mode == VOIDmode)
9898 mode = GET_MODE (op);
9899
9900 size = GET_MODE_SIZE (mode);
9901
9902 /* dword operations really put out 2 instructions, so eliminate
9903 them. */
9904 if (size > UNITS_PER_WORD)
9905 return false;
9906
9907 /* Decode the address now. */
9908 addr = XEXP (op, 0);
9909 switch (GET_CODE (addr))
9910 {
9911 case REG:
9912 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
9913 || COMPACT_GP_REG_P (REGNO (addr))
9914 || (SP_REG_P (REGNO (addr)) && (size != 2)));
9915 case PLUS:
9916 plus0 = XEXP (addr, 0);
9917 plus1 = XEXP (addr, 1);
9918
9919 if ((GET_CODE (plus0) == REG)
9920 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9921 || COMPACT_GP_REG_P (REGNO (plus0)))
9922 && ((GET_CODE (plus1) == REG)
9923 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
9924 || COMPACT_GP_REG_P (REGNO (plus1)))))
9925 {
9926 return !av2short;
9927 }
9928
9929 if ((GET_CODE (plus0) == REG)
9930 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9931 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
9932 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
9933 && (GET_CODE (plus1) == CONST_INT))
9934 {
9935 bool valid = false;
9936
9937 off = INTVAL (plus1);
9938
9939 /* Negative offset is not supported in 16-bit load/store insns. */
9940 if (off < 0)
9941 return 0;
9942
9943 /* Only u5 immediates allowed in code density instructions. */
9944 if (av2short)
9945 {
9946 switch (size)
9947 {
9948 case 1:
9949 return false;
9950 case 2:
9951 /* This is an ldh_s.x instruction, check the u6
9952 immediate. */
9953 if (COMPACT_GP_REG_P (REGNO (plus0)))
9954 valid = true;
9955 break;
9956 case 4:
9957 /* Only u5 immediates allowed in 32bit access code
9958 density instructions. */
9959 if (REGNO (plus0) <= 31)
9960 return ((off < 32) && (off % 4 == 0));
9961 break;
9962 default:
9963 return false;
9964 }
9965 }
9966 else
9967 if (COMPACT_GP_REG_P (REGNO (plus0)))
9968 valid = true;
9969
9970 if (valid)
9971 {
9972
9973 switch (size)
9974 {
9975 case 1:
9976 return (off < 32);
9977 case 2:
9978 /* The 6-bit constant get shifted to fit the real
9979 5-bits field. Check also for the alignment. */
9980 return ((off < 64) && (off % 2 == 0));
9981 case 4:
9982 return ((off < 128) && (off % 4 == 0));
9983 default:
9984 return false;
9985 }
9986 }
9987 }
9988
9989 if (REG_P (plus0) && CONST_INT_P (plus1)
9990 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9991 || SP_REG_P (REGNO (plus0)))
9992 && !av2short)
9993 {
9994 off = INTVAL (plus1);
9995 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
9996 }
9997
9998 if ((GET_CODE (plus0) == MULT)
9999 && (GET_CODE (XEXP (plus0, 0)) == REG)
10000 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10001 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10002 && (GET_CODE (plus1) == REG)
10003 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10004 || COMPACT_GP_REG_P (REGNO (plus1))))
10005 return scaled;
10006 default:
10007 break ;
10008 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10009 for 16-bit load instructions. */
10010 }
10011 return false;
10012}
10013
526b7aee
SV
10014struct gcc_target targetm = TARGET_INITIALIZER;
10015
10016#include "gt-arc.h"