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