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