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