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