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