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