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