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