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