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