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