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