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