]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/arc.c
cr16.c (cr16_print_operand): Add missing fallthru comment.
[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 }
3462 /* Fall through. Let output_addr_const deal with it. */
3463 default :
28633bbd
CZ
3464 if (flag_pic
3465 || (GET_CODE (x) == CONST
3466 && GET_CODE (XEXP (x, 0)) == UNSPEC
3467 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
3468 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
3469 || (GET_CODE (x) == CONST
3470 && GET_CODE (XEXP (x, 0)) == PLUS
3471 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
3472 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
3473 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
526b7aee
SV
3474 arc_output_pic_addr_const (file, x, code);
3475 else
3476 {
3477 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3478 with asm_output_symbol_ref */
3479 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
3480 {
3481 x = XEXP (x, 0);
3482 output_addr_const (file, XEXP (x, 0));
3483 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && SYMBOL_REF_SMALL_P (XEXP (x, 0)))
3484 fprintf (file, "@sda");
3485
3486 if (GET_CODE (XEXP (x, 1)) != CONST_INT
3487 || INTVAL (XEXP (x, 1)) >= 0)
3488 fprintf (file, "+");
3489 output_addr_const (file, XEXP (x, 1));
3490 }
3491 else
3492 output_addr_const (file, x);
3493 }
3494 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
3495 fprintf (file, "@sda");
3496 break;
3497 }
3498}
3499
3500/* Print a memory address as an operand to reference that memory location. */
3501
3502void
3503arc_print_operand_address (FILE *file , rtx addr)
3504{
3505 register rtx base, index = 0;
3506
3507 switch (GET_CODE (addr))
3508 {
3509 case REG :
3510 fputs (reg_names[REGNO (addr)], file);
3511 break;
3512 case SYMBOL_REF :
3513 output_addr_const (file, addr);
3514 if (SYMBOL_REF_SMALL_P (addr))
3515 fprintf (file, "@sda");
3516 break;
3517 case PLUS :
3518 if (GET_CODE (XEXP (addr, 0)) == MULT)
3519 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
3520 else if (CONST_INT_P (XEXP (addr, 0)))
3521 index = XEXP (addr, 0), base = XEXP (addr, 1);
3522 else
3523 base = XEXP (addr, 0), index = XEXP (addr, 1);
3524
3525 gcc_assert (OBJECT_P (base));
3526 arc_print_operand_address (file, base);
3527 if (CONSTANT_P (base) && CONST_INT_P (index))
3528 fputc ('+', file);
3529 else
3530 fputc (',', file);
3531 gcc_assert (OBJECT_P (index));
3532 arc_print_operand_address (file, index);
3533 break;
3534 case CONST:
3535 {
3536 rtx c = XEXP (addr, 0);
3537
28633bbd
CZ
3538 if ((GET_CODE (c) == UNSPEC
3539 && (XINT (c, 1) == UNSPEC_TLS_OFF
3540 || XINT (c, 1) == UNSPEC_TLS_IE))
3541 || (GET_CODE (c) == PLUS
3542 && GET_CODE (XEXP (c, 0)) == UNSPEC
f5e336b1
CZ
3543 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
3544 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
28633bbd
CZ
3545 {
3546 arc_output_pic_addr_const (file, c, 0);
3547 break;
3548 }
3549 gcc_assert (GET_CODE (c) == PLUS);
526b7aee
SV
3550 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
3551 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
3552
cc8ca59e 3553 output_address (VOIDmode, XEXP (addr, 0));
526b7aee
SV
3554
3555 break;
3556 }
3557 case PRE_INC :
3558 case PRE_DEC :
3559 /* We shouldn't get here as we've lost the mode of the memory object
3560 (which says how much to inc/dec by. */
3561 gcc_unreachable ();
3562 break;
3563 default :
3564 if (flag_pic)
3565 arc_output_pic_addr_const (file, addr, 0);
3566 else
3567 output_addr_const (file, addr);
3568 break;
3569 }
3570}
3571
3572/* Called via walk_stores. DATA points to a hash table we can use to
3573 establish a unique SYMBOL_REF for each counter, which corresponds to
3574 a caller-callee pair.
3575 X is a store which we want to examine for an UNSPEC_PROF, which
3576 would be an address loaded into a register, or directly used in a MEM.
3577 If we found an UNSPEC_PROF, if we encounter a new counter the first time,
3578 write out a description and a data allocation for a 32 bit counter.
3579 Also, fill in the appropriate symbol_ref into each UNSPEC_PROF instance. */
3580
3581static void
3582write_profile_sections (rtx dest ATTRIBUTE_UNUSED, rtx x, void *data)
3583{
3584 rtx *srcp, src;
3585 htab_t htab = (htab_t) data;
3586 rtx *slot;
3587
3588 if (GET_CODE (x) != SET)
3589 return;
3590 srcp = &SET_SRC (x);
3591 if (MEM_P (*srcp))
3592 srcp = &XEXP (*srcp, 0);
3593 else if (MEM_P (SET_DEST (x)))
3594 srcp = &XEXP (SET_DEST (x), 0);
3595 src = *srcp;
3596 if (GET_CODE (src) != CONST)
3597 return;
3598 src = XEXP (src, 0);
3599 if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_PROF)
3600 return;
3601
3602 gcc_assert (XVECLEN (src, 0) == 3);
3603 if (!htab_elements (htab))
3604 {
3605 output_asm_insn (".section .__arc_profile_desc, \"a\"\n"
3606 "\t.long %0 + 1\n",
3607 &XVECEXP (src, 0, 0));
3608 }
3609 slot = (rtx *) htab_find_slot (htab, src, INSERT);
3610 if (*slot == HTAB_EMPTY_ENTRY)
3611 {
3612 static int count_nr;
3613 char buf[24];
3614 rtx count;
3615
3616 *slot = src;
3617 sprintf (buf, "__prof_count%d", count_nr++);
3618 count = gen_rtx_SYMBOL_REF (Pmode, xstrdup (buf));
3619 XVECEXP (src, 0, 2) = count;
3620 output_asm_insn (".section\t.__arc_profile_desc, \"a\"\n"
3621 "\t.long\t%1\n"
3622 "\t.section\t.__arc_profile_counters, \"aw\"\n"
3623 "\t.type\t%o2, @object\n"
3624 "\t.size\t%o2, 4\n"
3625 "%o2:\t.zero 4",
3626 &XVECEXP (src, 0, 0));
3627 *srcp = count;
3628 }
3629 else
3630 *srcp = XVECEXP (*slot, 0, 2);
3631}
3632
3633/* Hash function for UNSPEC_PROF htab. Use both the caller's name and
3634 the callee's name (if known). */
3635
3636static hashval_t
3637unspec_prof_hash (const void *x)
3638{
3639 const_rtx u = (const_rtx) x;
3640 const_rtx s1 = XVECEXP (u, 0, 1);
3641
3642 return (htab_hash_string (XSTR (XVECEXP (u, 0, 0), 0))
3643 ^ (s1->code == SYMBOL_REF ? htab_hash_string (XSTR (s1, 0)) : 0));
3644}
3645
3646/* Equality function for UNSPEC_PROF htab. Two pieces of UNSPEC_PROF rtl
3647 shall refer to the same counter if both caller name and callee rtl
3648 are identical. */
3649
3650static int
3651unspec_prof_htab_eq (const void *x, const void *y)
3652{
3653 const_rtx u0 = (const_rtx) x;
3654 const_rtx u1 = (const_rtx) y;
3655 const_rtx s01 = XVECEXP (u0, 0, 1);
3656 const_rtx s11 = XVECEXP (u1, 0, 1);
3657
3658 return (!strcmp (XSTR (XVECEXP (u0, 0, 0), 0),
3659 XSTR (XVECEXP (u1, 0, 0), 0))
3660 && rtx_equal_p (s01, s11));
3661}
3662
3663/* Conditional execution support.
3664
3665 This is based on the ARM port but for now is much simpler.
3666
3667 A finite state machine takes care of noticing whether or not instructions
3668 can be conditionally executed, and thus decrease execution time and code
3669 size by deleting branch instructions. The fsm is controlled by
3670 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
3671 actions of PRINT_OPERAND. The patterns in the .md file for the branch
3672 insns also have a hand in this. */
3673/* The way we leave dealing with non-anulled or annull-false delay slot
3674 insns to the consumer is awkward. */
3675
3676/* The state of the fsm controlling condition codes are:
3677 0: normal, do nothing special
3678 1: don't output this insn
3679 2: don't output this insn
3680 3: make insns conditional
3681 4: make insns conditional
3682 5: make insn conditional (only for outputting anulled delay slot insns)
3683
3684 special value for cfun->machine->uid_ccfsm_state:
3685 6: return with but one insn before it since function start / call
3686
3687 State transitions (state->state by whom, under what condition):
3688 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
3689 some instructions.
3690 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
3691 by zero or more non-jump insns and an unconditional branch with
3692 the same target label as the condbranch.
3693 1 -> 3 branch patterns, after having not output the conditional branch
3694 2 -> 4 branch patterns, after having not output the conditional branch
3695 0 -> 5 branch patterns, for anulled delay slot insn.
3696 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
3697 (the target label has CODE_LABEL_NUMBER equal to
3698 arc_ccfsm_target_label).
3699 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
3700 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
3701 5 -> 0 when outputting the delay slot insn
3702
3703 If the jump clobbers the conditions then we use states 2 and 4.
3704
3705 A similar thing can be done with conditional return insns.
3706
3707 We also handle separating branches from sets of the condition code.
3708 This is done here because knowledge of the ccfsm state is required,
3709 we may not be outputting the branch. */
3710
3711/* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
3712 before letting final output INSN. */
3713
3714static void
b3458f61 3715arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
526b7aee
SV
3716{
3717 /* BODY will hold the body of INSN. */
3718 register rtx body;
3719
3720 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
3721 an if/then/else), and things need to be reversed. */
3722 int reverse = 0;
3723
3724 /* If we start with a return insn, we only succeed if we find another one. */
3725 int seeking_return = 0;
3726
3727 /* START_INSN will hold the insn from where we start looking. This is the
3728 first insn after the following code_label if REVERSE is true. */
b3458f61 3729 rtx_insn *start_insn = insn;
526b7aee
SV
3730
3731 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
3732 since they don't rely on a cmp preceding the. */
3733 enum attr_type jump_insn_type;
3734
3735 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
3736 We can't do this in macro FINAL_PRESCAN_INSN because its called from
3737 final_scan_insn which has `optimize' as a local. */
3738 if (optimize < 2 || TARGET_NO_COND_EXEC)
3739 return;
3740
3741 /* Ignore notes and labels. */
3742 if (!INSN_P (insn))
3743 return;
3744 body = PATTERN (insn);
3745 /* If in state 4, check if the target branch is reached, in order to
3746 change back to state 0. */
3747 if (state->state == 4)
3748 {
3749 if (insn == state->target_insn)
3750 {
3751 state->target_insn = NULL;
3752 state->state = 0;
3753 }
3754 return;
3755 }
3756
3757 /* If in state 3, it is possible to repeat the trick, if this insn is an
3758 unconditional branch to a label, and immediately following this branch
3759 is the previous target label which is only used once, and the label this
3760 branch jumps to is not too far off. Or in other words "we've done the
3761 `then' part, see if we can do the `else' part." */
3762 if (state->state == 3)
3763 {
3764 if (simplejump_p (insn))
3765 {
3766 start_insn = next_nonnote_insn (start_insn);
3767 if (GET_CODE (start_insn) == BARRIER)
3768 {
3769 /* ??? Isn't this always a barrier? */
3770 start_insn = next_nonnote_insn (start_insn);
3771 }
3772 if (GET_CODE (start_insn) == CODE_LABEL
3773 && CODE_LABEL_NUMBER (start_insn) == state->target_label
3774 && LABEL_NUSES (start_insn) == 1)
3775 reverse = TRUE;
3776 else
3777 return;
3778 }
3779 else if (GET_CODE (body) == SIMPLE_RETURN)
3780 {
3781 start_insn = next_nonnote_insn (start_insn);
3782 if (GET_CODE (start_insn) == BARRIER)
3783 start_insn = next_nonnote_insn (start_insn);
3784 if (GET_CODE (start_insn) == CODE_LABEL
3785 && CODE_LABEL_NUMBER (start_insn) == state->target_label
3786 && LABEL_NUSES (start_insn) == 1)
3787 {
3788 reverse = TRUE;
3789 seeking_return = 1;
3790 }
3791 else
3792 return;
3793 }
3794 else
3795 return;
3796 }
3797
3798 if (GET_CODE (insn) != JUMP_INSN
3799 || GET_CODE (PATTERN (insn)) == ADDR_VEC
3800 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
3801 return;
3802
3803 /* We can't predicate BRCC or loop ends.
3804 Also, when generating PIC code, and considering a medium range call,
3805 we can't predicate the call. */
3806 jump_insn_type = get_attr_type (insn);
3807 if (jump_insn_type == TYPE_BRCC
3808 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
3809 || jump_insn_type == TYPE_LOOP_END
3810 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
3811 return;
3812
3813 /* This jump might be paralleled with a clobber of the condition codes,
3814 the jump should always come first. */
3815 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
3816 body = XVECEXP (body, 0, 0);
3817
3818 if (reverse
3819 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
3820 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
3821 {
3822 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
3823 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
3824 int then_not_else = TRUE;
3825 /* Nonzero if next insn must be the target label. */
3826 int next_must_be_target_label_p;
b3458f61
DM
3827 rtx_insn *this_insn = start_insn;
3828 rtx label = 0;
526b7aee
SV
3829
3830 /* Register the insn jumped to. */
3831 if (reverse)
3832 {
3833 if (!seeking_return)
3834 label = XEXP (SET_SRC (body), 0);
3835 }
3836 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
3837 label = XEXP (XEXP (SET_SRC (body), 1), 0);
3838 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
3839 {
3840 label = XEXP (XEXP (SET_SRC (body), 2), 0);
3841 then_not_else = FALSE;
3842 }
3843 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
3844 seeking_return = 1;
3845 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
3846 {
3847 seeking_return = 1;
3848 then_not_else = FALSE;
3849 }
3850 else
3851 gcc_unreachable ();
3852
3853 /* If this is a non-annulled branch with a delay slot, there is
3854 no need to conditionalize the delay slot. */
3855 if (NEXT_INSN (PREV_INSN (insn)) != insn
3856 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
3857 {
3858 this_insn = NEXT_INSN (this_insn);
3859 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn)))
3860 == NEXT_INSN (this_insn));
3861 }
3862 /* See how many insns this branch skips, and what kind of insns. If all
3863 insns are okay, and the label or unconditional branch to the same
3864 label is not too far away, succeed. */
3865 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
3866 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
3867 insns_skipped++)
3868 {
3869 rtx scanbody;
3870
3871 this_insn = next_nonnote_insn (this_insn);
3872 if (!this_insn)
3873 break;
3874
3875 if (next_must_be_target_label_p)
3876 {
3877 if (GET_CODE (this_insn) == BARRIER)
3878 continue;
3879 if (GET_CODE (this_insn) == CODE_LABEL
3880 && this_insn == label)
3881 {
3882 state->state = 1;
3883 succeed = TRUE;
3884 }
3885 else
3886 fail = TRUE;
3887 break;
3888 }
3889
3890 scanbody = PATTERN (this_insn);
3891
3892 switch (GET_CODE (this_insn))
3893 {
3894 case CODE_LABEL:
3895 /* Succeed if it is the target label, otherwise fail since
3896 control falls in from somewhere else. */
3897 if (this_insn == label)
3898 {
3899 state->state = 1;
3900 succeed = TRUE;
3901 }
3902 else
3903 fail = TRUE;
3904 break;
3905
3906 case BARRIER:
3907 /* Succeed if the following insn is the target label.
3908 Otherwise fail.
3909 If return insns are used then the last insn in a function
3910 will be a barrier. */
3911 next_must_be_target_label_p = TRUE;
3912 break;
3913
3914 case CALL_INSN:
3915 /* Can handle a call insn if there are no insns after it.
3916 IE: The next "insn" is the target label. We don't have to
3917 worry about delay slots as such insns are SEQUENCE's inside
3918 INSN's. ??? It is possible to handle such insns though. */
3919 if (get_attr_cond (this_insn) == COND_CANUSE)
3920 next_must_be_target_label_p = TRUE;
3921 else
3922 fail = TRUE;
3923 break;
3924
3925 case JUMP_INSN:
3926 /* If this is an unconditional branch to the same label, succeed.
3927 If it is to another label, do nothing. If it is conditional,
3928 fail. */
3929 /* ??? Probably, the test for the SET and the PC are
3930 unnecessary. */
3931
3932 if (GET_CODE (scanbody) == SET
3933 && GET_CODE (SET_DEST (scanbody)) == PC)
3934 {
3935 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
3936 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
3937 {
3938 state->state = 2;
3939 succeed = TRUE;
3940 }
3941 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
3942 fail = TRUE;
3943 else if (get_attr_cond (this_insn) != COND_CANUSE)
3944 fail = TRUE;
3945 }
3946 else if (GET_CODE (scanbody) == SIMPLE_RETURN
3947 && seeking_return)
3948 {
3949 state->state = 2;
3950 succeed = TRUE;
3951 }
3952 else if (GET_CODE (scanbody) == PARALLEL)
3953 {
3954 if (get_attr_cond (this_insn) != COND_CANUSE)
3955 fail = TRUE;
3956 }
3957 break;
3958
3959 case INSN:
3960 /* We can only do this with insns that can use the condition
3961 codes (and don't set them). */
3962 if (GET_CODE (scanbody) == SET
3963 || GET_CODE (scanbody) == PARALLEL)
3964 {
3965 if (get_attr_cond (this_insn) != COND_CANUSE)
3966 fail = TRUE;
3967 }
3968 /* We can't handle other insns like sequences. */
3969 else
3970 fail = TRUE;
3971 break;
3972
3973 default:
3974 break;
3975 }
3976 }
3977
3978 if (succeed)
3979 {
3980 if ((!seeking_return) && (state->state == 1 || reverse))
3981 state->target_label = CODE_LABEL_NUMBER (label);
3982 else if (seeking_return || state->state == 2)
3983 {
3984 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
3985 {
3986 this_insn = next_nonnote_insn (this_insn);
3987
3988 gcc_assert (!this_insn ||
3989 (GET_CODE (this_insn) != BARRIER
3990 && GET_CODE (this_insn) != CODE_LABEL));
3991 }
3992 if (!this_insn)
3993 {
3994 /* Oh dear! we ran off the end, give up. */
3995 extract_insn_cached (insn);
3996 state->state = 0;
3997 state->target_insn = NULL;
3998 return;
3999 }
4000 state->target_insn = this_insn;
4001 }
4002 else
4003 gcc_unreachable ();
4004
4005 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4006 what it was. */
4007 if (!reverse)
4008 {
4009 state->cond = XEXP (SET_SRC (body), 0);
4010 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
4011 }
4012
4013 if (reverse || then_not_else)
4014 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
4015 }
4016
4017 /* Restore recog_operand. Getting the attributes of other insns can
4018 destroy this array, but final.c assumes that it remains intact
4019 across this call; since the insn has been recognized already we
4020 call insn_extract direct. */
4021 extract_insn_cached (insn);
4022 }
4023}
4024
4025/* Record that we are currently outputting label NUM with prefix PREFIX.
4026 It it's the label we're looking for, reset the ccfsm machinery.
4027
4028 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4029
4030static void
4031arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
4032{
4033 if (state->state == 3 && state->target_label == num
4034 && !strcmp (prefix, "L"))
4035 {
4036 state->state = 0;
b3458f61 4037 state->target_insn = NULL;
526b7aee
SV
4038 }
4039}
4040
4041/* We are considering a conditional branch with the condition COND.
4042 Check if we want to conditionalize a delay slot insn, and if so modify
4043 the ccfsm state accordingly.
4044 REVERSE says branch will branch when the condition is false. */
4045void
b32d5189 4046arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
526b7aee
SV
4047 struct arc_ccfsm *state)
4048{
b3458f61 4049 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
526b7aee
SV
4050 if (!state)
4051 state = &arc_ccfsm_current;
4052
4053 gcc_assert (state->state == 0);
4054 if (seq_insn != jump)
4055 {
4056 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
4057
4654c0cf 4058 if (!as_a<rtx_insn *> (insn)->deleted ()
526b7aee
SV
4059 && INSN_ANNULLED_BRANCH_P (jump)
4060 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
4061 {
4062 state->cond = cond;
4063 state->cc = get_arc_condition_code (cond);
4064 if (!reverse)
4065 arc_ccfsm_current.cc
4066 = ARC_INVERSE_CONDITION_CODE (state->cc);
4067 rtx pat = PATTERN (insn);
4068 if (GET_CODE (pat) == COND_EXEC)
4069 gcc_assert ((INSN_FROM_TARGET_P (insn)
4070 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
4071 == get_arc_condition_code (XEXP (pat, 0)));
4072 else
4073 state->state = 5;
4074 }
4075 }
4076}
4077
4078/* Update *STATE as we would when we emit INSN. */
4079
4080static void
b3458f61 4081arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
526b7aee 4082{
53ea364f
JR
4083 enum attr_type type;
4084
526b7aee
SV
4085 if (LABEL_P (insn))
4086 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
4087 else if (JUMP_P (insn)
4088 && GET_CODE (PATTERN (insn)) != ADDR_VEC
4089 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
53ea364f
JR
4090 && ((type = get_attr_type (insn)) == TYPE_BRANCH
4091 || (type == TYPE_UNCOND_BRANCH
1ea1e1b5
JR
4092 /* ??? Maybe should also handle TYPE_RETURN here,
4093 but we don't have a testcase for that. */
53ea364f 4094 && ARC_CCFSM_BRANCH_DELETED_P (state))))
526b7aee
SV
4095 {
4096 if (ARC_CCFSM_BRANCH_DELETED_P (state))
4097 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
4098 else
4099 {
4100 rtx src = SET_SRC (PATTERN (insn));
4101 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
4102 insn, state);
4103 }
4104 }
4105 else if (arc_ccfsm_current.state == 5)
4106 arc_ccfsm_current.state = 0;
4107}
4108
4109/* Return true if the current insn, which is a conditional branch, is to be
4110 deleted. */
4111
4112bool
4113arc_ccfsm_branch_deleted_p (void)
4114{
4115 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
4116}
4117
4118/* Record a branch isn't output because subsequent insns can be
4119 conditionalized. */
4120
4121void
4122arc_ccfsm_record_branch_deleted (void)
4123{
4124 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
4125}
4126
4127/* During insn output, indicate if the current insn is predicated. */
4128
4129bool
4130arc_ccfsm_cond_exec_p (void)
4131{
4132 return (cfun->machine->prescan_initialized
4133 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
4134}
4135
4136/* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4137 and look inside SEQUENCEs. */
4138
b3458f61
DM
4139static rtx_insn *
4140arc_next_active_insn (rtx_insn *insn, struct arc_ccfsm *statep)
526b7aee
SV
4141{
4142 rtx pat;
4143
4144 do
4145 {
4146 if (statep)
4147 arc_ccfsm_post_advance (insn, statep);
4148 insn = NEXT_INSN (insn);
4149 if (!insn || BARRIER_P (insn))
b3458f61 4150 return NULL;
526b7aee
SV
4151 if (statep)
4152 arc_ccfsm_advance (insn, statep);
4153 }
4154 while (NOTE_P (insn)
4155 || (cfun->machine->arc_reorg_started
4156 && LABEL_P (insn) && !label_to_alignment (insn))
4157 || (NONJUMP_INSN_P (insn)
4158 && (GET_CODE (PATTERN (insn)) == USE
4159 || GET_CODE (PATTERN (insn)) == CLOBBER)));
4160 if (!LABEL_P (insn))
4161 {
4162 gcc_assert (INSN_P (insn));
4163 pat = PATTERN (insn);
4164 if (GET_CODE (pat) == ADDR_VEC || GET_CODE (pat) == ADDR_DIFF_VEC)
b3458f61 4165 return NULL;
526b7aee 4166 if (GET_CODE (pat) == SEQUENCE)
b3458f61 4167 return as_a <rtx_insn *> (XVECEXP (pat, 0, 0));
526b7aee
SV
4168 }
4169 return insn;
4170}
4171
4172/* When deciding if an insn should be output short, we want to know something
4173 about the following insns:
4174 - if another insn follows which we know we can output as a short insn
4175 before an alignment-sensitive point, we can output this insn short:
4176 the decision about the eventual alignment can be postponed.
4177 - if a to-be-aligned label comes next, we should output this insn such
4178 as to get / preserve 4-byte alignment.
4179 - if a likely branch without delay slot insn, or a call with an immediately
4180 following short insn comes next, we should out output this insn such as to
4181 get / preserve 2 mod 4 unalignment.
4182 - do the same for a not completely unlikely branch with a short insn
4183 following before any other branch / label.
4184 - in order to decide if we are actually looking at a branch, we need to
4185 call arc_ccfsm_advance.
4186 - in order to decide if we are looking at a short insn, we should know
4187 if it is conditionalized. To a first order of approximation this is
4188 the case if the state from arc_ccfsm_advance from before this insn
4189 indicates the insn is conditionalized. However, a further refinement
4190 could be to not conditionalize an insn if the destination register(s)
4191 is/are dead in the non-executed case. */
4192/* Return non-zero if INSN should be output as a short insn. UNALIGN is
4193 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4194 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4195
4196int
b3458f61 4197arc_verify_short (rtx_insn *insn, int, int check_attr)
526b7aee
SV
4198{
4199 enum attr_iscompact iscompact;
4200 struct machine_function *machine;
4201
4202 if (check_attr > 0)
4203 {
4204 iscompact = get_attr_iscompact (insn);
4205 if (iscompact == ISCOMPACT_FALSE)
4206 return 0;
4207 }
4208 machine = cfun->machine;
4209
4210 if (machine->force_short_suffix >= 0)
4211 return machine->force_short_suffix;
4212
4213 return (get_attr_length (insn) & 2) != 0;
4214}
4215
4216/* When outputting an instruction (alternative) that can potentially be short,
4217 output the short suffix if the insn is in fact short, and update
4218 cfun->machine->unalign accordingly. */
4219
4220static void
4221output_short_suffix (FILE *file)
4222{
b3458f61 4223 rtx_insn *insn = current_output_insn;
526b7aee
SV
4224
4225 if (arc_verify_short (insn, cfun->machine->unalign, 1))
4226 {
4227 fprintf (file, "_s");
4228 cfun->machine->unalign ^= 2;
4229 }
4230 /* Restore recog_operand. */
4231 extract_insn_cached (insn);
4232}
4233
4234/* Implement FINAL_PRESCAN_INSN. */
4235
4236void
b3458f61 4237arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
526b7aee
SV
4238 int noperands ATTRIBUTE_UNUSED)
4239{
4240 if (TARGET_DUMPISIZE)
4241 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
4242
4243 /* Output a nop if necessary to prevent a hazard.
4244 Don't do this for delay slots: inserting a nop would
4245 alter semantics, and the only time we would find a hazard is for a
4246 call function result - and in that case, the hazard is spurious to
4247 start with. */
4248 if (PREV_INSN (insn)
4249 && PREV_INSN (NEXT_INSN (insn)) == insn
4250 && arc_hazard (prev_real_insn (insn), insn))
4251 {
4252 current_output_insn =
4253 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn)));
4254 final_scan_insn (current_output_insn, asm_out_file, optimize, 1, NULL);
b3458f61 4255 current_output_insn = insn;
526b7aee
SV
4256 }
4257 /* Restore extraction data which might have been clobbered by arc_hazard. */
4258 extract_constrain_insn_cached (insn);
4259
4260 if (!cfun->machine->prescan_initialized)
4261 {
4262 /* Clear lingering state from branch shortening. */
4263 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
4264 cfun->machine->prescan_initialized = 1;
4265 }
4266 arc_ccfsm_advance (insn, &arc_ccfsm_current);
4267
4268 cfun->machine->size_reason = 0;
4269}
4270
4271/* Given FROM and TO register numbers, say whether this elimination is allowed.
4272 Frame pointer elimination is automatically handled.
4273
4274 All eliminations are permissible. If we need a frame
4275 pointer, we must eliminate ARG_POINTER_REGNUM into
4276 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4277
4278static bool
4279arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
4280{
4281 return to == FRAME_POINTER_REGNUM || !arc_frame_pointer_required ();
4282}
4283
4284/* Define the offset between two registers, one to be eliminated, and
4285 the other its replacement, at the start of a routine. */
4286
4287int
4288arc_initial_elimination_offset (int from, int to)
4289{
4290 if (! cfun->machine->frame_info.initialized)
4291 arc_compute_frame_size (get_frame_size ());
4292
4293 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
4294 {
4295 return (cfun->machine->frame_info.extra_size
4296 + cfun->machine->frame_info.reg_size);
4297 }
4298
4299 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
4300 {
4301 return (cfun->machine->frame_info.total_size
4302 - cfun->machine->frame_info.pretend_size);
4303 }
4304
4305 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
4306 {
4307 return (cfun->machine->frame_info.total_size
4308 - (cfun->machine->frame_info.pretend_size
4309 + cfun->machine->frame_info.extra_size
4310 + cfun->machine->frame_info.reg_size));
4311 }
4312
4313 gcc_unreachable ();
4314}
4315
4316static bool
4317arc_frame_pointer_required (void)
4318{
4319 return cfun->calls_alloca;
4320}
4321
4322
4323/* Return the destination address of a branch. */
4324
4325int
4326branch_dest (rtx branch)
4327{
4328 rtx pat = PATTERN (branch);
4329 rtx dest = (GET_CODE (pat) == PARALLEL
4330 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
4331 int dest_uid;
4332
4333 if (GET_CODE (dest) == IF_THEN_ELSE)
4334 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
4335
4336 dest = XEXP (dest, 0);
4337 dest_uid = INSN_UID (dest);
4338
4339 return INSN_ADDRESSES (dest_uid);
4340}
4341
4342
5719867d 4343/* Implement TARGET_ENCODE_SECTION_INFO hook. */
526b7aee
SV
4344
4345static void
4346arc_encode_section_info (tree decl, rtx rtl, int first)
4347{
4348 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4349 This clears machine specific flags, so has to come first. */
4350 default_encode_section_info (decl, rtl, first);
4351
4352 /* Check if it is a function, and whether it has the
4353 [long/medium/short]_call attribute specified. */
4354 if (TREE_CODE (decl) == FUNCTION_DECL)
4355 {
4356 rtx symbol = XEXP (rtl, 0);
4357 int flags = SYMBOL_REF_FLAGS (symbol);
4358
4359 tree attr = (TREE_TYPE (decl) != error_mark_node
4360 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
4361 tree long_call_attr = lookup_attribute ("long_call", attr);
4362 tree medium_call_attr = lookup_attribute ("medium_call", attr);
4363 tree short_call_attr = lookup_attribute ("short_call", attr);
4364
4365 if (long_call_attr != NULL_TREE)
4366 flags |= SYMBOL_FLAG_LONG_CALL;
4367 else if (medium_call_attr != NULL_TREE)
4368 flags |= SYMBOL_FLAG_MEDIUM_CALL;
4369 else if (short_call_attr != NULL_TREE)
4370 flags |= SYMBOL_FLAG_SHORT_CALL;
4371
4372 SYMBOL_REF_FLAGS (symbol) = flags;
4373 }
4d03dc2f
JR
4374 else if (TREE_CODE (decl) == VAR_DECL)
4375 {
4376 rtx symbol = XEXP (rtl, 0);
4377
4378 tree attr = (TREE_TYPE (decl) != error_mark_node
4379 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
4380
4381 tree sec_attr = lookup_attribute ("section", attr);
4382 if (sec_attr)
4383 {
4384 const char *sec_name
4385 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
4386 if (strcmp (sec_name, ".cmem") == 0
4387 || strcmp (sec_name, ".cmem_shared") == 0
4388 || strcmp (sec_name, ".cmem_private") == 0)
4389 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
4390 }
4391 }
526b7aee
SV
4392}
4393
4394/* This is how to output a definition of an internal numbered label where
4395 PREFIX is the class of label and NUM is the number within the class. */
4396
4397static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
4398{
4399 if (cfun)
4400 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
4401 default_internal_label (stream, prefix, labelno);
4402}
4403
4404/* Set the cpu type and print out other fancy things,
4405 at the top of the file. */
4406
4407static void arc_file_start (void)
4408{
4409 default_file_start ();
4410 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
4411}
4412
4413/* Cost functions. */
4414
4415/* Compute a (partial) cost for rtx X. Return true if the complete
4416 cost has been computed, and false if subexpressions should be
4417 scanned. In either case, *TOTAL contains the cost result. */
4418
4419static bool
e548c9df
AM
4420arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
4421 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
526b7aee 4422{
e548c9df
AM
4423 int code = GET_CODE (x);
4424
526b7aee
SV
4425 switch (code)
4426 {
4427 /* Small integers are as cheap as registers. */
4428 case CONST_INT:
4429 {
4430 bool nolimm = false; /* Can we do without long immediate? */
4431 bool fast = false; /* Is the result available immediately? */
4432 bool condexec = false; /* Does this allow conditiobnal execution? */
4433 bool compact = false; /* Is a 16 bit opcode available? */
4434 /* CONDEXEC also implies that we can have an unconditional
4435 3-address operation. */
4436
4437 nolimm = compact = condexec = false;
4438 if (UNSIGNED_INT6 (INTVAL (x)))
4439 nolimm = condexec = compact = true;
4440 else
4441 {
4442 if (SMALL_INT (INTVAL (x)))
4443 nolimm = fast = true;
4444 switch (outer_code)
4445 {
4446 case AND: /* bclr, bmsk, ext[bw] */
4447 if (satisfies_constraint_Ccp (x) /* bclr */
4448 || satisfies_constraint_C1p (x) /* bmsk */)
4449 nolimm = fast = condexec = compact = true;
4450 break;
4451 case IOR: /* bset */
4452 if (satisfies_constraint_C0p (x)) /* bset */
4453 nolimm = fast = condexec = compact = true;
4454 break;
4455 case XOR:
4456 if (satisfies_constraint_C0p (x)) /* bxor */
4457 nolimm = fast = condexec = true;
4458 break;
4459 case SET:
4460 if (satisfies_constraint_Crr (x)) /* ror b,u6 */
4461 nolimm = true;
4462 default:
4463 break;
4464 }
4465 }
4466 /* FIXME: Add target options to attach a small cost if
4467 condexec / compact is not true. */
4468 if (nolimm)
4469 {
4470 *total = 0;
4471 return true;
4472 }
4473 }
4474 /* FALLTHRU */
4475
4476 /* 4 byte values can be fetched as immediate constants -
4477 let's give that the cost of an extra insn. */
4478 case CONST:
4479 case LABEL_REF:
4480 case SYMBOL_REF:
4481 *total = COSTS_N_INSNS (1);
4482 return true;
4483
4484 case CONST_DOUBLE:
4485 {
7d81a567 4486 rtx first, second;
526b7aee
SV
4487
4488 if (TARGET_DPFP)
4489 {
4490 *total = COSTS_N_INSNS (1);
4491 return true;
4492 }
7d81a567
CZ
4493 split_double (x, &first, &second);
4494 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
4495 + !SMALL_INT (INTVAL (second)));
526b7aee
SV
4496 return true;
4497 }
4498
4499 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4500 If we need more than 12 insns to do a multiply, then go out-of-line,
4501 since the call overhead will be < 10% of the cost of the multiply. */
4502 case ASHIFT:
4503 case ASHIFTRT:
4504 case LSHIFTRT:
4505 if (TARGET_BARREL_SHIFTER)
4506 {
4507 /* If we want to shift a constant, we need a LIMM. */
4508 /* ??? when the optimizers want to know if a constant should be
4509 hoisted, they ask for the cost of the constant. OUTER_CODE is
4510 insufficient context for shifts since we don't know which operand
4511 we are looking at. */
4512 if (CONSTANT_P (XEXP (x, 0)))
4513 {
4514 *total += (COSTS_N_INSNS (2)
e548c9df
AM
4515 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
4516 0, speed));
526b7aee
SV
4517 return true;
4518 }
4519 *total = COSTS_N_INSNS (1);
4520 }
4521 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4522 *total = COSTS_N_INSNS (16);
4523 else
4524 {
4525 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
4526 /* ??? want_to_gcse_p can throw negative shift counts at us,
4527 and then panics when it gets a negative cost as result.
4528 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4529 if (*total < 0)
4530 *total = 0;
4531 }
4532 return false;
4533
4534 case DIV:
4535 case UDIV:
4536 if (speed)
4537 *total = COSTS_N_INSNS(30);
4538 else
4539 *total = COSTS_N_INSNS(1);
4540 return false;
4541
4542 case MULT:
4543 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
4544 *total = COSTS_N_INSNS (1);
4545 else if (speed)
4546 *total= arc_multcost;
4547 /* We do not want synth_mult sequences when optimizing
4548 for size. */
f50bb868 4549 else if (TARGET_MUL64_SET || TARGET_ARC700_MPY)
526b7aee
SV
4550 *total = COSTS_N_INSNS (1);
4551 else
4552 *total = COSTS_N_INSNS (2);
4553 return false;
4554 case PLUS:
4555 if (GET_CODE (XEXP (x, 0)) == MULT
4556 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
4557 {
e548c9df
AM
4558 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
4559 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
526b7aee
SV
4560 return true;
4561 }
4562 return false;
4563 case MINUS:
4564 if (GET_CODE (XEXP (x, 1)) == MULT
4565 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
4566 {
e548c9df
AM
4567 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
4568 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
526b7aee
SV
4569 return true;
4570 }
4571 return false;
4572 case COMPARE:
4573 {
4574 rtx op0 = XEXP (x, 0);
4575 rtx op1 = XEXP (x, 1);
4576
4577 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
4578 && XEXP (op0, 1) == const1_rtx)
4579 {
4580 /* btst / bbit0 / bbit1:
4581 Small integers and registers are free; everything else can
4582 be put in a register. */
e548c9df
AM
4583 mode = GET_MODE (XEXP (op0, 0));
4584 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
4585 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
526b7aee
SV
4586 return true;
4587 }
4588 if (GET_CODE (op0) == AND && op1 == const0_rtx
4589 && satisfies_constraint_C1p (XEXP (op0, 1)))
4590 {
4591 /* bmsk.f */
e548c9df 4592 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
526b7aee
SV
4593 return true;
4594 }
4595 /* add.f */
4596 if (GET_CODE (op1) == NEG)
4597 {
4598 /* op0 might be constant, the inside of op1 is rather
4599 unlikely to be so. So swapping the operands might lower
4600 the cost. */
e548c9df
AM
4601 mode = GET_MODE (op0);
4602 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
4603 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
526b7aee
SV
4604 }
4605 return false;
4606 }
4607 case EQ: case NE:
4608 if (outer_code == IF_THEN_ELSE
4609 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
4610 && XEXP (x, 1) == const0_rtx
4611 && XEXP (XEXP (x, 0), 1) == const1_rtx)
4612 {
4613 /* btst / bbit0 / bbit1:
4614 Small integers and registers are free; everything else can
4615 be put in a register. */
4616 rtx op0 = XEXP (x, 0);
4617
e548c9df
AM
4618 mode = GET_MODE (XEXP (op0, 0));
4619 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
4620 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
526b7aee
SV
4621 return true;
4622 }
4623 /* Fall through. */
4624 /* scc_insn expands into two insns. */
4625 case GTU: case GEU: case LEU:
e548c9df 4626 if (mode == SImode)
526b7aee
SV
4627 *total += COSTS_N_INSNS (1);
4628 return false;
4629 case LTU: /* might use adc. */
e548c9df 4630 if (mode == SImode)
526b7aee
SV
4631 *total += COSTS_N_INSNS (1) - 1;
4632 return false;
4633 default:
4634 return false;
4635 }
4636}
4637
28633bbd
CZ
4638/* Helper used by arc_legitimate_pc_offset_p. */
4639
4640static bool
4641arc_needs_pcl_p (rtx x)
4642{
4643 register const char *fmt;
4644 register int i, j;
4645
4646 if ((GET_CODE (x) == UNSPEC)
4647 && (XVECLEN (x, 0) == 1)
4648 && (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF))
4649 switch (XINT (x, 1))
4650 {
4651 case ARC_UNSPEC_GOT:
f5e336b1 4652 case ARC_UNSPEC_GOTOFFPC:
28633bbd
CZ
4653 case UNSPEC_TLS_GD:
4654 case UNSPEC_TLS_IE:
4655 return true;
4656 default:
4657 break;
4658 }
4659
4660 fmt = GET_RTX_FORMAT (GET_CODE (x));
4661 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4662 {
4663 if (fmt[i] == 'e')
4664 {
4665 if (arc_needs_pcl_p (XEXP (x, i)))
4666 return true;
4667 }
4668 else if (fmt[i] == 'E')
4669 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4670 if (arc_needs_pcl_p (XVECEXP (x, i, j)))
4671 return true;
4672 }
4673
4674 return false;
4675}
4676
526b7aee
SV
4677/* Return true if ADDR is an address that needs to be expressed as an
4678 explicit sum of pcl + offset. */
4679
4680bool
4681arc_legitimate_pc_offset_p (rtx addr)
4682{
4683 if (GET_CODE (addr) != CONST)
4684 return false;
28633bbd
CZ
4685
4686 return arc_needs_pcl_p (addr);
526b7aee
SV
4687}
4688
4689/* Return true if ADDR is a valid pic address.
4690 A valid pic address on arc should look like
4691 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
4692
4693bool
4694arc_legitimate_pic_addr_p (rtx addr)
4695{
4696 if (GET_CODE (addr) == LABEL_REF)
4697 return true;
4698 if (GET_CODE (addr) != CONST)
4699 return false;
4700
4701 addr = XEXP (addr, 0);
4702
4703
4704 if (GET_CODE (addr) == PLUS)
4705 {
4706 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
4707 return false;
4708 addr = XEXP (addr, 0);
4709 }
4710
4711 if (GET_CODE (addr) != UNSPEC
4712 || XVECLEN (addr, 0) != 1)
4713 return false;
4714
f5e336b1 4715 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
526b7aee 4716 if (XINT (addr, 1) != ARC_UNSPEC_GOT
28633bbd 4717 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
f5e336b1 4718 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
28633bbd
CZ
4719 && XINT (addr, 1) != UNSPEC_TLS_GD
4720 && XINT (addr, 1) != UNSPEC_TLS_IE)
526b7aee
SV
4721 return false;
4722
4723 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
4724 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
4725 return false;
4726
4727 return true;
4728}
4729
4730
4731
4732/* Return true if OP contains a symbol reference. */
4733
4734static bool
4735symbolic_reference_mentioned_p (rtx op)
4736{
4737 register const char *fmt;
4738 register int i;
4739
4740 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
4741 return true;
4742
4743 fmt = GET_RTX_FORMAT (GET_CODE (op));
4744 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
4745 {
4746 if (fmt[i] == 'E')
4747 {
4748 register int j;
4749
4750 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
4751 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
4752 return true;
4753 }
4754
4755 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
4756 return true;
4757 }
4758
4759 return false;
4760}
4761
4762/* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
4763 If SKIP_LOCAL is true, skip symbols that bind locally.
4764 This is used further down in this file, and, without SKIP_LOCAL,
4765 in the addsi3 / subsi3 expanders when generating PIC code. */
4766
4767bool
4768arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
4769{
4770 register const char *fmt;
4771 register int i;
4772
4773 if (GET_CODE(op) == UNSPEC)
4774 return false;
4775
4776 if (GET_CODE (op) == SYMBOL_REF)
4777 {
28633bbd
CZ
4778 if (SYMBOL_REF_TLS_MODEL (op))
4779 return true;
4780 if (!flag_pic)
4781 return false;
526b7aee
SV
4782 tree decl = SYMBOL_REF_DECL (op);
4783 return !skip_local || !decl || !default_binds_local_p (decl);
4784 }
4785
4786 fmt = GET_RTX_FORMAT (GET_CODE (op));
4787 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
4788 {
4789 if (fmt[i] == 'E')
4790 {
4791 register int j;
4792
4793 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
4794 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
4795 skip_local))
4796 return true;
4797 }
4798
4799 else if (fmt[i] == 'e'
4800 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
4801 skip_local))
4802 return true;
4803 }
4804
4805 return false;
4806}
4807
28633bbd
CZ
4808/* Get the thread pointer. */
4809
4810static rtx
4811arc_get_tp (void)
4812{
4813 /* If arc_tp_regno has been set, we can use that hard register
4814 directly as a base register. */
4815 if (arc_tp_regno != -1)
4816 return gen_rtx_REG (Pmode, arc_tp_regno);
4817
4818 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
4819 conflicts with function arguments / results. */
4820 rtx reg = gen_reg_rtx (Pmode);
4821 emit_insn (gen_tls_load_tp_soft ());
4822 emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG));
4823 return reg;
4824}
4825
4826/* Helper to be used by TLS Global dynamic model. */
4827
4828static rtx
4829arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
4830{
4831 rtx r0 = gen_rtx_REG (Pmode, R0_REG);
4832 rtx insns;
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
4849 insns = get_insns ();
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;
6200 default:
40fecdd6
JM
6201 fatal_error (input_location,
6202 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
526b7aee
SV
6203 break;
6204 }
6205 return false;
6206}
6207
6208/* Return true if it is ok to make a tail-call to DECL. */
6209
6210static bool
6211arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
6212 tree exp ATTRIBUTE_UNUSED)
6213{
6214 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6215 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
6216 return false;
6217
6218 /* Everything else is ok. */
6219 return true;
6220}
6221
6222/* Output code to add DELTA to the first argument, and then jump
6223 to FUNCTION. Used for C++ multiple inheritance. */
6224
6225static void
6226arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6227 HOST_WIDE_INT delta,
6228 HOST_WIDE_INT vcall_offset,
6229 tree function)
6230{
6231 int mi_delta = delta;
6232 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
6233 int shift = 0;
6234 int this_regno
6235 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
6236 rtx fnaddr;
6237
6238 if (mi_delta < 0)
6239 mi_delta = - mi_delta;
6240
6241 /* Add DELTA. When possible use a plain add, otherwise load it into
6242 a register first. */
6243
6244 while (mi_delta != 0)
6245 {
6246 if ((mi_delta & (3 << shift)) == 0)
6247 shift += 2;
6248 else
6249 {
6250 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
6251 mi_op, reg_names[this_regno], reg_names[this_regno],
6252 mi_delta & (0xff << shift));
6253 mi_delta &= ~(0xff << shift);
6254 shift += 8;
6255 }
6256 }
6257
6258 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6259 if (vcall_offset != 0)
6260 {
6261 /* ld r12,[this] --> temp = *this
6262 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6263 ld r12,[r12]
6264 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6265 asm_fprintf (file, "\tld\t%s, [%s]\n",
6266 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
dfca07ea 6267 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
526b7aee
SV
6268 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
6269 asm_fprintf (file, "\tld\t%s, [%s]\n",
6270 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
6271 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
6272 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
6273 }
6274
6275 fnaddr = XEXP (DECL_RTL (function), 0);
6276
6277 if (arc_is_longcall_p (fnaddr))
6278 fputs ("\tj\t", file);
6279 else
6280 fputs ("\tb\t", file);
6281 assemble_name (file, XSTR (fnaddr, 0));
6282 fputc ('\n', file);
6283}
6284
6285/* Return true if a 32 bit "long_call" should be generated for
6286 this calling SYM_REF. We generate a long_call if the function:
6287
6288 a. has an __attribute__((long call))
6289 or b. the -mlong-calls command line switch has been specified
6290
6291 However we do not generate a long call if the function has an
6292 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6293
6294 This function will be called by C fragments contained in the machine
6295 description file. */
6296
6297bool
6298arc_is_longcall_p (rtx sym_ref)
6299{
6300 if (GET_CODE (sym_ref) != SYMBOL_REF)
6301 return false;
6302
6303 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
6304 || (TARGET_LONG_CALLS_SET
6305 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
6306 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6307
6308}
6309
6310/* Likewise for short calls. */
6311
6312bool
6313arc_is_shortcall_p (rtx sym_ref)
6314{
6315 if (GET_CODE (sym_ref) != SYMBOL_REF)
6316 return false;
6317
6318 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
6319 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
6320 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
6321 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6322
6323}
6324
6325/* Emit profiling code for calling CALLEE. Return true if a special
6326 call pattern needs to be generated. */
6327
6328bool
6329arc_profile_call (rtx callee)
6330{
6331 rtx from = XEXP (DECL_RTL (current_function_decl), 0);
6332
6333 if (TARGET_UCB_MCOUNT)
6334 /* Profiling is done by instrumenting the callee. */
6335 return false;
6336
6337 if (CONSTANT_P (callee))
6338 {
6339 rtx count_ptr
6340 = gen_rtx_CONST (Pmode,
6341 gen_rtx_UNSPEC (Pmode,
6342 gen_rtvec (3, from, callee,
6343 CONST0_RTX (Pmode)),
6344 UNSPEC_PROF));
6345 rtx counter = gen_rtx_MEM (SImode, count_ptr);
6346 /* ??? The increment would better be done atomically, but as there is
6347 no proper hardware support, that would be too expensive. */
6348 emit_move_insn (counter,
6349 force_reg (SImode, plus_constant (SImode, counter, 1)));
6350 return false;
6351 }
6352 else
6353 {
6354 rtx count_list_ptr
6355 = gen_rtx_CONST (Pmode,
6356 gen_rtx_UNSPEC (Pmode,
6357 gen_rtvec (3, from, CONST0_RTX (Pmode),
6358 CONST0_RTX (Pmode)),
6359 UNSPEC_PROF));
6360 emit_move_insn (gen_rtx_REG (Pmode, 8), count_list_ptr);
6361 emit_move_insn (gen_rtx_REG (Pmode, 9), callee);
6362 return true;
6363 }
6364}
6365
6366/* Worker function for TARGET_RETURN_IN_MEMORY. */
6367
6368static bool
6369arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6370{
6371 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
6372 return true;
6373 else
6374 {
6375 HOST_WIDE_INT size = int_size_in_bytes (type);
f50bb868 6376 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
526b7aee
SV
6377 }
6378}
6379
6380
6381/* This was in rtlanal.c, and can go in there when we decide we want
6382 to submit the change for inclusion in the GCC tree. */
6383/* Like note_stores, but allow the callback to have side effects on the rtl
6384 (like the note_stores of yore):
6385 Call FUN on each register or MEM that is stored into or clobbered by X.
6386 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6387 ignored by note_stores, but passed to FUN.
6388 FUN may alter parts of the RTL.
6389
6390 FUN receives three arguments:
6391 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6392 2. the SET or CLOBBER rtx that does the store,
6393 3. the pointer DATA provided to note_stores.
6394
6395 If the item being stored in or clobbered is a SUBREG of a hard register,
6396 the SUBREG will be passed. */
6397
6398/* For now. */ static
6399void
6400walk_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
6401{
6402 int i;
6403
6404 if (GET_CODE (x) == COND_EXEC)
6405 x = COND_EXEC_CODE (x);
6406
6407 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
6408 {
6409 rtx dest = SET_DEST (x);
6410
6411 while ((GET_CODE (dest) == SUBREG
6412 && (!REG_P (SUBREG_REG (dest))
6413 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
6414 || GET_CODE (dest) == ZERO_EXTRACT
6415 || GET_CODE (dest) == STRICT_LOW_PART)
6416 dest = XEXP (dest, 0);
6417
6418 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6419 each of whose first operand is a register. */
6420 if (GET_CODE (dest) == PARALLEL)
6421 {
6422 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
6423 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
6424 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
6425 }
6426 else
6427 (*fun) (dest, x, data);
6428 }
6429
6430 else if (GET_CODE (x) == PARALLEL)
6431 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6432 walk_stores (XVECEXP (x, 0, i), fun, data);
6433}
6434
6435static bool
6436arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
ef4bddc2 6437 machine_mode mode ATTRIBUTE_UNUSED,
526b7aee
SV
6438 const_tree type,
6439 bool named ATTRIBUTE_UNUSED)
6440{
6441 return (type != 0
6442 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
6443 || TREE_ADDRESSABLE (type)));
6444}
6445
1d0216c8
RS
6446/* Implement TARGET_CAN_USE_DOLOOP_P. */
6447
6448static bool
807e902e 6449arc_can_use_doloop_p (const widest_int &iterations, const widest_int &,
1d0216c8
RS
6450 unsigned int loop_depth, bool entered_at_top)
6451{
6452 if (loop_depth > 1)
6453 return false;
6454 /* Setting up the loop with two sr instructions costs 6 cycles. */
6455 if (TARGET_ARC700
6456 && !entered_at_top
807e902e
KZ
6457 && wi::gtu_p (iterations, 0)
6458 && wi::leu_p (iterations, flag_pic ? 6 : 3))
1d0216c8
RS
6459 return false;
6460 return true;
6461}
526b7aee
SV
6462
6463/* NULL if INSN insn is valid within a low-overhead loop.
6464 Otherwise return why doloop cannot be applied. */
6465
6466static const char *
ac44248e 6467arc_invalid_within_doloop (const rtx_insn *insn)
526b7aee
SV
6468{
6469 if (CALL_P (insn))
6470 return "Function call in the loop.";
6471 return NULL;
6472}
6473
f50bb868
CZ
6474/* The same functionality as arc_hazard. It is called in machine
6475 reorg before any other optimization. Hence, the NOP size is taken
6476 into account when doing branch shortening. */
6477
6478static void
6479workaround_arc_anomaly (void)
6480{
6481 rtx_insn *insn, *succ0;
6482
6483 /* For any architecture: call arc_hazard here. */
6484 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6485 {
6486 succ0 = next_real_insn (insn);
6487 if (arc_hazard (insn, succ0))
6488 {
6489 emit_insn_before (gen_nopv (), succ0);
6490 }
6491 }
6492}
6493
526b7aee
SV
6494static int arc_reorg_in_progress = 0;
6495
6496/* ARC's machince specific reorg function. */
6497
6498static void
6499arc_reorg (void)
6500{
b3458f61
DM
6501 rtx_insn *insn;
6502 rtx pattern;
526b7aee
SV
6503 rtx pc_target;
6504 long offset;
6505 int changed;
6506
f50bb868
CZ
6507 workaround_arc_anomaly ();
6508
526b7aee
SV
6509 cfun->machine->arc_reorg_started = 1;
6510 arc_reorg_in_progress = 1;
6511
6512 /* Emit special sections for profiling. */
6513 if (crtl->profile)
6514 {
6515 section *save_text_section;
b3458f61 6516 rtx_insn *insn;
526b7aee
SV
6517 int size = get_max_uid () >> 4;
6518 htab_t htab = htab_create (size, unspec_prof_hash, unspec_prof_htab_eq,
6519 NULL);
6520
6521 save_text_section = in_section;
6522 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6523 if (NONJUMP_INSN_P (insn))
6524 walk_stores (PATTERN (insn), write_profile_sections, htab);
6525 if (htab_elements (htab))
6526 in_section = 0;
6527 switch_to_section (save_text_section);
6528 htab_delete (htab);
6529 }
6530
6531 /* Link up loop ends with their loop start. */
6532 {
6533 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6534 if (GET_CODE (insn) == JUMP_INSN
6535 && recog_memoized (insn) == CODE_FOR_doloop_end_i)
6536 {
b3458f61
DM
6537 rtx_insn *top_label
6538 = as_a <rtx_insn *> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0));
526b7aee 6539 rtx num = GEN_INT (CODE_LABEL_NUMBER (top_label));
b3458f61
DM
6540 rtx_insn *lp, *prev = prev_nonnote_insn (top_label);
6541 rtx_insn *lp_simple = NULL;
6542 rtx_insn *next = NULL;
526b7aee
SV
6543 rtx op0 = XEXP (XVECEXP (PATTERN (insn), 0, 1), 0);
6544 HOST_WIDE_INT loop_end_id
6545 = -INTVAL (XEXP (XVECEXP (PATTERN (insn), 0, 4), 0));
6546 int seen_label = 0;
6547
6548 for (lp = prev;
6549 (lp && NONJUMP_INSN_P (lp)
6550 && recog_memoized (lp) != CODE_FOR_doloop_begin_i);
6551 lp = prev_nonnote_insn (lp))
6552 ;
6553 if (!lp || !NONJUMP_INSN_P (lp)
6554 || dead_or_set_regno_p (lp, LP_COUNT))
6555 {
b3458f61 6556 for (prev = next = insn, lp = NULL ; prev || next;)
526b7aee
SV
6557 {
6558 if (prev)
6559 {
6560 if (NONJUMP_INSN_P (prev)
6561 && recog_memoized (prev) == CODE_FOR_doloop_begin_i
6562 && (INTVAL (XEXP (XVECEXP (PATTERN (prev), 0, 5), 0))
6563 == loop_end_id))
6564 {
6565 lp = prev;
6566 break;
6567 }
6568 else if (LABEL_P (prev))
6569 seen_label = 1;
6570 prev = prev_nonnote_insn (prev);
6571 }
6572 if (next)
6573 {
6574 if (NONJUMP_INSN_P (next)
6575 && recog_memoized (next) == CODE_FOR_doloop_begin_i
6576 && (INTVAL (XEXP (XVECEXP (PATTERN (next), 0, 5), 0))
6577 == loop_end_id))
6578 {
6579 lp = next;
6580 break;
6581 }
6582 next = next_nonnote_insn (next);
6583 }
6584 }
b3458f61 6585 prev = NULL;
526b7aee
SV
6586 }
6587 else
6588 lp_simple = lp;
6589 if (lp && !dead_or_set_regno_p (lp, LP_COUNT))
6590 {
6591 rtx begin_cnt = XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0);
6592 if (INTVAL (XEXP (XVECEXP (PATTERN (lp), 0, 4), 0)))
6593 /* The loop end insn has been duplicated. That can happen
6594 when there is a conditional block at the very end of
6595 the loop. */
6596 goto failure;
6597 /* If Register allocation failed to allocate to the right
6598 register, There is no point into teaching reload to
6599 fix this up with reloads, as that would cost more
6600 than using an ordinary core register with the
6601 doloop_fallback pattern. */
6602 if ((true_regnum (op0) != LP_COUNT || !REG_P (begin_cnt))
6603 /* Likewise, if the loop setup is evidently inside the loop,
6604 we loose. */
6605 || (!lp_simple && lp != next && !seen_label))
6606 {
6607 remove_insn (lp);
6608 goto failure;
6609 }
6610 /* It is common that the optimizers copy the loop count from
6611 another register, and doloop_begin_i is stuck with the
6612 source of the move. Making doloop_begin_i only accept "l"
6613 is nonsentical, as this then makes reload evict the pseudo
6614 used for the loop end. The underlying cause is that the
6615 optimizers don't understand that the register allocation for
6616 doloop_begin_i should be treated as part of the loop.
6617 Try to work around this problem by verifying the previous
6618 move exists. */
6619 if (true_regnum (begin_cnt) != LP_COUNT)
6620 {
b3458f61
DM
6621 rtx_insn *mov;
6622 rtx set, note;
526b7aee
SV
6623
6624 for (mov = prev_nonnote_insn (lp); mov;
6625 mov = prev_nonnote_insn (mov))
6626 {
6627 if (!NONJUMP_INSN_P (mov))
6628 mov = 0;
6629 else if ((set = single_set (mov))
6630 && rtx_equal_p (SET_SRC (set), begin_cnt)
6631 && rtx_equal_p (SET_DEST (set), op0))
6632 break;
6633 }
6634 if (mov)
6635 {
6636 XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0) = op0;
6637 note = find_regno_note (lp, REG_DEAD, REGNO (begin_cnt));
6638 if (note)
6639 remove_note (lp, note);
6640 }
6641 else
6642 {
6643 remove_insn (lp);
6644 goto failure;
6645 }
6646 }
6647 XEXP (XVECEXP (PATTERN (insn), 0, 4), 0) = num;
6648 XEXP (XVECEXP (PATTERN (lp), 0, 4), 0) = num;
6649 if (next == lp)
6650 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const2_rtx;
6651 else if (!lp_simple)
6652 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const1_rtx;
6653 else if (prev != lp)
6654 {
6655 remove_insn (lp);
6656 add_insn_after (lp, prev, NULL);
6657 }
6658 if (!lp_simple)
6659 {
6660 XEXP (XVECEXP (PATTERN (lp), 0, 7), 0)
6661 = gen_rtx_LABEL_REF (Pmode, top_label);
6662 add_reg_note (lp, REG_LABEL_OPERAND, top_label);
6663 LABEL_NUSES (top_label)++;
6664 }
6665 /* We can avoid tedious loop start / end setting for empty loops
6666 be merely setting the loop count to its final value. */
6667 if (next_active_insn (top_label) == insn)
6668 {
6669 rtx lc_set
f7df4a84 6670 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp), 0, 3), 0),
526b7aee
SV
6671 const0_rtx);
6672
b3458f61 6673 rtx_insn *lc_set_insn = emit_insn_before (lc_set, insn);
526b7aee
SV
6674 delete_insn (lp);
6675 delete_insn (insn);
b3458f61 6676 insn = lc_set_insn;
526b7aee
SV
6677 }
6678 /* If the loop is non-empty with zero length, we can't make it
6679 a zero-overhead loop. That can happen for empty asms. */
6680 else
6681 {
b3458f61 6682 rtx_insn *scan;
526b7aee
SV
6683
6684 for (scan = top_label;
6685 (scan && scan != insn
6686 && (!NONJUMP_INSN_P (scan) || !get_attr_length (scan)));
6687 scan = NEXT_INSN (scan));
6688 if (scan == insn)
6689 {
6690 remove_insn (lp);
6691 goto failure;
6692 }
6693 }
6694 }
6695 else
6696 {
6697 /* Sometimes the loop optimizer makes a complete hash of the
6698 loop. If it were only that the loop is not entered at the
6699 top, we could fix this up by setting LP_START with SR .
6700 However, if we can't find the loop begin were it should be,
6701 chances are that it does not even dominate the loop, but is
6702 inside the loop instead. Using SR there would kill
6703 performance.
6704 We use the doloop_fallback pattern here, which executes
6705 in two cycles on the ARC700 when predicted correctly. */
6706 failure:
6707 if (!REG_P (op0))
6708 {
6709 rtx op3 = XEXP (XVECEXP (PATTERN (insn), 0, 5), 0);
6710
6711 emit_insn_before (gen_move_insn (op3, op0), insn);
6712 PATTERN (insn)
6713 = gen_doloop_fallback_m (op3, JUMP_LABEL (insn), op0);
6714 }
6715 else
6716 XVEC (PATTERN (insn), 0)
6717 = gen_rtvec (2, XVECEXP (PATTERN (insn), 0, 0),
6718 XVECEXP (PATTERN (insn), 0, 1));
6719 INSN_CODE (insn) = -1;
6720 }
6721 }
6722 }
6723
6724/* FIXME: should anticipate ccfsm action, generate special patterns for
6725 to-be-deleted branches that have no delay slot and have at least the
6726 length of the size increase forced on other insns that are conditionalized.
6727 This can also have an insn_list inside that enumerates insns which are
6728 not actually conditionalized because the destinations are dead in the
6729 not-execute case.
6730 Could also tag branches that we want to be unaligned if they get no delay
6731 slot, or even ones that we don't want to do delay slot sheduling for
6732 because we can unalign them.
6733
6734 However, there are cases when conditional execution is only possible after
6735 delay slot scheduling:
6736
6737 - If a delay slot is filled with a nocond/set insn from above, the previous
6738 basic block can become elegible for conditional execution.
6739 - If a delay slot is filled with a nocond insn from the fall-through path,
6740 the branch with that delay slot can become eligble for conditional
6741 execution (however, with the same sort of data flow analysis that dbr
6742 does, we could have figured out before that we don't need to
6743 conditionalize this insn.)
6744 - If a delay slot insn is filled with an insn from the target, the
6745 target label gets its uses decremented (even deleted if falling to zero),
6746 thus possibly creating more condexec opportunities there.
6747 Therefore, we should still be prepared to apply condexec optimization on
6748 non-prepared branches if the size increase of conditionalized insns is no
6749 more than the size saved from eliminating the branch. An invocation option
6750 could also be used to reserve a bit of extra size for condbranches so that
6751 this'll work more often (could also test in arc_reorg if the block is
6752 'close enough' to be eligible for condexec to make this likely, and
6753 estimate required size increase). */
6754 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
6755 if (TARGET_NO_BRCC_SET)
6756 return;
6757
6758 do
6759 {
6760 init_insn_lengths();
6761 changed = 0;
6762
6763 if (optimize > 1 && !TARGET_NO_COND_EXEC)
6764 {
6765 arc_ifcvt ();
6766 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
6767 df_finish_pass ((flags & TODO_df_verify) != 0);
6768 }
6769
6770 /* Call shorten_branches to calculate the insn lengths. */
6771 shorten_branches (get_insns());
6772 cfun->machine->ccfsm_current_insn = NULL_RTX;
6773
6774 if (!INSN_ADDRESSES_SET_P())
40fecdd6 6775 fatal_error (input_location, "Insn addresses not set after shorten_branches");
526b7aee
SV
6776
6777 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6778 {
6779 rtx label;
6780 enum attr_type insn_type;
6781
6782 /* If a non-jump insn (or a casesi jump table), continue. */
6783 if (GET_CODE (insn) != JUMP_INSN ||
6784 GET_CODE (PATTERN (insn)) == ADDR_VEC
6785 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
6786 continue;
6787
6788 /* If we already have a brcc, note if it is suitable for brcc_s.
6789 Be a bit generous with the brcc_s range so that we can take
6790 advantage of any code shortening from delay slot scheduling. */
6791 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
6792 {
6793 rtx pat = PATTERN (insn);
6794 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
6795 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
6796
6797 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6798 if ((offset >= -140 && offset < 140)
6799 && rtx_equal_p (XEXP (op, 1), const0_rtx)
6800 && compact_register_operand (XEXP (op, 0), VOIDmode)
6801 && equality_comparison_operator (op, VOIDmode))
6802 PUT_MODE (*ccp, CC_Zmode);
6803 else if (GET_MODE (*ccp) == CC_Zmode)
6804 PUT_MODE (*ccp, CC_ZNmode);
6805 continue;
6806 }
6807 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
6808 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
6809 continue;
6810
6811 /* OK. so we have a jump insn. */
6812 /* We need to check that it is a bcc. */
6813 /* Bcc => set (pc) (if_then_else ) */
6814 pattern = PATTERN (insn);
6815 if (GET_CODE (pattern) != SET
6816 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
6817 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
6818 continue;
6819
6820 /* Now check if the jump is beyond the s9 range. */
339ba33b 6821 if (CROSSING_JUMP_P (insn))
526b7aee
SV
6822 continue;
6823 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6824
6825 if(offset > 253 || offset < -254)
6826 continue;
6827
6828 pc_target = SET_SRC (pattern);
6829
8f3304d0
CZ
6830 /* Avoid FPU instructions. */
6831 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
6832 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
6833 continue;
6834
526b7aee
SV
6835 /* Now go back and search for the set cc insn. */
6836
6837 label = XEXP (pc_target, 1);
6838
6839 {
b3458f61
DM
6840 rtx pat;
6841 rtx_insn *scan, *link_insn = NULL;
526b7aee
SV
6842
6843 for (scan = PREV_INSN (insn);
6844 scan && GET_CODE (scan) != CODE_LABEL;
6845 scan = PREV_INSN (scan))
6846 {
6847 if (! INSN_P (scan))
6848 continue;
6849 pat = PATTERN (scan);
6850 if (GET_CODE (pat) == SET
6851 && cc_register (SET_DEST (pat), VOIDmode))
6852 {
6853 link_insn = scan;
6854 break;
6855 }
6856 }
8f3304d0 6857 if (!link_insn)
526b7aee
SV
6858 continue;
6859 else
6860 /* Check if this is a data dependency. */
6861 {
6862 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
6863 rtx cmp0, cmp1;
6864
6865 /* Ok this is the set cc. copy args here. */
6866 op = XEXP (pc_target, 0);
6867
6868 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
6869 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
6870 if (GET_CODE (op0) == ZERO_EXTRACT
6871 && XEXP (op0, 1) == const1_rtx
6872 && (GET_CODE (op) == EQ
6873 || GET_CODE (op) == NE))
6874 {
6875 /* btst / b{eq,ne} -> bbit{0,1} */
6876 op0 = XEXP (cmp0, 0);
6877 op1 = XEXP (cmp0, 2);
6878 }
6879 else if (!register_operand (op0, VOIDmode)
6880 || !general_operand (op1, VOIDmode))
6881 continue;
6882 /* Be careful not to break what cmpsfpx_raw is
6883 trying to create for checking equality of
6884 single-precision floats. */
6885 else if (TARGET_SPFP
6886 && GET_MODE (op0) == SFmode
6887 && GET_MODE (op1) == SFmode)
6888 continue;
6889
6890 /* None of the two cmp operands should be set between the
6891 cmp and the branch. */
6892 if (reg_set_between_p (op0, link_insn, insn))
6893 continue;
6894
6895 if (reg_set_between_p (op1, link_insn, insn))
6896 continue;
6897
6898 /* Since the MODE check does not work, check that this is
6899 CC reg's last set location before insn, and also no
6900 instruction between the cmp and branch uses the
6901 condition codes. */
6902 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
6903 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
6904 continue;
6905
6906 /* CC reg should be dead after insn. */
6907 if (!find_regno_note (insn, REG_DEAD, CC_REG))
6908 continue;
6909
6910 op = gen_rtx_fmt_ee (GET_CODE (op),
6911 GET_MODE (op), cmp0, cmp1);
6912 /* If we create a LIMM where there was none before,
6913 we only benefit if we can avoid a scheduling bubble
6914 for the ARC600. Otherwise, we'd only forgo chances
6915 at short insn generation, and risk out-of-range
6916 branches. */
6917 if (!brcc_nolimm_operator (op, VOIDmode)
6918 && !long_immediate_operand (op1, VOIDmode)
6919 && (TARGET_ARC700
6920 || next_active_insn (link_insn) != insn))
6921 continue;
6922
6923 /* Emit bbit / brcc (or brcc_s if possible).
6924 CC_Zmode indicates that brcc_s is possible. */
6925
6926 if (op0 != cmp0)
6927 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
6928 else if ((offset >= -140 && offset < 140)
6929 && rtx_equal_p (op1, const0_rtx)
6930 && compact_register_operand (op0, VOIDmode)
6931 && (GET_CODE (op) == EQ
6932 || GET_CODE (op) == NE))
6933 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
6934 else
6935 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
6936
6937 brcc_insn
6938 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
f7df4a84 6939 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
526b7aee
SV
6940 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
6941 brcc_insn
6942 = gen_rtx_PARALLEL
6943 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
6944 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
6945
6946 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
6947 note = find_reg_note (insn, REG_BR_PROB, 0);
6948 if (note)
6949 {
6950 XEXP (note, 1) = REG_NOTES (brcc_insn);
6951 REG_NOTES (brcc_insn) = note;
6952 }
6953 note = find_reg_note (link_insn, REG_DEAD, op0);
6954 if (note)
6955 {
6956 remove_note (link_insn, note);
6957 XEXP (note, 1) = REG_NOTES (brcc_insn);
6958 REG_NOTES (brcc_insn) = note;
6959 }
6960 note = find_reg_note (link_insn, REG_DEAD, op1);
6961 if (note)
6962 {
6963 XEXP (note, 1) = REG_NOTES (brcc_insn);
6964 REG_NOTES (brcc_insn) = note;
6965 }
6966
6967 changed = 1;
6968
6969 /* Delete the bcc insn. */
6970 set_insn_deleted (insn);
6971
6972 /* Delete the cmp insn. */
6973 set_insn_deleted (link_insn);
6974
6975 }
6976 }
6977 }
6978 /* Clear out insn_addresses. */
6979 INSN_ADDRESSES_FREE ();
6980
6981 } while (changed);
6982
6983 if (INSN_ADDRESSES_SET_P())
40fecdd6 6984 fatal_error (input_location, "insn addresses not freed");
526b7aee
SV
6985
6986 arc_reorg_in_progress = 0;
6987}
6988
6989 /* Check if the operands are valid for BRcc.d generation
6990 Valid Brcc.d patterns are
6991 Brcc.d b, c, s9
6992 Brcc.d b, u6, s9
6993
6994 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
6995 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
6996 does not have a delay slot
6997
6998 Assumed precondition: Second operand is either a register or a u6 value. */
6999
7000bool
7001valid_brcc_with_delay_p (rtx *operands)
7002{
7003 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
7004 return false;
7005 return brcc_nolimm_operator (operands[0], VOIDmode);
7006}
7007
7008/* ??? Hack. This should no really be here. See PR32143. */
7009static bool
7010arc_decl_anon_ns_mem_p (const_tree decl)
7011{
7012 while (1)
7013 {
7014 if (decl == NULL_TREE || decl == error_mark_node)
7015 return false;
7016 if (TREE_CODE (decl) == NAMESPACE_DECL
7017 && DECL_NAME (decl) == NULL_TREE)
7018 return true;
7019 /* Classes and namespaces inside anonymous namespaces have
7020 TREE_PUBLIC == 0, so we can shortcut the search. */
7021 else if (TYPE_P (decl))
7022 return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
7023 else if (TREE_CODE (decl) == NAMESPACE_DECL)
7024 return (TREE_PUBLIC (decl) == 0);
7025 else
7026 decl = DECL_CONTEXT (decl);
7027 }
7028}
7029
7030/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7031 access DECL using %gp_rel(...)($gp). */
7032
7033static bool
7034arc_in_small_data_p (const_tree decl)
7035{
7036 HOST_WIDE_INT size;
7037
7038 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
7039 return false;
7040
7041
7042 /* We don't yet generate small-data references for -mabicalls. See related
7043 -G handling in override_options. */
7044 if (TARGET_NO_SDATA_SET)
7045 return false;
7046
7047 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
7048 {
7049 const char *name;
7050
7051 /* Reject anything that isn't in a known small-data section. */
f961457f 7052 name = DECL_SECTION_NAME (decl);
526b7aee
SV
7053 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
7054 return false;
7055
7056 /* If a symbol is defined externally, the assembler will use the
7057 usual -G rules when deciding how to implement macros. */
7058 if (!DECL_EXTERNAL (decl))
7059 return true;
7060 }
7061 /* Only global variables go into sdata section for now. */
7062 else if (1)
7063 {
7064 /* Don't put constants into the small data section: we want them
7065 to be in ROM rather than RAM. */
7066 if (TREE_CODE (decl) != VAR_DECL)
7067 return false;
7068
7069 if (TREE_READONLY (decl)
7070 && !TREE_SIDE_EFFECTS (decl)
7071 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
7072 return false;
7073
7074 /* TREE_PUBLIC might change after the first call, because of the patch
7075 for PR19238. */
7076 if (default_binds_local_p_1 (decl, 1)
7077 || arc_decl_anon_ns_mem_p (decl))
7078 return false;
7079
7080 /* To ensure -mvolatile-cache works
7081 ld.di does not have a gp-relative variant. */
7082 if (TREE_THIS_VOLATILE (decl))
7083 return false;
7084 }
7085
7086 /* Disable sdata references to weak variables. */
7087 if (DECL_WEAK (decl))
7088 return false;
7089
7090 size = int_size_in_bytes (TREE_TYPE (decl));
7091
7092/* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7093/* return false; */
7094
7095 /* Allow only <=4B long data types into sdata. */
7096 return (size > 0 && size <= 4);
7097}
7098
7099/* Return true if X is a small data address that can be rewritten
7100 as a gp+symref. */
7101
7102static bool
752ae22f 7103arc_rewrite_small_data_p (const_rtx x)
526b7aee
SV
7104{
7105 if (GET_CODE (x) == CONST)
7106 x = XEXP (x, 0);
7107
7108 if (GET_CODE (x) == PLUS)
7109 {
7110 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
7111 x = XEXP (x, 0);
7112 }
7113
28633bbd
CZ
7114 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
7115 {
7116 gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0);
7117 return true;
7118 }
7119 return false;
526b7aee
SV
7120}
7121
526b7aee
SV
7122/* If possible, rewrite OP so that it refers to small data using
7123 explicit relocations. */
7124
7125rtx
7126arc_rewrite_small_data (rtx op)
7127{
7128 op = copy_insn (op);
6733978e
RS
7129 subrtx_ptr_iterator::array_type array;
7130 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
7131 {
7132 rtx *loc = *iter;
7133 if (arc_rewrite_small_data_p (*loc))
7134 {
7135 gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
7136 *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
7137 if (loc != &op)
7138 {
7139 if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
7140 ; /* OK. */
7141 else if (GET_CODE (op) == MEM
7142 && GET_CODE (XEXP (op, 0)) == PLUS
7143 && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
7144 *loc = force_reg (Pmode, *loc);
7145 else
7146 gcc_unreachable ();
7147 }
7148 iter.skip_subrtxes ();
7149 }
7150 else if (GET_CODE (*loc) == PLUS
7151 && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
7152 iter.skip_subrtxes ();
7153 }
526b7aee
SV
7154 return op;
7155}
7156
526b7aee
SV
7157/* Return true if OP refers to small data symbols directly, not through
7158 a PLUS. */
7159
7160bool
ef4bddc2 7161small_data_pattern (rtx op, machine_mode)
526b7aee 7162{
752ae22f
RS
7163 if (GET_CODE (op) == SEQUENCE)
7164 return false;
7165 subrtx_iterator::array_type array;
7166 FOR_EACH_SUBRTX (iter, array, op, ALL)
7167 {
7168 const_rtx x = *iter;
7169 if (GET_CODE (x) == PLUS
7170 && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
7171 iter.skip_subrtxes ();
7172 else if (arc_rewrite_small_data_p (x))
7173 return true;
7174 }
7175 return false;
526b7aee
SV
7176}
7177
7178/* Return true if OP is an acceptable memory operand for ARCompact
7179 16-bit gp-relative load instructions.
7180 op shd look like : [r26, symref@sda]
7181 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7182 */
7183/* volatile cache option still to be handled. */
7184
7185bool
ef4bddc2 7186compact_sda_memory_operand (rtx op, machine_mode mode)
526b7aee
SV
7187{
7188 rtx addr;
7189 int size;
7190
7191 /* Eliminate non-memory operations. */
7192 if (GET_CODE (op) != MEM)
7193 return false;
7194
7195 if (mode == VOIDmode)
7196 mode = GET_MODE (op);
7197
7198 size = GET_MODE_SIZE (mode);
7199
7200 /* dword operations really put out 2 instructions, so eliminate them. */
7201 if (size > UNITS_PER_WORD)
7202 return false;
7203
7204 /* Decode the address now. */
7205 addr = XEXP (op, 0);
7206
7207 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
7208}
7209
7210/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7211
7212void
7213arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
7214 unsigned HOST_WIDE_INT size,
7215 unsigned HOST_WIDE_INT align,
7216 unsigned HOST_WIDE_INT globalize_p)
7217{
7218 int in_small_data = arc_in_small_data_p (decl);
7219
7220 if (in_small_data)
7221 switch_to_section (get_named_section (NULL, ".sbss", 0));
7222 /* named_section (0,".sbss",0); */
7223 else
7224 switch_to_section (bss_section);
7225
7226 if (globalize_p)
7227 (*targetm.asm_out.globalize_label) (stream, name);
7228
7229 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
7230 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
7231 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
7232 ASM_OUTPUT_LABEL (stream, name);
7233
7234 if (size != 0)
7235 ASM_OUTPUT_SKIP (stream, size);
7236}
7237
526b7aee
SV
7238static bool
7239arc_preserve_reload_p (rtx in)
7240{
7241 return (GET_CODE (in) == PLUS
7242 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
7243 && CONST_INT_P (XEXP (in, 1))
7244 && !((INTVAL (XEXP (in, 1)) & 511)));
7245}
7246
7247int
ef4bddc2 7248arc_register_move_cost (machine_mode,
526b7aee
SV
7249 enum reg_class from_class, enum reg_class to_class)
7250{
7251 /* The ARC600 has no bypass for extension registers, hence a nop might be
7252 needed to be inserted after a write so that reads are safe. */
7253 if (TARGET_ARC600)
7254 {
7255 if (to_class == MPY_WRITABLE_CORE_REGS)
7256 return 3;
7257 /* Instructions modifying LP_COUNT need 4 additional cycles before
7258 the register will actually contain the value. */
7259 else if (to_class == LPCOUNT_REG)
7260 return 6;
7261 else if (to_class == WRITABLE_CORE_REGS)
7262 return 6;
7263 }
7264
7265 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7266 if (TARGET_ARC700
7267 && (from_class == LPCOUNT_REG || from_class == ALL_CORE_REGS
7268 || from_class == WRITABLE_CORE_REGS))
7269 return 8;
7270
7271 /* Force an attempt to 'mov Dy,Dx' to spill. */
7272 if (TARGET_ARC700 && TARGET_DPFP
7273 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
7274 return 100;
7275
7276 return 2;
7277}
7278
7279/* Emit code for an addsi3 instruction with OPERANDS.
7280 COND_P indicates if this will use conditional execution.
7281 Return the length of the instruction.
7282 If OUTPUT_P is false, don't actually output the instruction, just return
7283 its length. */
7284int
7285arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
7286{
7287 char format[32];
7288
7289 int match = operands_match_p (operands[0], operands[1]);
7290 int match2 = operands_match_p (operands[0], operands[2]);
7291 int intval = (REG_P (operands[2]) ? 1
7292 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
7293 int neg_intval = -intval;
7294 int short_0 = satisfies_constraint_Rcq (operands[0]);
7295 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
7296 int ret = 0;
7297
7298#define ADDSI_OUTPUT1(FORMAT) do {\
7299 if (output_p) \
7300 output_asm_insn (FORMAT, operands);\
7301 return ret; \
7302} while (0)
7303#define ADDSI_OUTPUT(LIST) do {\
7304 if (output_p) \
7305 sprintf LIST;\
7306 ADDSI_OUTPUT1 (format);\
7307 return ret; \
7308} while (0)
7309
7310 /* First try to emit a 16 bit insn. */
7311 ret = 2;
7312 if (!cond_p
7313 /* If we are actually about to output this insn, don't try a 16 bit
7314 variant if we already decided that we don't want that
7315 (I.e. we upsized this insn to align some following insn.)
7316 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7317 but add1 r0,sp,35 doesn't. */
7318 && (!output_p || (get_attr_length (current_output_insn) & 2)))
7319 {
7320 if (short_p
7321 && (REG_P (operands[2])
7322 ? (match || satisfies_constraint_Rcq (operands[2]))
7323 : (unsigned) intval <= (match ? 127 : 7)))
7324 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7325 if (short_0 && REG_P (operands[1]) && match2)
7326 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7327 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
7328 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
7329 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7330
7331 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
7332 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
7333 && match && !(neg_intval & ~124)))
7334 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7335 }
7336
7337 /* Now try to emit a 32 bit insn without long immediate. */
7338 ret = 4;
7339 if (!match && match2 && REG_P (operands[1]))
7340 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7341 if (match || !cond_p)
7342 {
7343 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
7344 int range_factor = neg_intval & intval;
7345 int shift;
7346
c419f71c 7347 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
526b7aee
SV
7348 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7349
7350 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7351 same size, do, so - the insn latency is lower. */
7352 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7353 0x800 is not. */
7354 if ((intval >= 0 && intval <= limit)
7355 || (intval == -0x800 && limit == 0x7ff))
7356 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7357 else if ((intval < 0 && neg_intval <= limit)
7358 || (intval == 0x800 && limit == 0x7ff))
7359 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7360 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
7361 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
7362 gcc_assert ((((1 << shift) - 1) & intval) == 0);
7363 if (((intval < 0 && intval != -0x4000)
7364 /* sub[123] is slower than add_s / sub, only use it if it
7365 avoids a long immediate. */
7366 && neg_intval <= limit << shift)
7367 || (intval == 0x4000 && limit == 0x7ff))
7368 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
7369 shift, neg_intval >> shift));
7370 else if ((intval >= 0 && intval <= limit << shift)
7371 || (intval == -0x4000 && limit == 0x7ff))
7372 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
7373 }
7374 /* Try to emit a 16 bit opcode with long immediate. */
7375 ret = 6;
7376 if (short_p && match)
7377 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7378
7379 /* We have to use a 32 bit opcode, and with a long immediate. */
7380 ret = 8;
7381 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7382}
7383
7384/* Emit code for an commutative_cond_exec instruction with OPERANDS.
7385 Return the length of the instruction.
7386 If OUTPUT_P is false, don't actually output the instruction, just return
7387 its length. */
7388int
7389arc_output_commutative_cond_exec (rtx *operands, bool output_p)
7390{
7391 enum rtx_code commutative_op = GET_CODE (operands[3]);
7392 const char *pat = NULL;
7393
7394 /* Canonical rtl should not have a constant in the first operand position. */
7395 gcc_assert (!CONSTANT_P (operands[1]));
7396
7397 switch (commutative_op)
7398 {
7399 case AND:
7400 if (satisfies_constraint_C1p (operands[2]))
7401 pat = "bmsk%? %0,%1,%Z2";
fc1c2d04
CZ
7402 else if (satisfies_constraint_C2p (operands[2]))
7403 {
7404 operands[2] = GEN_INT ((~INTVAL (operands[2])));
7405 pat = "bmskn%? %0,%1,%Z2";
7406 }
526b7aee
SV
7407 else if (satisfies_constraint_Ccp (operands[2]))
7408 pat = "bclr%? %0,%1,%M2";
7409 else if (satisfies_constraint_CnL (operands[2]))
7410 pat = "bic%? %0,%1,%n2-1";
7411 break;
7412 case IOR:
7413 if (satisfies_constraint_C0p (operands[2]))
7414 pat = "bset%? %0,%1,%z2";
7415 break;
7416 case XOR:
7417 if (satisfies_constraint_C0p (operands[2]))
7418 pat = "bxor%? %0,%1,%z2";
7419 break;
7420 case PLUS:
7421 return arc_output_addsi (operands, true, output_p);
7422 default: break;
7423 }
7424 if (output_p)
7425 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
7426 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
7427 return 4;
7428 return 8;
7429}
7430
7431/* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7432 Emit code and return an potentially modified address such that offsets
7433 up to SIZE are can be added to yield a legitimate address.
7434 if REUSE is set, ADDR is a register that may be modified. */
7435
7436static rtx
7437force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
7438{
7439 rtx base = addr;
7440 rtx offs = const0_rtx;
7441
7442 if (GET_CODE (base) == PLUS)
7443 {
7444 offs = XEXP (base, 1);
7445 base = XEXP (base, 0);
7446 }
7447 if (!REG_P (base)
7448 || (REGNO (base) != STACK_POINTER_REGNUM
7449 && REGNO_PTR_FRAME_P (REGNO (addr)))
7450 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
7451 || !SMALL_INT (INTVAL (offs) + size))
7452 {
7453 if (reuse)
7454 emit_insn (gen_add2_insn (addr, offs));
7455 else
7456 addr = copy_to_mode_reg (Pmode, addr);
7457 }
7458 return addr;
7459}
7460
d34a0fdc
CZ
7461/* Like move_by_pieces, but take account of load latency, and actual
7462 offset ranges. Return true on success. */
526b7aee
SV
7463
7464bool
7465arc_expand_movmem (rtx *operands)
7466{
7467 rtx dst = operands[0];
7468 rtx src = operands[1];
7469 rtx dst_addr, src_addr;
7470 HOST_WIDE_INT size;
7471 int align = INTVAL (operands[3]);
7472 unsigned n_pieces;
7473 int piece = align;
7474 rtx store[2];
7475 rtx tmpx[2];
7476 int i;
7477
7478 if (!CONST_INT_P (operands[2]))
7479 return false;
7480 size = INTVAL (operands[2]);
7481 /* move_by_pieces_ninsns is static, so we can't use it. */
7482 if (align >= 4)
d34a0fdc
CZ
7483 {
7484 if (TARGET_LL64)
7485 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
7486 else
7487 n_pieces = (size + 2) / 4U + (size & 1);
7488 }
526b7aee
SV
7489 else if (align == 2)
7490 n_pieces = (size + 1) / 2U;
7491 else
7492 n_pieces = size;
7493 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
7494 return false;
d34a0fdc
CZ
7495 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7496 possible. */
7497 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
7498 piece = 8;
7499 else if (piece > 4)
526b7aee
SV
7500 piece = 4;
7501 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
7502 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
7503 store[0] = store[1] = NULL_RTX;
7504 tmpx[0] = tmpx[1] = NULL_RTX;
7505 for (i = 0; size > 0; i ^= 1, size -= piece)
7506 {
7507 rtx tmp;
ef4bddc2 7508 machine_mode mode;
526b7aee 7509
d34a0fdc
CZ
7510 while (piece > size)
7511 piece >>= 1;
526b7aee
SV
7512 mode = smallest_mode_for_size (piece * BITS_PER_UNIT, MODE_INT);
7513 /* If we don't re-use temporaries, the scheduler gets carried away,
7514 and the register pressure gets unnecessarily high. */
7515 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
7516 tmp = tmpx[i];
7517 else
7518 tmpx[i] = tmp = gen_reg_rtx (mode);
7519 dst_addr = force_offsettable (dst_addr, piece, 1);
7520 src_addr = force_offsettable (src_addr, piece, 1);
7521 if (store[i])
7522 emit_insn (store[i]);
7523 emit_move_insn (tmp, change_address (src, mode, src_addr));
7524 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
7525 dst_addr = plus_constant (Pmode, dst_addr, piece);
7526 src_addr = plus_constant (Pmode, src_addr, piece);
7527 }
7528 if (store[i])
7529 emit_insn (store[i]);
7530 if (store[i^1])
7531 emit_insn (store[i^1]);
7532 return true;
7533}
7534
7535/* Prepare operands for move in MODE. Return true iff the move has
7536 been emitted. */
7537
7538bool
ef4bddc2 7539prepare_move_operands (rtx *operands, machine_mode mode)
526b7aee
SV
7540{
7541 /* We used to do this only for MODE_INT Modes, but addresses to floating
7542 point variables may well be in the small data section. */
28633bbd
CZ
7543 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
7544 operands[0] = arc_rewrite_small_data (operands[0]);
7545
7546 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
526b7aee 7547 {
28633bbd 7548 prepare_pic_move (operands, SImode);
526b7aee 7549
28633bbd
CZ
7550 /* Disable any REG_EQUALs associated with the symref
7551 otherwise the optimization pass undoes the work done
7552 here and references the variable directly. */
7553 }
7554
7555 if (GET_CODE (operands[0]) != MEM
7556 && !TARGET_NO_SDATA_SET
7557 && small_data_pattern (operands[1], Pmode))
7558 {
7559 /* This is to take care of address calculations involving sdata
7560 variables. */
7561 operands[1] = arc_rewrite_small_data (operands[1]);
7562
7563 emit_insn (gen_rtx_SET (operands[0],operands[1]));
7564 /* ??? This note is useless, since it only restates the set itself.
7565 We should rather use the original SYMBOL_REF. However, there is
7566 the problem that we are lying to the compiler about these
7567 SYMBOL_REFs to start with. symbol@sda should be encoded specially
7568 so that we can tell it apart from an actual symbol. */
7569 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7570
7571 /* Take care of the REG_EQUAL note that will be attached to mark the
7572 output reg equal to the initial symbol_ref after this code is
7573 executed. */
7574 emit_move_insn (operands[0], operands[0]);
7575 return true;
526b7aee
SV
7576 }
7577
7578 if (MEM_P (operands[0])
7579 && !(reload_in_progress || reload_completed))
7580 {
7581 operands[1] = force_reg (mode, operands[1]);
7582 if (!move_dest_operand (operands[0], mode))
7583 {
7584 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7585 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
7586 except that we can't use that function because it is static. */
7587 rtx pat = change_address (operands[0], mode, addr);
7588 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7589 operands[0] = pat;
7590 }
7591 if (!cse_not_expected)
7592 {
7593 rtx pat = XEXP (operands[0], 0);
7594
7595 pat = arc_legitimize_address_0 (pat, pat, mode);
7596 if (pat)
7597 {
7598 pat = change_address (operands[0], mode, pat);
7599 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7600 operands[0] = pat;
7601 }
7602 }
7603 }
7604
7605 if (MEM_P (operands[1]) && !cse_not_expected)
7606 {
7607 rtx pat = XEXP (operands[1], 0);
7608
7609 pat = arc_legitimize_address_0 (pat, pat, mode);
7610 if (pat)
7611 {
7612 pat = change_address (operands[1], mode, pat);
7613 MEM_COPY_ATTRIBUTES (pat, operands[1]);
7614 operands[1] = pat;
7615 }
7616 }
7617
7618 return false;
7619}
7620
7621/* Prepare OPERANDS for an extension using CODE to OMODE.
7622 Return true iff the move has been emitted. */
7623
7624bool
7625prepare_extend_operands (rtx *operands, enum rtx_code code,
ef4bddc2 7626 machine_mode omode)
526b7aee
SV
7627{
7628 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
7629 {
7630 /* This is to take care of address calculations involving sdata
7631 variables. */
7632 operands[1]
7633 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
f7df4a84 7634 emit_insn (gen_rtx_SET (operands[0], operands[1]));
526b7aee
SV
7635 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7636
7637 /* Take care of the REG_EQUAL note that will be attached to mark the
7638 output reg equal to the initial extension after this code is
7639 executed. */
7640 emit_move_insn (operands[0], operands[0]);
7641 return true;
7642 }
7643 return false;
7644}
7645
7646/* Output a library call to a function called FNAME that has been arranged
7647 to be local to any dso. */
7648
7649const char *
7650arc_output_libcall (const char *fname)
7651{
7652 unsigned len = strlen (fname);
7653 static char buf[64];
7654
7655 gcc_assert (len < sizeof buf - 35);
7656 if (TARGET_LONG_CALLS_SET
7657 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
7658 {
7659 if (flag_pic)
f5e336b1 7660 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
526b7aee
SV
7661 else
7662 sprintf (buf, "jl%%! @%s", fname);
7663 }
7664 else
7665 sprintf (buf, "bl%%!%%* @%s", fname);
7666 return buf;
7667}
7668
7669/* Return the SImode highpart of the DImode value IN. */
7670
7671rtx
7672disi_highpart (rtx in)
7673{
7674 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
7675}
7676
526b7aee
SV
7677/* Return length adjustment for INSN.
7678 For ARC600:
7679 A write to a core reg greater or equal to 32 must not be immediately
7680 followed by a use. Anticipate the length requirement to insert a nop
7681 between PRED and SUCC to prevent a hazard. */
7682
7683static int
647d790d 7684arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee
SV
7685{
7686 if (!TARGET_ARC600)
7687 return 0;
7688 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
7689 in front of SUCC anyway, so there will be separation between PRED and
7690 SUCC. */
7691 if (recog_memoized (succ) == CODE_FOR_doloop_end_i
7692 && LABEL_P (prev_nonnote_insn (succ)))
7693 return 0;
7694 if (recog_memoized (succ) == CODE_FOR_doloop_begin_i)
7695 return 0;
7696 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
647d790d 7697 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
526b7aee 7698 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
647d790d 7699 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
526b7aee
SV
7700 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7701 || recog_memoized (pred) == CODE_FOR_umul_600
7702 || recog_memoized (pred) == CODE_FOR_mac_600
7703 || recog_memoized (pred) == CODE_FOR_mul64_600
7704 || recog_memoized (pred) == CODE_FOR_mac64_600
7705 || recog_memoized (pred) == CODE_FOR_umul64_600
7706 || recog_memoized (pred) == CODE_FOR_umac64_600)
7707 return 0;
36cc6254
RS
7708 subrtx_iterator::array_type array;
7709 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7710 {
7711 const_rtx x = *iter;
7712 switch (GET_CODE (x))
7713 {
7714 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7715 break;
7716 default:
7717 /* This is also fine for PRE/POST_MODIFY, because they
7718 contain a SET. */
7719 continue;
7720 }
7721 rtx dest = XEXP (x, 0);
7722 /* Check if this sets a an extension register. N.B. we use 61 for the
7723 condition codes, which is definitely not an extension register. */
7724 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7725 /* Check if the same register is used by the PAT. */
7726 && (refers_to_regno_p
7727 (REGNO (dest),
7728 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7729 PATTERN (succ), 0)))
7730 return 4;
7731 }
7732 return 0;
526b7aee
SV
7733}
7734
f50bb868
CZ
7735/* Given a rtx, check if it is an assembly instruction or not. */
7736
7737static int
7738arc_asm_insn_p (rtx x)
7739{
7740 int i, j;
7741
7742 if (x == 0)
7743 return 0;
7744
7745 switch (GET_CODE (x))
7746 {
7747 case ASM_OPERANDS:
7748 case ASM_INPUT:
7749 return 1;
7750
7751 case SET:
7752 return arc_asm_insn_p (SET_SRC (x));
7753
7754 case PARALLEL:
7755 j = 0;
7756 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
7757 j += arc_asm_insn_p (XVECEXP (x, 0, i));
7758 if ( j > 0)
7759 return 1;
7760 break;
7761
7762 default:
7763 break;
7764 }
7765
7766 return 0;
7767}
7768
7769/* We might have a CALL to a non-returning function before a loop end.
7770 ??? Although the manual says that's OK (the target is outside the
7771 loop, and the loop counter unused there), the assembler barfs on
7772 this for ARC600, so we must insert a nop before such a call too.
7773 For ARC700, and ARCv2 is not allowed to have the last ZOL
7774 instruction a jump to a location where lp_count is modified. */
7775
7776static bool
7777arc_loop_hazard (rtx_insn *pred, rtx_insn *succ)
7778{
7779 rtx_insn *jump = NULL;
a30c5ca4 7780 rtx label_rtx = NULL_RTX;
f50bb868
CZ
7781 rtx_insn *label = NULL;
7782 basic_block succ_bb;
7783
7784 if (recog_memoized (succ) != CODE_FOR_doloop_end_i)
7785 return false;
7786
7787 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
7788 (i.e., jump/call) as the last instruction of a ZOL. */
7789 if (TARGET_ARC600 || TARGET_HS)
7790 if (JUMP_P (pred) || CALL_P (pred)
7791 || arc_asm_insn_p (PATTERN (pred))
7792 || GET_CODE (PATTERN (pred)) == SEQUENCE)
7793 return true;
7794
7795 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
7796 instruction a jump to a location where lp_count is modified. */
7797
7798 /* Phase 2a: Dig for the jump instruction. */
7799 if (JUMP_P (pred))
7800 jump = pred;
7801 else if (GET_CODE (PATTERN (pred)) == SEQUENCE
7802 && JUMP_P (XVECEXP (PATTERN (pred), 0, 0)))
7803 jump = as_a <rtx_insn *> XVECEXP (PATTERN (pred), 0, 0);
7804 else
7805 return false;
7806
f50bb868
CZ
7807 /* Phase 2b: Make sure is not a millicode jump. */
7808 if ((GET_CODE (PATTERN (jump)) == PARALLEL)
7809 && (XVECEXP (PATTERN (jump), 0, 0) == ret_rtx))
7810 return false;
7811
a30c5ca4
AB
7812 label_rtx = JUMP_LABEL (jump);
7813 if (!label_rtx)
7814 return false;
7815
7816 /* Phase 2c: Make sure is not a return. */
7817 if (ANY_RETURN_P (label_rtx))
f50bb868
CZ
7818 return false;
7819
7820 /* Pahse 2d: Go to the target of the jump and check for aliveness of
7821 LP_COUNT register. */
a30c5ca4 7822 label = safe_as_a <rtx_insn *> (label_rtx);
f50bb868
CZ
7823 succ_bb = BLOCK_FOR_INSN (label);
7824 if (!succ_bb)
7825 {
7826 gcc_assert (NEXT_INSN (label));
7827 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label)))
7828 succ_bb = NOTE_BASIC_BLOCK (NEXT_INSN (label));
7829 else
7830 succ_bb = BLOCK_FOR_INSN (NEXT_INSN (label));
7831 }
7832
7833 if (succ_bb && REGNO_REG_SET_P (df_get_live_out (succ_bb), LP_COUNT))
7834 return true;
7835
7836 return false;
7837}
7838
526b7aee
SV
7839/* For ARC600:
7840 A write to a core reg greater or equal to 32 must not be immediately
7841 followed by a use. Anticipate the length requirement to insert a nop
7842 between PRED and SUCC to prevent a hazard. */
7843
7844int
647d790d 7845arc_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee 7846{
526b7aee
SV
7847 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7848 return 0;
f50bb868
CZ
7849
7850 if (arc_loop_hazard (pred, succ))
526b7aee 7851 return 4;
f50bb868
CZ
7852
7853 if (TARGET_ARC600)
7854 return arc600_corereg_hazard (pred, succ);
7855
7856 return 0;
526b7aee
SV
7857}
7858
7859/* Return length adjustment for INSN. */
7860
7861int
647d790d 7862arc_adjust_insn_length (rtx_insn *insn, int len, bool)
526b7aee
SV
7863{
7864 if (!INSN_P (insn))
7865 return len;
7866 /* We already handle sequences by ignoring the delay sequence flag. */
7867 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
7868 return len;
7869
7870 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
7871 the ZOL mechanism only triggers when advancing to the end address,
7872 so if there's a label at the end of a ZOL, we need to insert a nop.
7873 The ARC600 ZOL also has extra restrictions on jumps at the end of a
7874 loop. */
7875 if (recog_memoized (insn) == CODE_FOR_doloop_end_i)
7876 {
b3458f61 7877 rtx_insn *prev = prev_nonnote_insn (insn);
526b7aee
SV
7878
7879 return ((LABEL_P (prev)
7880 || (TARGET_ARC600
7881 && (JUMP_P (prev)
7882 || CALL_P (prev) /* Could be a noreturn call. */
7883 || (NONJUMP_INSN_P (prev)
7884 && GET_CODE (PATTERN (prev)) == SEQUENCE))))
7885 ? len + 4 : len);
7886 }
7887
7888 /* Check for return with but one preceding insn since function
7889 start / call. */
7890 if (TARGET_PAD_RETURN
7891 && JUMP_P (insn)
7892 && GET_CODE (PATTERN (insn)) != ADDR_VEC
7893 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
7894 && get_attr_type (insn) == TYPE_RETURN)
7895 {
84034c69 7896 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
7897
7898 if (!prev || !(prev = prev_active_insn (prev))
7899 || ((NONJUMP_INSN_P (prev)
7900 && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
7901 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
7902 NON_SIBCALL)
526b7aee
SV
7903 : CALL_ATTR (prev, NON_SIBCALL)))
7904 return len + 4;
7905 }
7906 if (TARGET_ARC600)
7907 {
b3458f61 7908 rtx_insn *succ = next_real_insn (insn);
526b7aee
SV
7909
7910 /* One the ARC600, a write to an extension register must be separated
7911 from a read. */
7912 if (succ && INSN_P (succ))
7913 len += arc600_corereg_hazard (insn, succ);
7914 }
7915
7916 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
7917 can go awry. */
7918 extract_constrain_insn_cached (insn);
7919
7920 return len;
7921}
7922
7923/* Values for length_sensitive. */
7924enum
7925{
7926 ARC_LS_NONE,// Jcc
7927 ARC_LS_25, // 25 bit offset, B
7928 ARC_LS_21, // 21 bit offset, Bcc
7929 ARC_LS_U13,// 13 bit unsigned offset, LP
7930 ARC_LS_10, // 10 bit offset, B_s, Beq_s, Bne_s
7931 ARC_LS_9, // 9 bit offset, BRcc
7932 ARC_LS_8, // 8 bit offset, BRcc_s
7933 ARC_LS_U7, // 7 bit unsigned offset, LPcc
7934 ARC_LS_7 // 7 bit offset, Bcc_s
7935};
7936
7937/* While the infrastructure patch is waiting for review, duplicate the
7938 struct definitions, to allow this file to compile. */
7939#if 1
7940typedef struct
7941{
7942 unsigned align_set;
7943 /* Cost as a branch / call target or call return address. */
7944 int target_cost;
7945 int fallthrough_cost;
7946 int branch_cost;
7947 int length;
7948 /* 0 for not length sensitive, 1 for largest offset range,
7949 * 2 for next smaller etc. */
7950 unsigned length_sensitive : 8;
7951 bool enabled;
7952} insn_length_variant_t;
7953
7954typedef struct insn_length_parameters_s
7955{
7956 int align_unit_log;
7957 int align_base_log;
7958 int max_variants;
647d790d 7959 int (*get_variants) (rtx_insn *, int, bool, bool, insn_length_variant_t *);
526b7aee
SV
7960} insn_length_parameters_t;
7961
7962static void
7963arc_insn_length_parameters (insn_length_parameters_t *ilp) ATTRIBUTE_UNUSED;
7964#endif
7965
7966static int
647d790d 7967arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
526b7aee
SV
7968 insn_length_variant_t *ilv)
7969{
7970 if (!NONDEBUG_INSN_P (insn))
7971 return 0;
7972 enum attr_type type;
7973 /* shorten_branches doesn't take optimize_size into account yet for the
7974 get_variants mechanism, so turn this off for now. */
7975 if (optimize_size)
7976 return 0;
647d790d 7977 if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
526b7aee
SV
7978 {
7979 /* The interaction of a short delay slot insn with a short branch is
7980 too weird for shorten_branches to piece together, so describe the
7981 entire SEQUENCE. */
647d790d 7982 rtx_insn *inner;
526b7aee 7983 if (TARGET_UPSIZE_DBR
84034c69 7984 && get_attr_length (pat->insn (1)) <= 2
647d790d 7985 && (((type = get_attr_type (inner = pat->insn (0)))
526b7aee
SV
7986 == TYPE_UNCOND_BRANCH)
7987 || type == TYPE_BRANCH)
7988 && get_attr_delay_slot_filled (inner) == DELAY_SLOT_FILLED_YES)
7989 {
7990 int n_variants
7991 = arc_get_insn_variants (inner, get_attr_length (inner), true,
7992 target_p, ilv+1);
7993 /* The short variant gets split into a higher-cost aligned
7994 and a lower cost unaligned variant. */
7995 gcc_assert (n_variants);
7996 gcc_assert (ilv[1].length_sensitive == ARC_LS_7
7997 || ilv[1].length_sensitive == ARC_LS_10);
7998 gcc_assert (ilv[1].align_set == 3);
7999 ilv[0] = ilv[1];
8000 ilv[0].align_set = 1;
8001 ilv[0].branch_cost += 1;
8002 ilv[1].align_set = 2;
8003 n_variants++;
8004 for (int i = 0; i < n_variants; i++)
8005 ilv[i].length += 2;
8006 /* In case an instruction with aligned size is wanted, and
8007 the short variants are unavailable / too expensive, add
8008 versions of long branch + long delay slot. */
8009 for (int i = 2, end = n_variants; i < end; i++, n_variants++)
8010 {
8011 ilv[n_variants] = ilv[i];
8012 ilv[n_variants].length += 2;
8013 }
8014 return n_variants;
8015 }
8016 return 0;
8017 }
8018 insn_length_variant_t *first_ilv = ilv;
8019 type = get_attr_type (insn);
8020 bool delay_filled
8021 = (get_attr_delay_slot_filled (insn) == DELAY_SLOT_FILLED_YES);
8022 int branch_align_cost = delay_filled ? 0 : 1;
8023 int branch_unalign_cost = delay_filled ? 0 : TARGET_UNALIGN_BRANCH ? 0 : 1;
8024 /* If the previous instruction is an sfunc call, this insn is always
8025 a target, even though the middle-end is unaware of this. */
8026 bool force_target = false;
b3458f61 8027 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8028 if (prev && arc_next_active_insn (prev, 0) == insn
8029 && ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8030 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8031 NON_SIBCALL)
526b7aee
SV
8032 : (CALL_ATTR (prev, NON_SIBCALL)
8033 && NEXT_INSN (PREV_INSN (prev)) == prev)))
8034 force_target = true;
8035
8036 switch (type)
8037 {
8038 case TYPE_BRCC:
8039 /* Short BRCC only comes in no-delay-slot version, and without limm */
8040 if (!delay_filled)
8041 {
8042 ilv->align_set = 3;
8043 ilv->length = 2;
8044 ilv->branch_cost = 1;
8045 ilv->enabled = (len == 2);
8046 ilv->length_sensitive = ARC_LS_8;
8047 ilv++;
8048 }
8049 /* Fall through. */
8050 case TYPE_BRCC_NO_DELAY_SLOT:
8051 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8052 (delay slot) scheduling purposes, but they are longer. */
8053 if (GET_CODE (PATTERN (insn)) == PARALLEL
8054 && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET)
8055 return 0;
8056 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8057 ilv->length = ((type == TYPE_BRCC) ? 4 : 8);
8058 ilv->align_set = 3;
8059 ilv->branch_cost = branch_align_cost;
8060 ilv->enabled = (len <= ilv->length);
8061 ilv->length_sensitive = ARC_LS_9;
8062 if ((target_p || force_target)
8063 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8064 {
8065 ilv[1] = *ilv;
8066 ilv->align_set = 1;
8067 ilv++;
8068 ilv->align_set = 2;
8069 ilv->target_cost = 1;
8070 ilv->branch_cost = branch_unalign_cost;
8071 }
8072 ilv++;
8073
8074 rtx op, op0;
8075 op = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
8076 op0 = XEXP (op, 0);
8077
8078 if (GET_CODE (op0) == ZERO_EXTRACT
8079 && satisfies_constraint_L (XEXP (op0, 2)))
8080 op0 = XEXP (op0, 0);
8081 if (satisfies_constraint_Rcq (op0))
8082 {
8083 ilv->length = ((type == TYPE_BRCC) ? 6 : 10);
8084 ilv->align_set = 3;
8085 ilv->branch_cost = 1 + branch_align_cost;
8086 ilv->fallthrough_cost = 1;
8087 ilv->enabled = true;
8088 ilv->length_sensitive = ARC_LS_21;
8089 if (!delay_filled && TARGET_UNALIGN_BRANCH)
8090 {
8091 ilv[1] = *ilv;
8092 ilv->align_set = 1;
8093 ilv++;
8094 ilv->align_set = 2;
8095 ilv->branch_cost = 1 + branch_unalign_cost;
8096 }
8097 ilv++;
8098 }
8099 ilv->length = ((type == TYPE_BRCC) ? 8 : 12);
8100 ilv->align_set = 3;
8101 ilv->branch_cost = 1 + branch_align_cost;
8102 ilv->fallthrough_cost = 1;
8103 ilv->enabled = true;
8104 ilv->length_sensitive = ARC_LS_21;
8105 if ((target_p || force_target)
8106 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8107 {
8108 ilv[1] = *ilv;
8109 ilv->align_set = 1;
8110 ilv++;
8111 ilv->align_set = 2;
8112 ilv->target_cost = 1;
8113 ilv->branch_cost = 1 + branch_unalign_cost;
8114 }
8115 ilv++;
8116 break;
8117
8118 case TYPE_SFUNC:
8119 ilv->length = 12;
8120 goto do_call;
8121 case TYPE_CALL_NO_DELAY_SLOT:
8122 ilv->length = 8;
8123 goto do_call;
8124 case TYPE_CALL:
8125 ilv->length = 4;
8126 ilv->length_sensitive
8127 = GET_CODE (PATTERN (insn)) == COND_EXEC ? ARC_LS_21 : ARC_LS_25;
8128 do_call:
8129 ilv->align_set = 3;
8130 ilv->fallthrough_cost = branch_align_cost;
8131 ilv->enabled = true;
8132 if ((target_p || force_target)
8133 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8134 {
8135 ilv[1] = *ilv;
8136 ilv->align_set = 1;
8137 ilv++;
8138 ilv->align_set = 2;
8139 ilv->target_cost = 1;
8140 ilv->fallthrough_cost = branch_unalign_cost;
8141 }
8142 ilv++;
8143 break;
8144 case TYPE_UNCOND_BRANCH:
8145 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8146 but that makes no difference at the moment. */
8147 ilv->length_sensitive = ARC_LS_7;
8148 ilv[1].length_sensitive = ARC_LS_25;
8149 goto do_branch;
8150 case TYPE_BRANCH:
8151 ilv->length_sensitive = ARC_LS_10;
8152 ilv[1].length_sensitive = ARC_LS_21;
8153 do_branch:
8154 ilv->align_set = 3;
8155 ilv->length = 2;
8156 ilv->branch_cost = branch_align_cost;
8157 ilv->enabled = (len == ilv->length);
8158 ilv++;
8159 ilv->length = 4;
8160 ilv->align_set = 3;
8161 ilv->branch_cost = branch_align_cost;
8162 ilv->enabled = true;
8163 if ((target_p || force_target)
8164 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8165 {
8166 ilv[1] = *ilv;
8167 ilv->align_set = 1;
8168 ilv++;
8169 ilv->align_set = 2;
8170 ilv->target_cost = 1;
8171 ilv->branch_cost = branch_unalign_cost;
8172 }
8173 ilv++;
8174 break;
8175 case TYPE_JUMP:
8176 return 0;
8177 default:
8178 /* For every short insn, there is generally also a long insn.
8179 trap_s is an exception. */
8180 if ((len & 2) == 0 || recog_memoized (insn) == CODE_FOR_trap_s)
8181 return 0;
8182 ilv->align_set = 3;
8183 ilv->length = len;
8184 ilv->enabled = 1;
8185 ilv++;
8186 ilv->align_set = 3;
8187 ilv->length = len + 2;
8188 ilv->enabled = 1;
8189 if (target_p || force_target)
8190 {
8191 ilv[1] = *ilv;
8192 ilv->align_set = 1;
8193 ilv++;
8194 ilv->align_set = 2;
8195 ilv->target_cost = 1;
8196 }
8197 ilv++;
8198 }
8199 /* If the previous instruction is an sfunc call, this insn is always
8200 a target, even though the middle-end is unaware of this.
8201 Therefore, if we have a call predecessor, transfer the target cost
8202 to the fallthrough and branch costs. */
8203 if (force_target)
8204 {
8205 for (insn_length_variant_t *p = first_ilv; p < ilv; p++)
8206 {
8207 p->fallthrough_cost += p->target_cost;
8208 p->branch_cost += p->target_cost;
8209 p->target_cost = 0;
8210 }
8211 }
8212
8213 return ilv - first_ilv;
8214}
8215
8216static void
8217arc_insn_length_parameters (insn_length_parameters_t *ilp)
8218{
8219 ilp->align_unit_log = 1;
8220 ilp->align_base_log = 1;
8221 ilp->max_variants = 7;
8222 ilp->get_variants = arc_get_insn_variants;
8223}
8224
8225/* Return a copy of COND from *STATEP, inverted if that is indicated by the
8226 CC field of *STATEP. */
8227
8228static rtx
8229arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8230{
8231 rtx cond = statep->cond;
8232 int raw_cc = get_arc_condition_code (cond);
8233 if (reverse)
8234 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8235
8236 if (statep->cc == raw_cc)
8237 return copy_rtx (cond);
8238
8239 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8240
ef4bddc2 8241 machine_mode ccm = GET_MODE (XEXP (cond, 0));
526b7aee
SV
8242 enum rtx_code code = reverse_condition (GET_CODE (cond));
8243 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8244 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8245
8246 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8247 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8248}
8249
bae56bbb
JR
8250/* Return version of PAT conditionalized with COND, which is part of INSN.
8251 ANNULLED indicates if INSN is an annulled delay-slot insn.
8252 Register further changes if necessary. */
8253static rtx
8254conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8255{
8256 /* For commutative operators, we generally prefer to have
8257 the first source match the destination. */
8258 if (GET_CODE (pat) == SET)
8259 {
8260 rtx src = SET_SRC (pat);
8261
8262 if (COMMUTATIVE_P (src))
8263 {
8264 rtx src0 = XEXP (src, 0);
8265 rtx src1 = XEXP (src, 1);
8266 rtx dst = SET_DEST (pat);
8267
8268 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8269 /* Leave add_n alone - the canonical form is to
8270 have the complex summand first. */
8271 && REG_P (src0))
f7df4a84 8272 pat = gen_rtx_SET (dst,
bae56bbb
JR
8273 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8274 src1, src0));
8275 }
8276 }
8277
8278 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8279 what to do with COND_EXEC. */
8280 if (RTX_FRAME_RELATED_P (insn))
8281 {
8282 /* If this is the delay slot insn of an anulled branch,
8283 dwarf2out.c:scan_trace understands the anulling semantics
8284 without the COND_EXEC. */
8285 gcc_assert (annulled);
8286 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8287 REG_NOTES (insn));
8288 validate_change (insn, &REG_NOTES (insn), note, 1);
8289 }
8290 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8291 return pat;
8292}
8293
526b7aee
SV
8294/* Use the ccfsm machinery to do if conversion. */
8295
8296static unsigned
8297arc_ifcvt (void)
8298{
8299 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8300 basic_block merge_bb = 0;
8301
8302 memset (statep, 0, sizeof *statep);
b3458f61 8303 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
526b7aee
SV
8304 {
8305 arc_ccfsm_advance (insn, statep);
8306
8307 switch (statep->state)
8308 {
8309 case 0:
8310 if (JUMP_P (insn))
8311 merge_bb = 0;
8312 break;
8313 case 1: case 2:
8314 {
8315 /* Deleted branch. */
8316 gcc_assert (!merge_bb);
8317 merge_bb = BLOCK_FOR_INSN (insn);
8318 basic_block succ_bb
8319 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn))));
8320 arc_ccfsm_post_advance (insn, statep);
53ea364f 8321 gcc_assert (!IN_RANGE (statep->state, 1, 2));
b3458f61 8322 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
526b7aee
SV
8323 if (seq != insn)
8324 {
8325 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8326 rtx pat = PATTERN (slot);
8327 if (INSN_ANNULLED_BRANCH_P (insn))
8328 {
8329 rtx cond
8330 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8331 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8332 }
8333 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8334 gcc_unreachable ();
8335 PUT_CODE (slot, NOTE);
8336 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8337 if (merge_bb && succ_bb)
8338 merge_blocks (merge_bb, succ_bb);
8339 }
8340 else if (merge_bb && succ_bb)
8341 {
8342 set_insn_deleted (insn);
8343 merge_blocks (merge_bb, succ_bb);
8344 }
8345 else
8346 {
8347 PUT_CODE (insn, NOTE);
8348 NOTE_KIND (insn) = NOTE_INSN_DELETED;
8349 }
8350 continue;
8351 }
8352 case 3:
8353 if (LABEL_P (insn)
8354 && statep->target_label == CODE_LABEL_NUMBER (insn))
8355 {
8356 arc_ccfsm_post_advance (insn, statep);
8357 basic_block succ_bb = BLOCK_FOR_INSN (insn);
8358 if (merge_bb && succ_bb)
8359 merge_blocks (merge_bb, succ_bb);
8360 else if (--LABEL_NUSES (insn) == 0)
8361 {
8362 const char *name = LABEL_NAME (insn);
8363 PUT_CODE (insn, NOTE);
8364 NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
8365 NOTE_DELETED_LABEL_NAME (insn) = name;
8366 }
8367 merge_bb = 0;
8368 continue;
8369 }
8370 /* Fall through. */
8371 case 4: case 5:
8372 if (!NONDEBUG_INSN_P (insn))
8373 break;
8374
8375 /* Conditionalized insn. */
8376
b3458f61
DM
8377 rtx_insn *prev, *pprev;
8378 rtx *patp, pat, cond;
bae56bbb 8379 bool annulled; annulled = false;
526b7aee
SV
8380
8381 /* If this is a delay slot insn in a non-annulled branch,
8382 don't conditionalize it. N.B., this should be fine for
8383 conditional return too. However, don't do this for
8384 unconditional branches, as these would be encountered when
8385 processing an 'else' part. */
8386 prev = PREV_INSN (insn);
8387 pprev = PREV_INSN (prev);
8388 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
bae56bbb
JR
8389 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8390 {
8391 if (!INSN_ANNULLED_BRANCH_P (prev))
8392 break;
8393 annulled = true;
8394 }
526b7aee
SV
8395
8396 patp = &PATTERN (insn);
8397 pat = *patp;
8398 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
8399 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
8400 {
8401 /* ??? don't conditionalize if all side effects are dead
8402 in the not-execute case. */
9bf218f9 8403
bae56bbb 8404 pat = conditionalize_nonjump (pat, cond, insn, annulled);
526b7aee
SV
8405 }
8406 else if (simplejump_p (insn))
8407 {
8408 patp = &SET_SRC (pat);
8409 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
8410 }
8411 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
8412 {
8413 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
f7df4a84 8414 pat = gen_rtx_SET (pc_rtx, pat);
526b7aee
SV
8415 }
8416 else
8417 gcc_unreachable ();
8418 validate_change (insn, patp, pat, 1);
8419 if (!apply_change_group ())
8420 gcc_unreachable ();
8421 if (JUMP_P (insn))
8422 {
b3458f61 8423 rtx_insn *next = next_nonnote_insn (insn);
526b7aee
SV
8424 if (GET_CODE (next) == BARRIER)
8425 delete_insn (next);
8426 if (statep->state == 3)
8427 continue;
8428 }
8429 break;
8430 default:
8431 gcc_unreachable ();
8432 }
8433 arc_ccfsm_post_advance (insn, statep);
8434 }
8435 return 0;
8436}
8437
0bc69b81
JR
8438/* Find annulled delay insns and convert them to use the appropriate predicate.
8439 This allows branch shortening to size up these insns properly. */
8440
8441static unsigned
8442arc_predicate_delay_insns (void)
8443{
b3458f61 8444 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
0bc69b81
JR
8445 {
8446 rtx pat, jump, dlay, src, cond, *patp;
8447 int reverse;
8448
8449 if (!NONJUMP_INSN_P (insn)
8450 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
8451 continue;
8452 jump = XVECEXP (pat, 0, 0);
8453 dlay = XVECEXP (pat, 0, 1);
8454 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
8455 continue;
8456 /* If the branch insn does the annulling, leave the delay insn alone. */
8457 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
8458 continue;
8459 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8460 on the other path. */
8461 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
8462 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
8463 src = SET_SRC (PATTERN (jump));
8464 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
8465 cond = XEXP (src, 0);
8466 if (XEXP (src, 2) == pc_rtx)
8467 reverse = 0;
8468 else if (XEXP (src, 1) == pc_rtx)
8469 reverse = 1;
8470 else
8471 gcc_unreachable ();
9af539fe 8472 if (reverse != !INSN_FROM_TARGET_P (dlay))
0bc69b81 8473 {
ef4bddc2 8474 machine_mode ccm = GET_MODE (XEXP (cond, 0));
0bc69b81
JR
8475 enum rtx_code code = reverse_condition (GET_CODE (cond));
8476 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8477 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8478
8479 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
8480 copy_rtx (XEXP (cond, 0)),
8481 copy_rtx (XEXP (cond, 1)));
8482 }
8483 else
8484 cond = copy_rtx (cond);
8485 patp = &PATTERN (dlay);
8486 pat = *patp;
eeac7d15 8487 pat = conditionalize_nonjump (pat, cond, dlay, true);
0bc69b81
JR
8488 validate_change (dlay, patp, pat, 1);
8489 if (!apply_change_group ())
8490 gcc_unreachable ();
8491 }
8492 return 0;
8493}
8494
526b7aee
SV
8495/* For ARC600: If a write to a core reg >=32 appears in a delay slot
8496 (other than of a forward brcc), it creates a hazard when there is a read
8497 of the same register at the branch target. We can't know what is at the
8498 branch target of calls, and for branches, we don't really know before the
8499 end of delay slot scheduling, either. Not only can individual instruction
8500 be hoisted out into a delay slot, a basic block can also be emptied this
8501 way, and branch and/or fall through targets be redirected. Hence we don't
8502 want such writes in a delay slot. */
526b7aee
SV
8503
8504/* Return nonzreo iff INSN writes to an extension core register. */
8505
8506int
8507arc_write_ext_corereg (rtx insn)
8508{
24dbe738
RS
8509 subrtx_iterator::array_type array;
8510 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
8511 {
8512 const_rtx x = *iter;
8513 switch (GET_CODE (x))
8514 {
8515 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8516 break;
8517 default:
8518 /* This is also fine for PRE/POST_MODIFY, because they
8519 contain a SET. */
8520 continue;
8521 }
8522 const_rtx dest = XEXP (x, 0);
8523 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
8524 return 1;
8525 }
8526 return 0;
526b7aee
SV
8527}
8528
8529/* This is like the hook, but returns NULL when it can't / won't generate
8530 a legitimate address. */
8531
8532static rtx
8533arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 8534 machine_mode mode)
526b7aee
SV
8535{
8536 rtx addr, inner;
8537
8538 if (flag_pic && SYMBOLIC_CONST (x))
8539 (x) = arc_legitimize_pic_address (x, 0);
8540 addr = x;
8541 if (GET_CODE (addr) == CONST)
8542 addr = XEXP (addr, 0);
8543 if (GET_CODE (addr) == PLUS
8544 && CONST_INT_P (XEXP (addr, 1))
8545 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
8546 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
8547 || (REG_P (XEXP (addr, 0))
8548 && (INTVAL (XEXP (addr, 1)) & 252))))
8549 {
8550 HOST_WIDE_INT offs, upper;
8551 int size = GET_MODE_SIZE (mode);
8552
8553 offs = INTVAL (XEXP (addr, 1));
8554 upper = (offs + 256 * size) & ~511 * size;
8555 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
8556#if 0 /* ??? this produces worse code for EEMBC idctrn01 */
8557 if (GET_CODE (x) == CONST)
8558 inner = gen_rtx_CONST (Pmode, inner);
8559#endif
8560 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
8561 x = addr;
8562 }
8563 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
8564 x = force_reg (Pmode, x);
ef4bddc2 8565 if (memory_address_p ((machine_mode) mode, x))
526b7aee
SV
8566 return x;
8567 return NULL_RTX;
8568}
8569
8570static rtx
ef4bddc2 8571arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
526b7aee 8572{
28633bbd
CZ
8573 if (GET_CODE (orig_x) == SYMBOL_REF)
8574 {
8575 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
8576 if (model != 0)
8577 return arc_legitimize_tls_address (orig_x, model);
8578 }
8579
526b7aee
SV
8580 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
8581
8582 if (new_x)
8583 return new_x;
8584 return orig_x;
8585}
8586
8587static rtx
8588arc_delegitimize_address_0 (rtx x)
8589{
f5e336b1 8590 rtx u, gp, p;
526b7aee
SV
8591
8592 if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
8593 {
f5e336b1
CZ
8594 if (XINT (u, 1) == ARC_UNSPEC_GOT
8595 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)
526b7aee
SV
8596 return XVECEXP (u, 0, 0);
8597 }
f5e336b1
CZ
8598 else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS
8599 && GET_CODE (u = XEXP (p, 0)) == UNSPEC
8600 && (XINT (u, 1) == ARC_UNSPEC_GOT
8601 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC))
8602 return gen_rtx_CONST
8603 (GET_MODE (x),
8604 gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1)));
526b7aee
SV
8605 else if (GET_CODE (x) == PLUS
8606 && ((REG_P (gp = XEXP (x, 0))
8607 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8608 || (GET_CODE (gp) == CONST
8609 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8610 && XINT (u, 1) == ARC_UNSPEC_GOT
8611 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8612 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8613 && GET_CODE (XEXP (x, 1)) == CONST
8614 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8615 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8616 return XVECEXP (u, 0, 0);
8617 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
8618 && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
8619 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8620 || (GET_CODE (gp) == CONST
8621 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8622 && XINT (u, 1) == ARC_UNSPEC_GOT
8623 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8624 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8625 && GET_CODE (XEXP (x, 1)) == CONST
8626 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8627 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8628 return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
8629 XVECEXP (u, 0, 0));
8630 else if (GET_CODE (x) == PLUS
8631 && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
8632 return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
8633 return NULL_RTX;
8634}
8635
8636static rtx
8637arc_delegitimize_address (rtx x)
8638{
8639 rtx orig_x = x = delegitimize_mem_from_attrs (x);
8640 if (GET_CODE (x) == MEM)
8641 x = XEXP (x, 0);
8642 x = arc_delegitimize_address_0 (x);
8643 if (x)
8644 {
8645 if (MEM_P (orig_x))
8646 x = replace_equiv_address_nv (orig_x, x);
8647 return x;
8648 }
8649 return orig_x;
8650}
8651
8652/* Return a REG rtx for acc1. N.B. the gcc-internal representation may
8653 differ from the hardware register number in order to allow the generic
8654 code to correctly split the concatenation of acc1 and acc2. */
8655
8656rtx
8657gen_acc1 (void)
8658{
8659 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
8660}
8661
8662/* Return a REG rtx for acc2. N.B. the gcc-internal representation may
8663 differ from the hardware register number in order to allow the generic
8664 code to correctly split the concatenation of acc1 and acc2. */
8665
8666rtx
8667gen_acc2 (void)
8668{
8669 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
8670}
8671
8672/* Return a REG rtx for mlo. N.B. the gcc-internal representation may
8673 differ from the hardware register number in order to allow the generic
8674 code to correctly split the concatenation of mhi and mlo. */
8675
8676rtx
8677gen_mlo (void)
8678{
8679 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
8680}
8681
8682/* Return a REG rtx for mhi. N.B. the gcc-internal representation may
8683 differ from the hardware register number in order to allow the generic
8684 code to correctly split the concatenation of mhi and mlo. */
8685
8686rtx
8687gen_mhi (void)
8688{
8689 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
8690}
8691
8692/* FIXME: a parameter should be added, and code added to final.c,
8693 to reproduce this functionality in shorten_branches. */
8694#if 0
8695/* Return nonzero iff BRANCH should be unaligned if possible by upsizing
8696 a previous instruction. */
8697int
8698arc_unalign_branch_p (rtx branch)
8699{
8700 rtx note;
8701
8702 if (!TARGET_UNALIGN_BRANCH)
8703 return 0;
8704 /* Do not do this if we have a filled delay slot. */
8705 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
4654c0cf 8706 && !NEXT_INSN (branch)->deleted ())
526b7aee
SV
8707 return 0;
8708 note = find_reg_note (branch, REG_BR_PROB, 0);
8709 return (!note
8710 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
8711 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
8712}
8713#endif
8714
8715/* When estimating sizes during arc_reorg, when optimizing for speed, there
8716 are three reasons why we need to consider branches to be length 6:
8717 - annull-false delay slot insns are implemented using conditional execution,
8718 thus preventing short insn formation where used.
8719 - for ARC600: annul-true delay slot insns are implemented where possible
8720 using conditional execution, preventing short insn formation where used.
8721 - for ARC700: likely or somewhat likely taken branches are made long and
8722 unaligned if possible to avoid branch penalty. */
8723
8724bool
8725arc_branch_size_unknown_p (void)
8726{
8727 return !optimize_size && arc_reorg_in_progress;
8728}
8729
8730/* We are about to output a return insn. Add padding if necessary to avoid
8731 a mispredict. A return could happen immediately after the function
8732 start, but after a call we know that there will be at least a blink
8733 restore. */
8734
8735void
8736arc_pad_return (void)
8737{
fa7af581 8738 rtx_insn *insn = current_output_insn;
b3458f61 8739 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8740 int want_long;
8741
8742 if (!prev)
8743 {
8744 fputs ("\tnop_s\n", asm_out_file);
8745 cfun->machine->unalign ^= 2;
8746 want_long = 1;
8747 }
8748 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
8749 because after a call, we'd have to restore blink first. */
8750 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
8751 return;
8752 else
8753 {
8754 want_long = (get_attr_length (prev) == 2);
8755 prev = prev_active_insn (prev);
8756 }
8757 if (!prev
8758 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8759 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8760 NON_SIBCALL)
526b7aee
SV
8761 : CALL_ATTR (prev, NON_SIBCALL)))
8762 {
8763 if (want_long)
8764 cfun->machine->size_reason
8765 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
8766 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
8767 {
8768 cfun->machine->size_reason
8769 = "Long unaligned jump avoids non-delay slot penalty";
8770 want_long = 1;
8771 }
8772 /* Disgorge delay insn, if there is any, and it may be moved. */
8773 if (final_sequence
8774 /* ??? Annulled would be OK if we can and do conditionalize
8775 the delay slot insn accordingly. */
8776 && !INSN_ANNULLED_BRANCH_P (insn)
8777 && (get_attr_cond (insn) != COND_USE
8778 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
8779 XVECEXP (final_sequence, 0, 1))))
8780 {
b3458f61 8781 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
526b7aee
SV
8782 gcc_assert (!prev_real_insn (insn)
8783 || !arc_hazard (prev_real_insn (insn), prev));
8784 cfun->machine->force_short_suffix = !want_long;
8785 rtx save_pred = current_insn_predicate;
8786 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
8787 cfun->machine->force_short_suffix = -1;
4654c0cf 8788 prev->set_deleted ();
526b7aee
SV
8789 current_output_insn = insn;
8790 current_insn_predicate = save_pred;
8791 }
8792 else if (want_long)
8793 fputs ("\tnop\n", asm_out_file);
8794 else
8795 {
8796 fputs ("\tnop_s\n", asm_out_file);
8797 cfun->machine->unalign ^= 2;
8798 }
8799 }
8800 return;
8801}
8802
8803/* The usual; we set up our machine_function data. */
8804
8805static struct machine_function *
8806arc_init_machine_status (void)
8807{
8808 struct machine_function *machine;
766090c2 8809 machine = ggc_cleared_alloc<machine_function> ();
526b7aee
SV
8810 machine->fn_type = ARC_FUNCTION_UNKNOWN;
8811 machine->force_short_suffix = -1;
8812
8813 return machine;
8814}
8815
8816/* Implements INIT_EXPANDERS. We just set up to call the above
8817 function. */
8818
8819void
8820arc_init_expanders (void)
8821{
8822 init_machine_status = arc_init_machine_status;
8823}
8824
8825/* Check if OP is a proper parallel of a millicode call pattern. OFFSET
8826 indicates a number of elements to ignore - that allows to have a
8827 sibcall pattern that starts with (return). LOAD_P is zero for store
8828 multiple (for prologues), and one for load multiples (for epilogues),
8829 and two for load multiples where no final clobber of blink is required.
8830 We also skip the first load / store element since this is supposed to
8831 be checked in the instruction pattern. */
8832
8833int
8834arc_check_millicode (rtx op, int offset, int load_p)
8835{
8836 int len = XVECLEN (op, 0) - offset;
8837 int i;
8838
8839 if (load_p == 2)
8840 {
8841 if (len < 2 || len > 13)
8842 return 0;
8843 load_p = 1;
8844 }
8845 else
8846 {
8847 rtx elt = XVECEXP (op, 0, --len);
8848
8849 if (GET_CODE (elt) != CLOBBER
8850 || !REG_P (XEXP (elt, 0))
8851 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
8852 || len < 3 || len > 13)
8853 return 0;
8854 }
8855 for (i = 1; i < len; i++)
8856 {
8857 rtx elt = XVECEXP (op, 0, i + offset);
8858 rtx reg, mem, addr;
8859
8860 if (GET_CODE (elt) != SET)
8861 return 0;
8862 mem = XEXP (elt, load_p);
8863 reg = XEXP (elt, 1-load_p);
8864 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
8865 return 0;
8866 addr = XEXP (mem, 0);
8867 if (GET_CODE (addr) != PLUS
8868 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
8869 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
8870 return 0;
8871 }
8872 return 1;
8873}
8874
8875/* Accessor functions for cfun->machine->unalign. */
8876
8877int
8878arc_get_unalign (void)
8879{
8880 return cfun->machine->unalign;
8881}
8882
8883void
8884arc_clear_unalign (void)
8885{
8886 if (cfun)
8887 cfun->machine->unalign = 0;
8888}
8889
8890void
8891arc_toggle_unalign (void)
8892{
8893 cfun->machine->unalign ^= 2;
8894}
8895
8896/* Operands 0..2 are the operands of a addsi which uses a 12 bit
8897 constant in operand 2, but which would require a LIMM because of
8898 operand mismatch.
8899 operands 3 and 4 are new SET_SRCs for operands 0. */
8900
8901void
8902split_addsi (rtx *operands)
8903{
8904 int val = INTVAL (operands[2]);
8905
8906 /* Try for two short insns first. Lengths being equal, we prefer
8907 expansions with shorter register lifetimes. */
8908 if (val > 127 && val <= 255
8909 && satisfies_constraint_Rcq (operands[0]))
8910 {
8911 operands[3] = operands[2];
8912 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8913 }
8914 else
8915 {
8916 operands[3] = operands[1];
8917 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
8918 }
8919}
8920
8921/* Operands 0..2 are the operands of a subsi which uses a 12 bit
8922 constant in operand 1, but which would require a LIMM because of
8923 operand mismatch.
8924 operands 3 and 4 are new SET_SRCs for operands 0. */
8925
8926void
8927split_subsi (rtx *operands)
8928{
8929 int val = INTVAL (operands[1]);
8930
8931 /* Try for two short insns first. Lengths being equal, we prefer
8932 expansions with shorter register lifetimes. */
8933 if (satisfies_constraint_Rcq (operands[0])
8934 && satisfies_constraint_Rcq (operands[2]))
8935 {
8936 if (val >= -31 && val <= 127)
8937 {
8938 operands[3] = gen_rtx_NEG (SImode, operands[2]);
8939 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8940 return;
8941 }
8942 else if (val >= 0 && val < 255)
8943 {
8944 operands[3] = operands[1];
8945 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
8946 return;
8947 }
8948 }
8949 /* If the destination is not an ARCompact16 register, we might
8950 still have a chance to make a short insn if the source is;
8951 we need to start with a reg-reg move for this. */
8952 operands[3] = operands[2];
8953 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
8954}
8955
8956/* Handle DOUBLE_REGS uses.
8957 Operand 0: destination register
8958 Operand 1: source register */
8959
d34a0fdc 8960static bool
526b7aee
SV
8961arc_process_double_reg_moves (rtx *operands)
8962{
8963 rtx dest = operands[0];
8964 rtx src = operands[1];
526b7aee
SV
8965
8966 enum usesDxState { none, srcDx, destDx, maxDx };
8967 enum usesDxState state = none;
8968
8969 if (refers_to_regno_p (40, 44, src, 0))
8970 state = srcDx;
8971 if (refers_to_regno_p (40, 44, dest, 0))
8972 {
8973 /* Via arc_register_move_cost, we should never see D,D moves. */
8974 gcc_assert (state == none);
8975 state = destDx;
8976 }
8977
8978 if (state == none)
d34a0fdc 8979 return false;
526b7aee
SV
8980
8981 if (state == srcDx)
8982 {
8983 /* Without the LR insn, we need to split this into a
8984 sequence of insns which will use the DEXCLx and DADDHxy
8985 insns to be able to read the Dx register in question. */
8986 if (TARGET_DPFP_DISABLE_LRSR)
8987 {
8988 /* gen *movdf_insn_nolrsr */
f7df4a84 8989 rtx set = gen_rtx_SET (dest, src);
526b7aee
SV
8990 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
8991 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
8992 }
8993 else
8994 {
8995 /* When we have 'mov D, r' or 'mov D, D' then get the target
8996 register pair for use with LR insn. */
7d81a567
CZ
8997 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
8998 TARGET_BIG_ENDIAN ? 0 : 4);
8999 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9000 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee
SV
9001
9002 /* Produce the two LR insns to get the high and low parts. */
f7df4a84 9003 emit_insn (gen_rtx_SET (destHigh,
c69899f0
CZ
9004 gen_rtx_UNSPEC_VOLATILE (Pmode,
9005 gen_rtvec (1, src),
9006 VUNSPEC_ARC_LR_HIGH)));
f7df4a84 9007 emit_insn (gen_rtx_SET (destLow,
c69899f0
CZ
9008 gen_rtx_UNSPEC_VOLATILE (Pmode,
9009 gen_rtvec (1, src),
9010 VUNSPEC_ARC_LR)));
526b7aee
SV
9011 }
9012 }
9013 else if (state == destDx)
9014 {
9015 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9016 LR insn get the target register pair. */
7d81a567
CZ
9017 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9018 TARGET_BIG_ENDIAN ? 0 : 4);
9019 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9020 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee
SV
9021
9022 emit_insn (gen_rtx_UNSPEC_VOLATILE (Pmode,
9023 gen_rtvec (3, dest, srcHigh, srcLow),
c69899f0 9024 VUNSPEC_ARC_DEXCL_NORES));
526b7aee
SV
9025
9026 }
9027 else
9028 gcc_unreachable ();
9029
d34a0fdc 9030 return true;
526b7aee
SV
9031}
9032
9033/* operands 0..1 are the operands of a 64 bit move instruction.
9034 split it into two moves with operands 2/3 and 4/5. */
9035
d34a0fdc 9036void
526b7aee
SV
9037arc_split_move (rtx *operands)
9038{
ef4bddc2 9039 machine_mode mode = GET_MODE (operands[0]);
526b7aee
SV
9040 int i;
9041 int swap = 0;
9042 rtx xop[4];
526b7aee
SV
9043
9044 if (TARGET_DPFP)
9045 {
d34a0fdc
CZ
9046 if (arc_process_double_reg_moves (operands))
9047 return;
526b7aee
SV
9048 }
9049
d34a0fdc
CZ
9050 if (TARGET_LL64
9051 && ((memory_operand (operands[0], mode)
9052 && even_register_operand (operands[1], mode))
9053 || (memory_operand (operands[1], mode)
9054 && even_register_operand (operands[0], mode))))
9055 {
9056 emit_move_insn (operands[0], operands[1]);
9057 return;
9058 }
9059
00c072ae
CZ
9060 if (TARGET_PLUS_QMACW
9061 && GET_CODE (operands[1]) == CONST_VECTOR)
9062 {
9063 HOST_WIDE_INT intval0, intval1;
9064 if (GET_MODE (operands[1]) == V2SImode)
9065 {
9066 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9067 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9068 }
9069 else
9070 {
9071 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9072 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9073 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9074 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9075 }
9076 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9077 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9078 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9079 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9080 emit_move_insn (xop[0], xop[2]);
9081 emit_move_insn (xop[3], xop[1]);
9082 return;
9083 }
9084
526b7aee
SV
9085 for (i = 0; i < 2; i++)
9086 {
9087 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9088 {
9089 rtx addr = XEXP (operands[i], 0);
9090 rtx r, o;
9091 enum rtx_code code;
9092
9093 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9094 switch (GET_CODE (addr))
9095 {
9096 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9097 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9098 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9099 pre_modify:
9100 code = PRE_MODIFY;
9101 break;
9102 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9103 case POST_INC: o = GEN_INT (8); goto post_modify;
9104 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9105 post_modify:
9106 code = POST_MODIFY;
9107 swap = 2;
9108 break;
9109 default:
9110 gcc_unreachable ();
9111 }
9112 r = XEXP (addr, 0);
9113 xop[0+i] = adjust_automodify_address_nv
9114 (operands[i], SImode,
9115 gen_rtx_fmt_ee (code, Pmode, r,
9116 gen_rtx_PLUS (Pmode, r, o)),
9117 0);
9118 xop[2+i] = adjust_automodify_address_nv
9119 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9120 }
9121 else
9122 {
9123 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9124 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9125 }
9126 }
9127 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9128 {
9129 swap = 2;
9130 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9131 }
526b7aee 9132
d34a0fdc
CZ
9133 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9134 emit_move_insn (xop[2 - swap], xop[3 - swap]);
526b7aee 9135
526b7aee
SV
9136}
9137
9138/* Select between the instruction output templates s_tmpl (for short INSNs)
9139 and l_tmpl (for long INSNs). */
9140
9141const char *
b3458f61 9142arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
526b7aee
SV
9143{
9144 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9145
9146 extract_constrain_insn_cached (insn);
9147 return is_short ? s_tmpl : l_tmpl;
9148}
9149
9150/* Searches X for any reference to REGNO, returning the rtx of the
9151 reference found if any. Otherwise, returns NULL_RTX. */
9152
9153rtx
9154arc_regno_use_in (unsigned int regno, rtx x)
9155{
9156 const char *fmt;
9157 int i, j;
9158 rtx tem;
9159
c9bd6bcd 9160 if (REG_P (x) && refers_to_regno_p (regno, x))
526b7aee
SV
9161 return x;
9162
9163 fmt = GET_RTX_FORMAT (GET_CODE (x));
9164 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9165 {
9166 if (fmt[i] == 'e')
9167 {
9168 if ((tem = regno_use_in (regno, XEXP (x, i))))
9169 return tem;
9170 }
9171 else if (fmt[i] == 'E')
9172 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9173 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9174 return tem;
9175 }
9176
9177 return NULL_RTX;
9178}
9179
9180/* Return the integer value of the "type" attribute for INSN, or -1 if
9181 INSN can't have attributes. */
9182
9183int
84034c69 9184arc_attr_type (rtx_insn *insn)
526b7aee
SV
9185{
9186 if (NONJUMP_INSN_P (insn)
9187 ? (GET_CODE (PATTERN (insn)) == USE
9188 || GET_CODE (PATTERN (insn)) == CLOBBER)
9189 : JUMP_P (insn)
9190 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9191 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9192 : !CALL_P (insn))
9193 return -1;
9194 return get_attr_type (insn);
9195}
9196
9197/* Return true if insn sets the condition codes. */
9198
9199bool
84034c69 9200arc_sets_cc_p (rtx_insn *insn)
526b7aee 9201{
84034c69
DM
9202 if (NONJUMP_INSN_P (insn))
9203 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9204 insn = seq->insn (seq->len () - 1);
526b7aee
SV
9205 return arc_attr_type (insn) == TYPE_COMPARE;
9206}
9207
9208/* Return true if INSN is an instruction with a delay slot we may want
9209 to fill. */
9210
9211bool
b3458f61 9212arc_need_delay (rtx_insn *insn)
526b7aee 9213{
b3458f61 9214 rtx_insn *next;
526b7aee
SV
9215
9216 if (!flag_delayed_branch)
9217 return false;
9218 /* The return at the end of a function needs a delay slot. */
9219 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9220 && (!(next = next_active_insn (insn))
9221 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9222 && arc_attr_type (next) == TYPE_RETURN))
9223 && (!TARGET_PAD_RETURN
9224 || (prev_active_insn (insn)
9225 && prev_active_insn (prev_active_insn (insn))
9226 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9227 return true;
9228 if (NONJUMP_INSN_P (insn)
9229 ? (GET_CODE (PATTERN (insn)) == USE
9230 || GET_CODE (PATTERN (insn)) == CLOBBER
9231 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9232 : JUMP_P (insn)
9233 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9234 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9235 : !CALL_P (insn))
9236 return false;
9237 return num_delay_slots (insn) != 0;
9238}
9239
9240/* Return true if the scheduling pass(es) has/have already run,
9241 i.e. where possible, we should try to mitigate high latencies
9242 by different instruction selection. */
9243
9244bool
9245arc_scheduling_not_expected (void)
9246{
9247 return cfun->machine->arc_reorg_started;
9248}
9249
9250/* Oddly enough, sometimes we get a zero overhead loop that branch
9251 shortening doesn't think is a loop - observed with compile/pr24883.c
9252 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9253 alignment visible for branch shortening (we actually align the loop
9254 insn before it, but that is equivalent since the loop insn is 4 byte
9255 long.) */
9256
9257int
82082f65 9258arc_label_align (rtx_insn *label)
526b7aee
SV
9259{
9260 int loop_align = LOOP_ALIGN (LABEL);
9261
9262 if (loop_align > align_labels_log)
9263 {
b3458f61 9264 rtx_insn *prev = prev_nonnote_insn (label);
526b7aee
SV
9265
9266 if (prev && NONJUMP_INSN_P (prev)
9267 && GET_CODE (PATTERN (prev)) == PARALLEL
9268 && recog_memoized (prev) == CODE_FOR_doloop_begin_i)
9269 return loop_align;
9270 }
9271 /* Code has a minimum p2 alignment of 1, which we must restore after an
9272 ADDR_DIFF_VEC. */
9273 if (align_labels_log < 1)
9274 {
b3458f61 9275 rtx_insn *next = next_nonnote_nondebug_insn (label);
526b7aee
SV
9276 if (INSN_P (next) && recog_memoized (next) >= 0)
9277 return 1;
9278 }
9279 return align_labels_log;
9280}
9281
9282/* Return true if LABEL is in executable code. */
9283
9284bool
b32d5189 9285arc_text_label (rtx_insn *label)
526b7aee 9286{
b3458f61 9287 rtx_insn *next;
526b7aee
SV
9288
9289 /* ??? We use deleted labels like they were still there, see
9290 gcc.c-torture/compile/20000326-2.c . */
9291 gcc_assert (GET_CODE (label) == CODE_LABEL
9292 || (GET_CODE (label) == NOTE
9293 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9294 next = next_nonnote_insn (label);
9295 if (next)
9296 return (!JUMP_TABLE_DATA_P (next)
9297 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9298 else if (!PREV_INSN (label))
9299 /* ??? sometimes text labels get inserted very late, see
9300 gcc.dg/torture/stackalign/comp-goto-1.c */
9301 return true;
9302 return false;
9303}
9304
9305/* Return the size of the pretend args for DECL. */
9306
9307int
9308arc_decl_pretend_args (tree decl)
9309{
9310 /* struct function is in DECL_STRUCT_FUNCTION (decl), but no
9311 pretend_args there... See PR38391. */
9312 gcc_assert (decl == current_function_decl);
9313 return crtl->args.pretend_args_size;
9314}
9315
9316/* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9317 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
339ba33b 9318 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
526b7aee
SV
9319 to redirect two breqs. */
9320
9321static bool
c1ce59ab 9322arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
526b7aee
SV
9323{
9324 /* ??? get_attr_type is declared to take an rtx. */
c1ce59ab 9325 union { const rtx_insn *c; rtx_insn *r; } u;
526b7aee
SV
9326
9327 u.c = follower;
339ba33b 9328 if (CROSSING_JUMP_P (followee))
526b7aee
SV
9329 switch (get_attr_type (u.r))
9330 {
9331 case TYPE_BRCC:
9332 case TYPE_BRCC_NO_DELAY_SLOT:
9333 return false;
9334 default:
9335 return true;
9336 }
9337 return true;
9338}
9339
9340/* Implement EPILOGUE__USES.
9341 Return true if REGNO should be added to the deemed uses of the epilogue.
9342
9343 We use the return address
9344 arc_return_address_regs[arc_compute_function_type (cfun)] .
9345 But also, we have to make sure all the register restore instructions
9346 are known to be live in interrupt functions. */
9347
9348bool
9349arc_epilogue_uses (int regno)
9350{
28633bbd
CZ
9351 if (regno == arc_tp_regno)
9352 return true;
526b7aee
SV
9353 if (reload_completed)
9354 {
9355 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9356 {
9357 if (!fixed_regs[regno])
9358 return true;
9359 return regno == arc_return_address_regs[cfun->machine->fn_type];
9360 }
9361 else
9362 return regno == RETURN_ADDR_REGNUM;
9363 }
9364 else
9365 return regno == arc_return_address_regs[arc_compute_function_type (cfun)];
9366}
9367
28633bbd
CZ
9368/* Helper for EH_USES macro. */
9369
9370bool
9371arc_eh_uses (int regno)
9372{
9373 if (regno == arc_tp_regno)
9374 return true;
9375 return false;
9376}
9377
526b7aee
SV
9378#ifndef TARGET_NO_LRA
9379#define TARGET_NO_LRA !TARGET_LRA
9380#endif
9381
9382static bool
9383arc_lra_p (void)
9384{
9385 return !TARGET_NO_LRA;
9386}
9387
9388/* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9389 Rcq registers, because some insn are shorter with them. OTOH we already
9390 have separate alternatives for this purpose, and other insns don't
9391 mind, so maybe we should rather prefer the other registers?
9392 We need more data, and we can only get that if we allow people to
9393 try all options. */
9394static int
9395arc_register_priority (int r)
9396{
9397 switch (arc_lra_priority_tag)
9398 {
9399 case ARC_LRA_PRIORITY_NONE:
9400 return 0;
9401 case ARC_LRA_PRIORITY_NONCOMPACT:
9402 return ((((r & 7) ^ 4) - 4) & 15) != r;
9403 case ARC_LRA_PRIORITY_COMPACT:
9404 return ((((r & 7) ^ 4) - 4) & 15) == r;
9405 default:
9406 gcc_unreachable ();
9407 }
9408}
9409
9410static reg_class_t
ef4bddc2 9411arc_spill_class (reg_class_t /* orig_class */, machine_mode)
526b7aee
SV
9412{
9413 return GENERAL_REGS;
9414}
9415
9416bool
ef4bddc2 9417arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
526b7aee
SV
9418 int itype)
9419{
9420 rtx x = *p;
9421 enum reload_type type = (enum reload_type) itype;
9422
9423 if (GET_CODE (x) == PLUS
9424 && CONST_INT_P (XEXP (x, 1))
9425 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9426 || (REG_P (XEXP (x, 0))
9427 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9428 {
9429 int scale = GET_MODE_SIZE (mode);
9430 int shift;
9431 rtx index_rtx = XEXP (x, 1);
9432 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9433 rtx reg, sum, sum2;
9434
9435 if (scale > 4)
9436 scale = 4;
9437 if ((scale-1) & offset)
9438 scale = 1;
9439 shift = scale >> 1;
c419f71c
JL
9440 offset_base
9441 = ((offset + (256 << shift))
4e671509 9442 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
526b7aee
SV
9443 /* Sometimes the normal form does not suit DImode. We
9444 could avoid that by using smaller ranges, but that
9445 would give less optimized code when SImode is
9446 prevalent. */
9447 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9448 {
9449 int regno;
9450
9451 reg = XEXP (x, 0);
9452 regno = REGNO (reg);
9453 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9454
9455 if (reg_equiv_constant (regno))
9456 {
9457 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9458 offset_base);
9459 if (GET_CODE (sum2) == PLUS)
9460 sum2 = gen_rtx_CONST (Pmode, sum2);
9461 }
9462 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9463 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9464 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9465 type);
9466 return true;
9467 }
9468 }
9469 /* We must re-recognize what we created before. */
9470 else if (GET_CODE (x) == PLUS
9471 && GET_CODE (XEXP (x, 0)) == PLUS
9472 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9473 && REG_P (XEXP (XEXP (x, 0), 0))
9474 && CONST_INT_P (XEXP (x, 1)))
9475 {
9476 /* Because this address is so complex, we know it must have
9477 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9478 it is already unshared, and needs no further unsharing. */
9479 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9480 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
9481 return true;
9482 }
9483 return false;
9484}
9485
ad23f5d4
JG
9486/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9487
9488static bool
445d7826 9489arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
ad23f5d4
JG
9490 unsigned int align,
9491 enum by_pieces_operation op,
9492 bool speed_p)
9493{
9494 /* Let the movmem expander handle small block moves. */
9495 if (op == MOVE_BY_PIECES)
9496 return false;
9497
9498 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
9499}
9500
b8a64b7f
CZ
9501/* Emit a (pre) memory barrier around an atomic sequence according to
9502 MODEL. */
9503
9504static void
9505arc_pre_atomic_barrier (enum memmodel model)
9506{
9507 if (need_atomic_barrier_p (model, true))
9508 emit_insn (gen_memory_barrier ());
9509}
9510
9511/* Emit a (post) memory barrier around an atomic sequence according to
9512 MODEL. */
9513
9514static void
9515arc_post_atomic_barrier (enum memmodel model)
9516{
9517 if (need_atomic_barrier_p (model, false))
9518 emit_insn (gen_memory_barrier ());
9519}
9520
9521/* Expand a compare and swap pattern. */
9522
9523static void
9524emit_unlikely_jump (rtx insn)
9525{
9526 int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
9527
9528 insn = emit_jump_insn (insn);
9529 add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
9530}
9531
9532/* Expand code to perform a 8 or 16-bit compare and swap by doing
9533 32-bit compare and swap on the word containing the byte or
9534 half-word. The difference between a weak and a strong CAS is that
9535 the weak version may simply fail. The strong version relies on two
9536 loops, one checks if the SCOND op is succsfully or not, the other
9537 checks if the 32 bit accessed location which contains the 8 or 16
9538 bit datum is not changed by other thread. The first loop is
9539 implemented by the atomic_compare_and_swapsi_1 pattern. The second
9540 loops is implemented by this routine. */
9541
9542static void
9543arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
9544 rtx oldval, rtx newval, rtx weak,
9545 rtx mod_s, rtx mod_f)
9546{
9547 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
9548 rtx addr = gen_reg_rtx (Pmode);
9549 rtx off = gen_reg_rtx (SImode);
9550 rtx oldv = gen_reg_rtx (SImode);
9551 rtx newv = gen_reg_rtx (SImode);
9552 rtx oldvalue = gen_reg_rtx (SImode);
9553 rtx newvalue = gen_reg_rtx (SImode);
9554 rtx res = gen_reg_rtx (SImode);
9555 rtx resv = gen_reg_rtx (SImode);
9556 rtx memsi, val, mask, end_label, loop_label, cc, x;
9557 machine_mode mode;
9558 bool is_weak = (weak != const0_rtx);
9559
9560 /* Truncate the address. */
9561 emit_insn (gen_rtx_SET (addr,
9562 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
9563
9564 /* Compute the datum offset. */
9565 emit_insn (gen_rtx_SET (off,
9566 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
9567 if (TARGET_BIG_ENDIAN)
9568 emit_insn (gen_rtx_SET (off,
9569 gen_rtx_MINUS (SImode,
9570 (GET_MODE (mem) == QImode) ?
9571 GEN_INT (3) : GEN_INT (2), off)));
9572
9573 /* Normal read from truncated address. */
9574 memsi = gen_rtx_MEM (SImode, addr);
9575 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
9576 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
9577
9578 val = copy_to_reg (memsi);
9579
9580 /* Convert the offset in bits. */
9581 emit_insn (gen_rtx_SET (off,
9582 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
9583
9584 /* Get the proper mask. */
9585 if (GET_MODE (mem) == QImode)
9586 mask = force_reg (SImode, GEN_INT (0xff));
9587 else
9588 mask = force_reg (SImode, GEN_INT (0xffff));
9589
9590 emit_insn (gen_rtx_SET (mask,
9591 gen_rtx_ASHIFT (SImode, mask, off)));
9592
9593 /* Prepare the old and new values. */
9594 emit_insn (gen_rtx_SET (val,
9595 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
9596 val)));
9597
9598 oldval = gen_lowpart (SImode, oldval);
9599 emit_insn (gen_rtx_SET (oldv,
9600 gen_rtx_ASHIFT (SImode, oldval, off)));
9601
9602 newval = gen_lowpart_common (SImode, newval);
9603 emit_insn (gen_rtx_SET (newv,
9604 gen_rtx_ASHIFT (SImode, newval, off)));
9605
9606 emit_insn (gen_rtx_SET (oldv,
9607 gen_rtx_AND (SImode, oldv, mask)));
9608
9609 emit_insn (gen_rtx_SET (newv,
9610 gen_rtx_AND (SImode, newv, mask)));
9611
9612 if (!is_weak)
9613 {
9614 end_label = gen_label_rtx ();
9615 loop_label = gen_label_rtx ();
9616 emit_label (loop_label);
9617 }
9618
9619 /* Make the old and new values. */
9620 emit_insn (gen_rtx_SET (oldvalue,
9621 gen_rtx_IOR (SImode, oldv, val)));
9622
9623 emit_insn (gen_rtx_SET (newvalue,
9624 gen_rtx_IOR (SImode, newv, val)));
9625
9626 /* Try an 32bit atomic compare and swap. It clobbers the CC
9627 register. */
9628 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
9629 weak, mod_s, mod_f));
9630
9631 /* Regardless of the weakness of the operation, a proper boolean
9632 result needs to be provided. */
9633 x = gen_rtx_REG (CC_Zmode, CC_REG);
9634 x = gen_rtx_EQ (SImode, x, const0_rtx);
9635 emit_insn (gen_rtx_SET (bool_result, x));
9636
9637 if (!is_weak)
9638 {
9639 /* Check the results: if the atomic op is successfully the goto
9640 to end label. */
9641 x = gen_rtx_REG (CC_Zmode, CC_REG);
9642 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
9643 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9644 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
9645 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
9646
9647 /* Wait for the right moment when the accessed 32-bit location
9648 is stable. */
9649 emit_insn (gen_rtx_SET (resv,
9650 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
9651 res)));
9652 mode = SELECT_CC_MODE (NE, resv, val);
9653 cc = gen_rtx_REG (mode, CC_REG);
9654 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
9655
9656 /* Set the new value of the 32 bit location, proper masked. */
9657 emit_insn (gen_rtx_SET (val, resv));
9658
9659 /* Try again if location is unstable. Fall through if only
9660 scond op failed. */
9661 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
9662 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9663 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
9664 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9665
9666 emit_label (end_label);
9667 }
9668
9669 /* End: proper return the result for the given mode. */
9670 emit_insn (gen_rtx_SET (res,
9671 gen_rtx_AND (SImode, res, mask)));
9672
9673 emit_insn (gen_rtx_SET (res,
9674 gen_rtx_LSHIFTRT (SImode, res, off)));
9675
9676 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
9677}
9678
9679/* Helper function used by "atomic_compare_and_swap" expand
9680 pattern. */
9681
9682void
9683arc_expand_compare_and_swap (rtx operands[])
9684{
9685 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
9686 machine_mode mode;
9687
9688 bval = operands[0];
9689 rval = operands[1];
9690 mem = operands[2];
9691 oldval = operands[3];
9692 newval = operands[4];
9693 is_weak = operands[5];
9694 mod_s = operands[6];
9695 mod_f = operands[7];
9696 mode = GET_MODE (mem);
9697
9698 if (reg_overlap_mentioned_p (rval, oldval))
9699 oldval = copy_to_reg (oldval);
9700
9701 if (mode == SImode)
9702 {
9703 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
9704 is_weak, mod_s, mod_f));
9705 x = gen_rtx_REG (CC_Zmode, CC_REG);
9706 x = gen_rtx_EQ (SImode, x, const0_rtx);
9707 emit_insn (gen_rtx_SET (bval, x));
9708 }
9709 else
9710 {
9711 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
9712 is_weak, mod_s, mod_f);
9713 }
9714}
9715
9716/* Helper function used by the "atomic_compare_and_swapsi_1"
9717 pattern. */
9718
9719void
9720arc_split_compare_and_swap (rtx operands[])
9721{
9722 rtx rval, mem, oldval, newval;
9723 machine_mode mode;
9724 enum memmodel mod_s, mod_f;
9725 bool is_weak;
9726 rtx label1, label2, x, cond;
9727
9728 rval = operands[0];
9729 mem = operands[1];
9730 oldval = operands[2];
9731 newval = operands[3];
9732 is_weak = (operands[4] != const0_rtx);
9733 mod_s = (enum memmodel) INTVAL (operands[5]);
9734 mod_f = (enum memmodel) INTVAL (operands[6]);
9735 mode = GET_MODE (mem);
9736
9737 /* ARC atomic ops work only with 32-bit aligned memories. */
9738 gcc_assert (mode == SImode);
9739
9740 arc_pre_atomic_barrier (mod_s);
9741
9742 label1 = NULL_RTX;
9743 if (!is_weak)
9744 {
9745 label1 = gen_label_rtx ();
9746 emit_label (label1);
9747 }
9748 label2 = gen_label_rtx ();
9749
9750 /* Load exclusive. */
9751 emit_insn (gen_arc_load_exclusivesi (rval, mem));
9752
9753 /* Check if it is oldval. */
9754 mode = SELECT_CC_MODE (NE, rval, oldval);
9755 cond = gen_rtx_REG (mode, CC_REG);
9756 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
9757
9758 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9759 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9760 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
9761 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9762
9763 /* Exclusively store new item. Store clobbers CC reg. */
9764 emit_insn (gen_arc_store_exclusivesi (mem, newval));
9765
9766 if (!is_weak)
9767 {
9768 /* Check the result of the store. */
9769 cond = gen_rtx_REG (CC_Zmode, CC_REG);
9770 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9771 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9772 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
9773 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9774 }
9775
9776 if (mod_f != MEMMODEL_RELAXED)
9777 emit_label (label2);
9778
9779 arc_post_atomic_barrier (mod_s);
9780
9781 if (mod_f == MEMMODEL_RELAXED)
9782 emit_label (label2);
9783}
9784
9785/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
9786 to perform. MEM is the memory on which to operate. VAL is the second
9787 operand of the binary operator. BEFORE and AFTER are optional locations to
9788 return the value of MEM either before of after the operation. MODEL_RTX
9789 is a CONST_INT containing the memory model to use. */
9790
9791void
9792arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
9793 rtx orig_before, rtx orig_after, rtx model_rtx)
9794{
9795 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
9796 machine_mode mode = GET_MODE (mem);
9797 rtx label, x, cond;
9798 rtx before = orig_before, after = orig_after;
9799
9800 /* ARC atomic ops work only with 32-bit aligned memories. */
9801 gcc_assert (mode == SImode);
9802
9803 arc_pre_atomic_barrier (model);
9804
9805 label = gen_label_rtx ();
9806 emit_label (label);
9807 label = gen_rtx_LABEL_REF (VOIDmode, label);
9808
9809 if (before == NULL_RTX)
9810 before = gen_reg_rtx (mode);
9811
9812 if (after == NULL_RTX)
9813 after = gen_reg_rtx (mode);
9814
9815 /* Load exclusive. */
9816 emit_insn (gen_arc_load_exclusivesi (before, mem));
9817
9818 switch (code)
9819 {
9820 case NOT:
9821 x = gen_rtx_AND (mode, before, val);
9822 emit_insn (gen_rtx_SET (after, x));
9823 x = gen_rtx_NOT (mode, after);
9824 emit_insn (gen_rtx_SET (after, x));
9825 break;
9826
9827 case MINUS:
9828 if (CONST_INT_P (val))
9829 {
9830 val = GEN_INT (-INTVAL (val));
9831 code = PLUS;
9832 }
9833
9834 /* FALLTHRU. */
9835 default:
9836 x = gen_rtx_fmt_ee (code, mode, before, val);
9837 emit_insn (gen_rtx_SET (after, x));
9838 break;
9839 }
9840
9841 /* Exclusively store new item. Store clobbers CC reg. */
9842 emit_insn (gen_arc_store_exclusivesi (mem, after));
9843
9844 /* Check the result of the store. */
9845 cond = gen_rtx_REG (CC_Zmode, CC_REG);
9846 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
9847 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
9848 label, pc_rtx);
9849 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
9850
9851 arc_post_atomic_barrier (model);
9852}
9853
bf9e9dc5
CZ
9854/* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
9855
9856static bool
9857arc_no_speculation_in_delay_slots_p ()
9858{
9859 return true;
9860}
9861
d34a0fdc
CZ
9862/* Return a parallel of registers to represent where to find the
9863 register pieces if required, otherwise NULL_RTX. */
9864
9865static rtx
9866arc_dwarf_register_span (rtx rtl)
9867{
cd1e4d41 9868 machine_mode mode = GET_MODE (rtl);
d34a0fdc
CZ
9869 unsigned regno;
9870 rtx p;
9871
9872 if (GET_MODE_SIZE (mode) != 8)
9873 return NULL_RTX;
9874
9875 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
9876 regno = REGNO (rtl);
9877 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
9878 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
9879
9880 return p;
9881}
9882
28633bbd
CZ
9883/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
9884 resource.h doesn't include the required header files. */
fc1c2d04 9885
28633bbd
CZ
9886bool
9887insn_is_tls_gd_dispatch (rtx_insn *insn)
9888{
9889 return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
9890}
d34a0fdc 9891
fc1c2d04
CZ
9892/* Return true if OP is an acceptable memory operand for ARCompact
9893 16-bit load instructions of MODE.
9894
9895 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
9896 non scaled instructions.
9897
9898 SCALED: TRUE if address can be scaled. */
9899
9900bool
9901compact_memory_operand_p (rtx op, machine_mode mode,
9902 bool av2short, bool scaled)
9903{
9904 rtx addr, plus0, plus1;
9905 int size, off;
9906
9907 /* Eliminate non-memory operations. */
9908 if (GET_CODE (op) != MEM)
9909 return 0;
9910
9911 /* .di instructions have no 16-bit form. */
9912 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
9913 return false;
9914
9915 if (mode == VOIDmode)
9916 mode = GET_MODE (op);
9917
9918 size = GET_MODE_SIZE (mode);
9919
9920 /* dword operations really put out 2 instructions, so eliminate
9921 them. */
9922 if (size > UNITS_PER_WORD)
9923 return false;
9924
9925 /* Decode the address now. */
9926 addr = XEXP (op, 0);
9927 switch (GET_CODE (addr))
9928 {
9929 case REG:
9930 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
9931 || COMPACT_GP_REG_P (REGNO (addr))
9932 || (SP_REG_P (REGNO (addr)) && (size != 2)));
9933 case PLUS:
9934 plus0 = XEXP (addr, 0);
9935 plus1 = XEXP (addr, 1);
9936
9937 if ((GET_CODE (plus0) == REG)
9938 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9939 || COMPACT_GP_REG_P (REGNO (plus0)))
9940 && ((GET_CODE (plus1) == REG)
9941 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
9942 || COMPACT_GP_REG_P (REGNO (plus1)))))
9943 {
9944 return !av2short;
9945 }
9946
9947 if ((GET_CODE (plus0) == REG)
9948 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
9949 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
9950 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
9951 && (GET_CODE (plus1) == CONST_INT))
9952 {
9953 bool valid = false;
9954
9955 off = INTVAL (plus1);
9956
9957 /* Negative offset is not supported in 16-bit load/store insns. */
9958 if (off < 0)
9959 return 0;
9960
9961 /* Only u5 immediates allowed in code density instructions. */
9962 if (av2short)
9963 {
9964 switch (size)
9965 {
9966 case 1:
9967 return false;
9968 case 2:
9969 /* This is an ldh_s.x instruction, check the u6
9970 immediate. */
9971 if (COMPACT_GP_REG_P (REGNO (plus0)))
9972 valid = true;
9973 break;
9974 case 4:
9975 /* Only u5 immediates allowed in 32bit access code
9976 density instructions. */
9977 if (REGNO (plus0) <= 31)
9978 return ((off < 32) && (off % 4 == 0));
9979 break;
9980 default:
9981 return false;
9982 }
9983 }
9984 else
9985 if (COMPACT_GP_REG_P (REGNO (plus0)))
9986 valid = true;
9987
9988 if (valid)
9989 {
9990
9991 switch (size)
9992 {
9993 case 1:
9994 return (off < 32);
9995 case 2:
9996 /* The 6-bit constant get shifted to fit the real
9997 5-bits field. Check also for the alignment. */
9998 return ((off < 64) && (off % 2 == 0));
9999 case 4:
10000 return ((off < 128) && (off % 4 == 0));
10001 default:
10002 return false;
10003 }
10004 }
10005 }
10006
10007 if (REG_P (plus0) && CONST_INT_P (plus1)
10008 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10009 || SP_REG_P (REGNO (plus0)))
10010 && !av2short)
10011 {
10012 off = INTVAL (plus1);
10013 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10014 }
10015
10016 if ((GET_CODE (plus0) == MULT)
10017 && (GET_CODE (XEXP (plus0, 0)) == REG)
10018 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10019 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10020 && (GET_CODE (plus1) == REG)
10021 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10022 || COMPACT_GP_REG_P (REGNO (plus1))))
10023 return scaled;
10024 default:
10025 break ;
10026 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10027 for 16-bit load instructions. */
10028 }
10029 return false;
10030}
10031
526b7aee
SV
10032struct gcc_target targetm = TARGET_INITIALIZER;
10033
10034#include "gt-arc.h"