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