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