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