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