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