]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/arc.c
Add must_pass_va_arg_in_stack
[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
ef4bddc2 6435arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
526b7aee
SV
6436 tree type, bool named ATTRIBUTE_UNUSED)
6437{
6438 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6439 int bytes = (mode == BLKmode
6440 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
6441 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6442 int arg_num = *cum;
6443 int ret;
6444
6445 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
6446 ret = GPR_REST_ARG_REGS (arg_num);
6447
6448 /* ICEd at function.c:2361, and ret is copied to data->partial */
6449 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
6450
6451 return ret;
6452}
6453
526b7aee
SV
6454/* This function is used to control a function argument is passed in a
6455 register, and which register.
6456
6457 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
6458 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
6459 all of the previous arguments so far passed in registers; MODE, the
6460 machine mode of the argument; TYPE, the data type of the argument
6461 as a tree node or 0 if that is not known (which happens for C
6462 support library functions); and NAMED, which is 1 for an ordinary
6463 argument and 0 for nameless arguments that correspond to `...' in
6464 the called function's prototype.
6465
6466 The returned value should either be a `reg' RTX for the hard
6467 register in which to pass the argument, or zero to pass the
6468 argument on the stack.
6469
6470 For machines like the Vax and 68000, where normally all arguments
6471 are pushed, zero suffices as a definition.
6472
6473 The usual way to make the ANSI library `stdarg.h' work on a machine
6474 where some arguments are usually passed in registers, is to cause
6475 nameless arguments to be passed on the stack instead. This is done
6476 by making the function return 0 whenever NAMED is 0.
6477
6478 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
6479 definition of this function to determine if this argument is of a
6480 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
6481 is not defined and the function returns non-zero for such an
6482 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
6483 defined, the argument will be computed in the stack and then loaded
6484 into a register.
6485
6486 The function is used to implement macro FUNCTION_ARG. */
6487/* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
6488 and the rest are pushed. */
6489
6490static rtx
8f3304d0
CZ
6491arc_function_arg (cumulative_args_t cum_v,
6492 machine_mode mode,
6493 const_tree type ATTRIBUTE_UNUSED,
6494 bool named ATTRIBUTE_UNUSED)
526b7aee
SV
6495{
6496 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6497 int arg_num = *cum;
6498 rtx ret;
6499 const char *debstr ATTRIBUTE_UNUSED;
6500
6501 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
6502 /* Return a marker for use in the call instruction. */
6503 if (mode == VOIDmode)
6504 {
6505 ret = const0_rtx;
6506 debstr = "<0>";
6507 }
6508 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6509 {
6510 ret = gen_rtx_REG (mode, arg_num);
6511 debstr = reg_names [arg_num];
6512 }
6513 else
6514 {
6515 ret = NULL_RTX;
6516 debstr = "memory";
6517 }
6518 return ret;
6519}
6520
6521/* The function to update the summarizer variable *CUM to advance past
6522 an argument in the argument list. The values MODE, TYPE and NAMED
6523 describe that argument. Once this is done, the variable *CUM is
6524 suitable for analyzing the *following* argument with
6525 `FUNCTION_ARG', etc.
6526
6527 This function need not do anything if the argument in question was
6528 passed on the stack. The compiler knows how to track the amount of
6529 stack space used for arguments without any special help.
6530
6531 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
6532/* For the ARC: the cum set here is passed on to function_arg where we
6533 look at its value and say which reg to use. Strategy: advance the
6534 regnumber here till we run out of arg regs, then set *cum to last
6535 reg. In function_arg, since *cum > last arg reg we would return 0
6536 and thus the arg will end up on the stack. For straddling args of
6537 course function_arg_partial_nregs will come into play. */
6538
6539static void
8f3304d0
CZ
6540arc_function_arg_advance (cumulative_args_t cum_v,
6541 machine_mode mode,
6542 const_tree type,
6543 bool named ATTRIBUTE_UNUSED)
526b7aee
SV
6544{
6545 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6546 int bytes = (mode == BLKmode
6547 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
6548 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6549 int i;
6550
6551 if (words)
6552 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
6553 for (i = 0; i < words; i++)
6554 *cum = ARC_NEXT_ARG_REG (*cum);
6555
6556}
6557
6558/* Define how to find the value returned by a function.
6559 VALTYPE is the data type of the value (as a tree).
6560 If the precise function being called is known, FN_DECL_OR_TYPE is its
6561 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6562
6563static rtx
6564arc_function_value (const_tree valtype,
6565 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6566 bool outgoing ATTRIBUTE_UNUSED)
6567{
ef4bddc2 6568 machine_mode mode = TYPE_MODE (valtype);
526b7aee
SV
6569 int unsignedp ATTRIBUTE_UNUSED;
6570
6571 unsignedp = TYPE_UNSIGNED (valtype);
6572 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6573 PROMOTE_MODE (mode, unsignedp, valtype);
6574 return gen_rtx_REG (mode, 0);
6575}
6576
6577/* Returns the return address that is used by builtin_return_address. */
6578
6579rtx
6580arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6581{
6582 if (count != 0)
6583 return const0_rtx;
6584
6585 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6586}
6587
526b7aee
SV
6588/* Determine if a given RTX is a valid constant. We already know this
6589 satisfies CONSTANT_P. */
6590
6591bool
28633bbd 6592arc_legitimate_constant_p (machine_mode mode, rtx x)
526b7aee 6593{
526b7aee
SV
6594 switch (GET_CODE (x))
6595 {
6596 case CONST:
b6c354eb 6597 if (flag_pic)
526b7aee 6598 {
b6c354eb 6599 if (arc_legitimate_pic_addr_p (x))
526b7aee 6600 return true;
b6c354eb
CZ
6601 }
6602 return arc_legitimate_constant_p (mode, XEXP (x, 0));
526b7aee 6603
526b7aee 6604 case SYMBOL_REF:
28633bbd
CZ
6605 if (SYMBOL_REF_TLS_MODEL (x))
6606 return false;
6607 /* Fall through. */
6608 case LABEL_REF:
6609 if (flag_pic)
6610 return false;
6611 /* Fall through. */
b6c354eb
CZ
6612 case CONST_INT:
6613 case CONST_DOUBLE:
6614 return true;
6615
6616 case NEG:
6617 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6618
6619 case PLUS:
6620 case MINUS:
6621 {
6622 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6623 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6624
6625 return (t1 && t2);
6626 }
6627
6628 case CONST_VECTOR:
6629 switch (mode)
6630 {
4e10a5a7 6631 case E_V2HImode:
b6c354eb 6632 return TARGET_PLUS_DMPY;
4e10a5a7
RS
6633 case E_V2SImode:
6634 case E_V4HImode:
b6c354eb
CZ
6635 return TARGET_PLUS_QMACW;
6636 default:
6637 return false;
6638 }
6639
6640 case UNSPEC:
6641 switch (XINT (x, 1))
6642 {
6643 case UNSPEC_TLS_GD:
6644 case UNSPEC_TLS_OFF:
6645 case UNSPEC_TLS_IE:
6646 return true;
6647 default:
6648 /* Any other unspec ending here are pic related, hence the above
6649 constant pic address checking returned false. */
6650 return false;
6651 }
6652 /* Fall through. */
526b7aee
SV
6653
6654 default:
b6c354eb 6655 fatal_insn ("unrecognized supposed constant", x);
526b7aee
SV
6656 }
6657
b6c354eb 6658 gcc_unreachable ();
526b7aee
SV
6659}
6660
6661static bool
ef4bddc2 6662arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
526b7aee
SV
6663{
6664 if (RTX_OK_FOR_BASE_P (x, strict))
6665 return true;
ac2e1a51 6666 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
526b7aee 6667 return true;
9f532472 6668 if (legitimate_scaled_address_p (mode, x, strict))
526b7aee 6669 return true;
e0be3321 6670 if (legitimate_small_data_address_p (x))
526b7aee
SV
6671 return true;
6672 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6673 return true;
28633bbd
CZ
6674
6675 /* When we compile for size avoid const (@sym + offset)
6676 addresses. */
6677 if (!flag_pic && optimize_size && !reload_completed
6678 && (GET_CODE (x) == CONST)
6679 && (GET_CODE (XEXP (x, 0)) == PLUS)
6680 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6681 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6682 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
526b7aee 6683 {
28633bbd
CZ
6684 rtx addend = XEXP (XEXP (x, 0), 1);
6685 gcc_assert (CONST_INT_P (addend));
6686 HOST_WIDE_INT offset = INTVAL (addend);
6687
6688 /* Allow addresses having a large offset to pass. Anyhow they
6689 will end in a limm. */
6690 return !(offset > -1024 && offset < 1020);
6691 }
6692
6693 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6694 {
b6c354eb 6695 return arc_legitimate_constant_p (mode, x);
526b7aee
SV
6696 }
6697 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6698 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6699 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6700 return true;
6701 /* We're restricted here by the `st' insn. */
6702 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6703 && GET_CODE (XEXP ((x), 1)) == PLUS
6704 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
ac2e1a51 6705 && legitimate_offset_address_p (QImode, XEXP (x, 1),
526b7aee
SV
6706 TARGET_AUTO_MODIFY_REG, strict))
6707 return true;
6708 return false;
6709}
6710
6711/* Return true iff ADDR (a legitimate address expression)
6712 has an effect that depends on the machine mode it is used for. */
6713
6714static bool
6715arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6716{
6717 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6718 which is valid for loads and stores, or a limm offset, which is valid for
1fccdd40 6719 loads. Scaled indices are scaled by the access mode. */
526b7aee 6720 if (GET_CODE (addr) == PLUS
1fccdd40 6721 && GET_CODE (XEXP ((addr), 0)) == MULT)
526b7aee
SV
6722 return true;
6723 return false;
6724}
6725
6726/* Determine if it's legal to put X into the constant pool. */
6727
6728static bool
ef4bddc2 6729arc_cannot_force_const_mem (machine_mode mode, rtx x)
526b7aee
SV
6730{
6731 return !arc_legitimate_constant_p (mode, x);
6732}
6733
c69899f0
CZ
6734/* IDs for all the ARC builtins. */
6735
6736enum arc_builtin_id
6737 {
6738#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6739 ARC_BUILTIN_ ## NAME,
6740#include "builtins.def"
6741#undef DEF_BUILTIN
6742
6743 ARC_BUILTIN_COUNT
6744 };
6745
6746struct GTY(()) arc_builtin_description
6747{
6748 enum insn_code icode;
6749 int n_args;
6750 tree fndecl;
6751};
6752
6753static GTY(()) struct arc_builtin_description
6754arc_bdesc[ARC_BUILTIN_COUNT] =
6755{
6756#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6757 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6758#include "builtins.def"
6759#undef DEF_BUILTIN
6760};
6761
6762/* Transform UP into lowercase and write the result to LO.
6763 You must provide enough space for LO. Return LO. */
6764
6765static char*
6766arc_tolower (char *lo, const char *up)
6767{
6768 char *lo0 = lo;
6769
6770 for (; *up; up++, lo++)
6771 *lo = TOLOWER (*up);
6772
6773 *lo = '\0';
6774
6775 return lo0;
6776}
6777
6778/* Implement `TARGET_BUILTIN_DECL'. */
526b7aee 6779
c69899f0
CZ
6780static tree
6781arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6782{
6783 if (id < ARC_BUILTIN_COUNT)
6784 return arc_bdesc[id].fndecl;
526b7aee 6785
c69899f0
CZ
6786 return error_mark_node;
6787}
526b7aee
SV
6788
6789static void
6790arc_init_builtins (void)
6791{
00c072ae
CZ
6792 tree V4HI_type_node;
6793 tree V2SI_type_node;
6794 tree V2HI_type_node;
6795
6796 /* Vector types based on HS SIMD elements. */
6797 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6798 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6799 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6800
c69899f0
CZ
6801 tree pcvoid_type_node
6802 = build_pointer_type (build_qualified_type (void_type_node,
6803 TYPE_QUAL_CONST));
6804 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6805 V8HImode);
6806
6807 tree void_ftype_void
6808 = build_function_type_list (void_type_node, NULL_TREE);
6809 tree int_ftype_int
6810 = build_function_type_list (integer_type_node, integer_type_node,
6811 NULL_TREE);
6812 tree int_ftype_pcvoid_int
6813 = build_function_type_list (integer_type_node, pcvoid_type_node,
6814 integer_type_node, NULL_TREE);
6815 tree void_ftype_usint_usint
6816 = build_function_type_list (void_type_node, long_unsigned_type_node,
6817 long_unsigned_type_node, NULL_TREE);
6818 tree int_ftype_int_int
6819 = build_function_type_list (integer_type_node, integer_type_node,
6820 integer_type_node, NULL_TREE);
6821 tree usint_ftype_usint
6822 = build_function_type_list (long_unsigned_type_node,
6823 long_unsigned_type_node, NULL_TREE);
6824 tree void_ftype_usint
6825 = build_function_type_list (void_type_node, long_unsigned_type_node,
6826 NULL_TREE);
6827 tree int_ftype_void
6828 = build_function_type_list (integer_type_node, void_type_node,
6829 NULL_TREE);
6830 tree void_ftype_int
6831 = build_function_type_list (void_type_node, integer_type_node,
6832 NULL_TREE);
6833 tree int_ftype_short
6834 = build_function_type_list (integer_type_node, short_integer_type_node,
6835 NULL_TREE);
6836
6837 /* Old ARC SIMD types. */
6838 tree v8hi_ftype_v8hi_v8hi
6839 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6840 V8HI_type_node, NULL_TREE);
6841 tree v8hi_ftype_v8hi_int
6842 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6843 integer_type_node, NULL_TREE);
6844 tree v8hi_ftype_v8hi_int_int
6845 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6846 integer_type_node, integer_type_node,
6847 NULL_TREE);
6848 tree void_ftype_v8hi_int_int
6849 = build_function_type_list (void_type_node, V8HI_type_node,
6850 integer_type_node, integer_type_node,
6851 NULL_TREE);
6852 tree void_ftype_v8hi_int_int_int
6853 = build_function_type_list (void_type_node, V8HI_type_node,
6854 integer_type_node, integer_type_node,
6855 integer_type_node, NULL_TREE);
6856 tree v8hi_ftype_int_int
6857 = build_function_type_list (V8HI_type_node, integer_type_node,
6858 integer_type_node, NULL_TREE);
6859 tree void_ftype_int_int
6860 = build_function_type_list (void_type_node, integer_type_node,
6861 integer_type_node, NULL_TREE);
6862 tree v8hi_ftype_v8hi
6863 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6864 NULL_TREE);
00c072ae
CZ
6865 /* ARCv2 SIMD types. */
6866 tree long_ftype_v4hi_v4hi
6867 = build_function_type_list (long_long_integer_type_node,
6868 V4HI_type_node, V4HI_type_node, NULL_TREE);
6869 tree int_ftype_v2hi_v2hi
6870 = build_function_type_list (integer_type_node,
6871 V2HI_type_node, V2HI_type_node, NULL_TREE);
6872 tree v2si_ftype_v2hi_v2hi
6873 = build_function_type_list (V2SI_type_node,
6874 V2HI_type_node, V2HI_type_node, NULL_TREE);
6875 tree v2hi_ftype_v2hi_v2hi
6876 = build_function_type_list (V2HI_type_node,
6877 V2HI_type_node, V2HI_type_node, NULL_TREE);
6878 tree v2si_ftype_v2si_v2si
6879 = build_function_type_list (V2SI_type_node,
6880 V2SI_type_node, V2SI_type_node, NULL_TREE);
6881 tree v4hi_ftype_v4hi_v4hi
6882 = build_function_type_list (V4HI_type_node,
6883 V4HI_type_node, V4HI_type_node, NULL_TREE);
6884 tree long_ftype_v2si_v2hi
6885 = build_function_type_list (long_long_integer_type_node,
6886 V2SI_type_node, V2HI_type_node, NULL_TREE);
c69899f0
CZ
6887
6888 /* Add the builtins. */
6889#define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6890 { \
6891 int id = ARC_BUILTIN_ ## NAME; \
6892 const char *Name = "__builtin_arc_" #NAME; \
6893 char *name = (char*) alloca (1 + strlen (Name)); \
6894 \
6895 gcc_assert (id < ARC_BUILTIN_COUNT); \
6896 if (MASK) \
6897 arc_bdesc[id].fndecl \
6898 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6899 BUILT_IN_MD, NULL, NULL_TREE); \
6900 }
6901#include "builtins.def"
6902#undef DEF_BUILTIN
6903}
6904
6905/* Helper to expand __builtin_arc_aligned (void* val, int
6906 alignval). */
6907
6908static rtx
6909arc_expand_builtin_aligned (tree exp)
6910{
6911 tree arg0 = CALL_EXPR_ARG (exp, 0);
6912 tree arg1 = CALL_EXPR_ARG (exp, 1);
6913 fold (arg1);
6914 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6915 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6916
6917 if (!CONST_INT_P (op1))
6918 {
6919 /* If we can't fold the alignment to a constant integer
6920 whilst optimizing, this is probably a user error. */
6921 if (optimize)
a3f9f006 6922 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
c69899f0
CZ
6923 }
6924 else
6925 {
6926 HOST_WIDE_INT alignTest = INTVAL (op1);
6927 /* Check alignTest is positive, and a power of two. */
6928 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6929 {
a3f9f006 6930 error ("invalid alignment value for %<__builtin_arc_aligned%>");
c69899f0
CZ
6931 return NULL_RTX;
6932 }
6933
6934 if (CONST_INT_P (op0))
6935 {
6936 HOST_WIDE_INT pnt = INTVAL (op0);
6937
6938 if ((pnt & (alignTest - 1)) == 0)
6939 return const1_rtx;
6940 }
6941 else
6942 {
6943 unsigned align = get_pointer_alignment (arg0);
6944 unsigned numBits = alignTest * BITS_PER_UNIT;
6945
6946 if (align && align >= numBits)
6947 return const1_rtx;
6948 /* Another attempt to ascertain alignment. Check the type
6949 we are pointing to. */
6950 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6951 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6952 return const1_rtx;
6953 }
6954 }
6955
6956 /* Default to false. */
6957 return const0_rtx;
6958}
6959
6960/* Helper arc_expand_builtin, generates a pattern for the given icode
6961 and arguments. */
6962
6963static rtx_insn *
6964apply_GEN_FCN (enum insn_code icode, rtx *arg)
6965{
6966 switch (insn_data[icode].n_generator_args)
6967 {
6968 case 0:
6969 return GEN_FCN (icode) ();
6970 case 1:
6971 return GEN_FCN (icode) (arg[0]);
6972 case 2:
6973 return GEN_FCN (icode) (arg[0], arg[1]);
6974 case 3:
6975 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6976 case 4:
6977 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6978 case 5:
6979 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6980 default:
6981 gcc_unreachable ();
6982 }
6983}
526b7aee
SV
6984
6985/* Expand an expression EXP that calls a built-in function,
6986 with result going to TARGET if that's convenient
6987 (and in mode MODE if that's convenient).
6988 SUBTARGET may be used as the target for computing one of EXP's operands.
6989 IGNORE is nonzero if the value is to be ignored. */
6990
6991static rtx
6992arc_expand_builtin (tree exp,
6993 rtx target,
c69899f0
CZ
6994 rtx subtarget ATTRIBUTE_UNUSED,
6995 machine_mode mode ATTRIBUTE_UNUSED,
6996 int ignore ATTRIBUTE_UNUSED)
6997{
6998 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
4d732405 6999 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
c69899f0
CZ
7000 const struct arc_builtin_description *d = &arc_bdesc[id];
7001 int i, j, n_args = call_expr_nargs (exp);
7002 rtx pat = NULL_RTX;
7003 rtx xop[5];
7004 enum insn_code icode = d->icode;
7005 machine_mode tmode = insn_data[icode].operand[0].mode;
7006 int nonvoid;
7007 tree arg0;
7008 tree arg1;
7009 tree arg2;
7010 tree arg3;
7011 rtx op0;
7012 rtx op1;
7013 rtx op2;
7014 rtx op3;
7015 rtx op4;
ef4bddc2
RS
7016 machine_mode mode0;
7017 machine_mode mode1;
c69899f0
CZ
7018 machine_mode mode2;
7019 machine_mode mode3;
7020 machine_mode mode4;
526b7aee 7021
c69899f0
CZ
7022 if (id >= ARC_BUILTIN_COUNT)
7023 internal_error ("bad builtin fcode");
526b7aee 7024
c69899f0
CZ
7025 /* 1st part: Expand special builtins. */
7026 switch (id)
526b7aee
SV
7027 {
7028 case ARC_BUILTIN_NOP:
c69899f0 7029 emit_insn (gen_nopv ());
526b7aee
SV
7030 return NULL_RTX;
7031
c69899f0
CZ
7032 case ARC_BUILTIN_RTIE:
7033 case ARC_BUILTIN_SYNC:
7034 case ARC_BUILTIN_BRK:
7035 case ARC_BUILTIN_SWI:
7036 case ARC_BUILTIN_UNIMP_S:
7037 gcc_assert (icode != 0);
7038 emit_insn (GEN_FCN (icode) (const1_rtx));
7039 return NULL_RTX;
526b7aee 7040
c69899f0
CZ
7041 case ARC_BUILTIN_ALIGNED:
7042 return arc_expand_builtin_aligned (exp);
526b7aee 7043
c69899f0
CZ
7044 case ARC_BUILTIN_CLRI:
7045 target = gen_reg_rtx (SImode);
7046 emit_insn (gen_clri (target, const1_rtx));
526b7aee
SV
7047 return target;
7048
c69899f0
CZ
7049 case ARC_BUILTIN_TRAP_S:
7050 case ARC_BUILTIN_SLEEP:
526b7aee 7051 arg0 = CALL_EXPR_ARG (exp, 0);
c69899f0 7052 fold (arg0);
526b7aee 7053 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
526b7aee 7054
c69899f0
CZ
7055 gcc_assert (icode != 0);
7056 emit_insn (GEN_FCN (icode) (op0));
7057 return NULL_RTX;
526b7aee 7058
c69899f0
CZ
7059 case ARC_BUILTIN_VDORUN:
7060 case ARC_BUILTIN_VDIRUN:
526b7aee
SV
7061 arg0 = CALL_EXPR_ARG (exp, 0);
7062 arg1 = CALL_EXPR_ARG (exp, 1);
c69899f0
CZ
7063 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7064 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
526b7aee 7065
c69899f0
CZ
7066 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
7067
7068 mode0 = insn_data[icode].operand[1].mode;
7069 mode1 = insn_data[icode].operand[2].mode;
526b7aee 7070
c69899f0 7071 if (!insn_data[icode].operand[1].predicate (op0, mode0))
526b7aee
SV
7072 op0 = copy_to_mode_reg (mode0, op0);
7073
c69899f0 7074 if (!insn_data[icode].operand[2].predicate (op1, mode1))
526b7aee
SV
7075 op1 = copy_to_mode_reg (mode1, op1);
7076
c69899f0
CZ
7077 pat = GEN_FCN (icode) (target, op0, op1);
7078 if (!pat)
7079 return NULL_RTX;
7080
7081 emit_insn (pat);
526b7aee
SV
7082 return NULL_RTX;
7083
c69899f0
CZ
7084 case ARC_BUILTIN_VDIWR:
7085 case ARC_BUILTIN_VDOWR:
526b7aee
SV
7086 arg0 = CALL_EXPR_ARG (exp, 0);
7087 arg1 = CALL_EXPR_ARG (exp, 1);
c69899f0
CZ
7088 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7089 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7090
7091 if (!CONST_INT_P (op0)
7092 || !(UNSIGNED_INT3 (INTVAL (op0))))
7093 error ("operand 1 should be an unsigned 3-bit immediate");
526b7aee 7094
526b7aee
SV
7095 mode1 = insn_data[icode].operand[1].mode;
7096
c69899f0
CZ
7097 if (icode == CODE_FOR_vdiwr_insn)
7098 target = gen_rtx_REG (SImode,
7099 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
7100 else if (icode == CODE_FOR_vdowr_insn)
7101 target = gen_rtx_REG (SImode,
7102 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
7103 else
7104 gcc_unreachable ();
526b7aee 7105
c69899f0 7106 if (!insn_data[icode].operand[2].predicate (op1, mode1))
526b7aee
SV
7107 op1 = copy_to_mode_reg (mode1, op1);
7108
c69899f0
CZ
7109 pat = GEN_FCN (icode) (target, op1);
7110 if (!pat)
7111 return NULL_RTX;
526b7aee 7112
c69899f0 7113 emit_insn (pat);
526b7aee
SV
7114 return NULL_RTX;
7115
c69899f0
CZ
7116 case ARC_BUILTIN_VASRW:
7117 case ARC_BUILTIN_VSR8:
7118 case ARC_BUILTIN_VSR8AW:
526b7aee 7119 arg0 = CALL_EXPR_ARG (exp, 0);
c69899f0
CZ
7120 arg1 = CALL_EXPR_ARG (exp, 1);
7121 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7122 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7123 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7124
7125 target = gen_reg_rtx (V8HImode);
526b7aee 7126 mode0 = insn_data[icode].operand[1].mode;
c69899f0 7127 mode1 = insn_data[icode].operand[2].mode;
526b7aee 7128
c69899f0 7129 if (!insn_data[icode].operand[1].predicate (op0, mode0))
526b7aee
SV
7130 op0 = copy_to_mode_reg (mode0, op0);
7131
c69899f0
CZ
7132 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7133 || !(UNSIGNED_INT3 (INTVAL (op1))))
7134 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
526b7aee 7135
c69899f0
CZ
7136 pat = GEN_FCN (icode) (target, op0, op1, op2);
7137 if (!pat)
7138 return NULL_RTX;
526b7aee 7139
c69899f0
CZ
7140 emit_insn (pat);
7141 return target;
526b7aee 7142
c69899f0
CZ
7143 case ARC_BUILTIN_VLD32WH:
7144 case ARC_BUILTIN_VLD32WL:
7145 case ARC_BUILTIN_VLD64:
7146 case ARC_BUILTIN_VLD32:
7147 rtx src_vreg;
7148 icode = d->icode;
7149 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7150 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7151 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
526b7aee 7152
c69899f0
CZ
7153 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7154 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7155 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7156 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
526b7aee 7157
c69899f0
CZ
7158 /* target <- src vreg. */
7159 emit_insn (gen_move_insn (target, src_vreg));
526b7aee 7160
c69899f0
CZ
7161 /* target <- vec_concat: target, mem (Ib, u8). */
7162 mode0 = insn_data[icode].operand[3].mode;
7163 mode1 = insn_data[icode].operand[1].mode;
526b7aee 7164
c69899f0
CZ
7165 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
7166 || !(UNSIGNED_INT3 (INTVAL (op0))))
7167 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
526b7aee 7168
c69899f0
CZ
7169 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7170 || !(UNSIGNED_INT8 (INTVAL (op1))))
7171 error ("operand 2 should be an unsigned 8-bit value");
526b7aee 7172
c69899f0
CZ
7173 pat = GEN_FCN (icode) (target, op1, op2, op0);
7174 if (!pat)
7175 return NULL_RTX;
526b7aee 7176
c69899f0
CZ
7177 emit_insn (pat);
7178 return target;
526b7aee 7179
c69899f0
CZ
7180 case ARC_BUILTIN_VLD64W:
7181 case ARC_BUILTIN_VLD128:
7182 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
7183 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
526b7aee 7184
c69899f0
CZ
7185 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7186 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7187 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
526b7aee 7188
c69899f0
CZ
7189 /* target <- src vreg. */
7190 target = gen_reg_rtx (V8HImode);
526b7aee 7191
c69899f0
CZ
7192 /* target <- vec_concat: target, mem (Ib, u8). */
7193 mode0 = insn_data[icode].operand[1].mode;
7194 mode1 = insn_data[icode].operand[2].mode;
7195 mode2 = insn_data[icode].operand[3].mode;
526b7aee 7196
c69899f0
CZ
7197 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7198 || !(UNSIGNED_INT3 (INTVAL (op1))))
7199 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
526b7aee 7200
c69899f0
CZ
7201 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
7202 || !(UNSIGNED_INT8 (INTVAL (op2))))
7203 error ("operand 2 should be an unsigned 8-bit value");
526b7aee 7204
c69899f0 7205 pat = GEN_FCN (icode) (target, op0, op1, op2);
526b7aee 7206
c69899f0
CZ
7207 if (!pat)
7208 return NULL_RTX;
526b7aee 7209
c69899f0 7210 emit_insn (pat);
526b7aee
SV
7211 return target;
7212
c69899f0
CZ
7213 case ARC_BUILTIN_VST128:
7214 case ARC_BUILTIN_VST64:
7215 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
7216 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7217 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
526b7aee 7218
c69899f0
CZ
7219 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7220 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7221 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7222 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
526b7aee
SV
7223
7224 mode0 = insn_data[icode].operand[0].mode;
7225 mode1 = insn_data[icode].operand[1].mode;
c69899f0
CZ
7226 mode2 = insn_data[icode].operand[2].mode;
7227 mode3 = insn_data[icode].operand[3].mode;
526b7aee 7228
c69899f0
CZ
7229 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7230 || !(UNSIGNED_INT3 (INTVAL (op1))))
7231 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
526b7aee 7232
c69899f0
CZ
7233 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7234 || !(UNSIGNED_INT8 (INTVAL (op2))))
7235 error ("operand 3 should be an unsigned 8-bit value");
526b7aee 7236
c69899f0
CZ
7237 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7238 op3 = copy_to_mode_reg (mode3, op3);
526b7aee 7239
c69899f0
CZ
7240 pat = GEN_FCN (icode) (op0, op1, op2, op3);
7241 if (!pat)
7242 return NULL_RTX;
526b7aee 7243
c69899f0
CZ
7244 emit_insn (pat);
7245 return NULL_RTX;
526b7aee 7246
c69899f0
CZ
7247 case ARC_BUILTIN_VST16_N:
7248 case ARC_BUILTIN_VST32_N:
7249 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7250 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
7251 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
7252 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
526b7aee 7253
c69899f0
CZ
7254 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
7255 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7256 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7257 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7258 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
526b7aee
SV
7259
7260 mode0 = insn_data[icode].operand[0].mode;
c69899f0
CZ
7261 mode2 = insn_data[icode].operand[2].mode;
7262 mode3 = insn_data[icode].operand[3].mode;
7263 mode4 = insn_data[icode].operand[4].mode;
526b7aee 7264
c69899f0
CZ
7265 /* Do some correctness checks for the operands. */
7266 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
7267 || !(UNSIGNED_INT8 (INTVAL (op0))))
7268 error ("operand 4 should be an unsigned 8-bit value (0-255)");
526b7aee 7269
c69899f0
CZ
7270 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7271 || !(UNSIGNED_INT3 (INTVAL (op2))))
7272 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
526b7aee 7273
c69899f0
CZ
7274 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7275 op3 = copy_to_mode_reg (mode3, op3);
526b7aee 7276
c69899f0
CZ
7277 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
7278 || !(UNSIGNED_INT3 (INTVAL (op4))))
7279 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
7280 else if (icode == CODE_FOR_vst32_n_insn
7281 && ((INTVAL (op4) % 2) != 0))
7282 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
526b7aee 7283
c69899f0
CZ
7284 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
7285 if (!pat)
7286 return NULL_RTX;
526b7aee 7287
c69899f0 7288 emit_insn (pat);
526b7aee
SV
7289 return NULL_RTX;
7290
c69899f0
CZ
7291 default:
7292 break;
7293 }
7294
7295 /* 2nd part: Expand regular builtins. */
7296 if (icode == 0)
7297 internal_error ("bad builtin fcode");
7298
7299 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7300 j = 0;
526b7aee 7301
c69899f0
CZ
7302 if (nonvoid)
7303 {
7304 if (target == NULL_RTX
7305 || GET_MODE (target) != tmode
7306 || !insn_data[icode].operand[0].predicate (target, tmode))
526b7aee 7307 {
c69899f0 7308 target = gen_reg_rtx (tmode);
526b7aee 7309 }
c69899f0
CZ
7310 xop[j++] = target;
7311 }
7312
7313 gcc_assert (n_args <= 4);
7314 for (i = 0; i < n_args; i++, j++)
7315 {
7316 tree arg = CALL_EXPR_ARG (exp, i);
7317 machine_mode mode = insn_data[icode].operand[j].mode;
7318 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
7319 machine_mode opmode = GET_MODE (op);
7320 char c = insn_data[icode].operand[j].constraint[0];
7321
7322 /* SIMD extension requires exact immediate operand match. */
7323 if ((id > ARC_BUILTIN_SIMD_BEGIN)
7324 && (id < ARC_BUILTIN_SIMD_END)
7325 && (c != 'v')
7326 && (c != 'r'))
526b7aee 7327 {
c69899f0
CZ
7328 if (!CONST_INT_P (op))
7329 error ("builtin requires an immediate for operand %d", j);
7330 switch (c)
526b7aee 7331 {
c69899f0
CZ
7332 case 'L':
7333 if (!satisfies_constraint_L (op))
7334 error ("operand %d should be a 6 bit unsigned immediate", j);
7335 break;
7336 case 'P':
7337 if (!satisfies_constraint_P (op))
7338 error ("operand %d should be a 8 bit unsigned immediate", j);
7339 break;
7340 case 'K':
7341 if (!satisfies_constraint_K (op))
7342 error ("operand %d should be a 3 bit unsigned immediate", j);
7343 break;
7344 default:
7345 error ("unknown builtin immediate operand type for operand %d",
7346 j);
526b7aee 7347 }
c69899f0 7348 }
526b7aee 7349
c69899f0
CZ
7350 if (CONST_INT_P (op))
7351 opmode = mode;
526b7aee 7352
c69899f0
CZ
7353 if ((opmode == SImode) && (mode == HImode))
7354 {
7355 opmode = HImode;
7356 op = gen_lowpart (HImode, op);
526b7aee
SV
7357 }
7358
c69899f0
CZ
7359 /* In case the insn wants input operands in modes different from
7360 the result, abort. */
7361 gcc_assert (opmode == mode || opmode == VOIDmode);
526b7aee 7362
c69899f0
CZ
7363 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
7364 op = copy_to_mode_reg (mode, op);
7365
7366 xop[j] = op;
526b7aee
SV
7367 }
7368
c69899f0
CZ
7369 pat = apply_GEN_FCN (icode, xop);
7370 if (pat == NULL_RTX)
7371 return NULL_RTX;
7372
7373 emit_insn (pat);
7374
7375 if (nonvoid)
7376 return target;
7377 else
7378 return const0_rtx;
526b7aee
SV
7379}
7380
7381/* Returns true if the operands[opno] is a valid compile-time constant to be
7382 used as register number in the code for builtins. Else it flags an error
7383 and returns false. */
7384
7385bool
7386check_if_valid_regno_const (rtx *operands, int opno)
7387{
7388
7389 switch (GET_CODE (operands[opno]))
7390 {
7391 case SYMBOL_REF :
7392 case CONST :
7393 case CONST_INT :
7394 return true;
7395 default:
2fa9c1f6
CZ
7396 error ("register number must be a compile-time constant. "
7397 "Try giving higher optimization levels");
526b7aee
SV
7398 break;
7399 }
7400 return false;
7401}
7402
526b7aee
SV
7403/* Return true if it is ok to make a tail-call to DECL. */
7404
7405static bool
6b55f8c9 7406arc_function_ok_for_sibcall (tree decl,
526b7aee
SV
7407 tree exp ATTRIBUTE_UNUSED)
7408{
6b55f8c9
CZ
7409 tree attrs = NULL_TREE;
7410
526b7aee
SV
7411 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7412 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
7413 return false;
7414
6b55f8c9
CZ
7415 if (decl)
7416 {
7417 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
7418
7419 if (lookup_attribute ("jli_always", attrs))
7420 return false;
7421 if (lookup_attribute ("jli_fixed", attrs))
7422 return false;
7778a1ad
CZ
7423 if (lookup_attribute ("secure_call", attrs))
7424 return false;
6b55f8c9
CZ
7425 }
7426
526b7aee
SV
7427 /* Everything else is ok. */
7428 return true;
7429}
7430
7431/* Output code to add DELTA to the first argument, and then jump
7432 to FUNCTION. Used for C++ multiple inheritance. */
7433
7434static void
7435arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7436 HOST_WIDE_INT delta,
7437 HOST_WIDE_INT vcall_offset,
7438 tree function)
7439{
f7430263 7440 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
526b7aee
SV
7441 int mi_delta = delta;
7442 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
7443 int shift = 0;
7444 int this_regno
7445 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
7446 rtx fnaddr;
7447
f7430263
MF
7448 assemble_start_function (thunk, fnname);
7449
526b7aee
SV
7450 if (mi_delta < 0)
7451 mi_delta = - mi_delta;
7452
7453 /* Add DELTA. When possible use a plain add, otherwise load it into
7454 a register first. */
7455
7456 while (mi_delta != 0)
7457 {
7458 if ((mi_delta & (3 << shift)) == 0)
7459 shift += 2;
7460 else
7461 {
7462 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
7463 mi_op, reg_names[this_regno], reg_names[this_regno],
7464 mi_delta & (0xff << shift));
7465 mi_delta &= ~(0xff << shift);
7466 shift += 8;
7467 }
7468 }
7469
7470 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7471 if (vcall_offset != 0)
7472 {
7473 /* ld r12,[this] --> temp = *this
7474 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7475 ld r12,[r12]
7476 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7477 asm_fprintf (file, "\tld\t%s, [%s]\n",
7478 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
dfca07ea 7479 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
526b7aee
SV
7480 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7481 asm_fprintf (file, "\tld\t%s, [%s]\n",
7482 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7483 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7484 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7485 }
7486
7487 fnaddr = XEXP (DECL_RTL (function), 0);
7488
7489 if (arc_is_longcall_p (fnaddr))
1f8876c7
CZ
7490 {
7491 if (flag_pic)
7492 {
7493 asm_fprintf (file, "\tld\t%s, [pcl, @",
7494 ARC_TEMP_SCRATCH_REG);
7495 assemble_name (file, XSTR (fnaddr, 0));
7496 fputs ("@gotpc]\n", file);
7497 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7498 }
7499 else
7500 {
7501 fputs ("\tj\t@", file);
7502 assemble_name (file, XSTR (fnaddr, 0));
7503 }
7504 }
526b7aee 7505 else
1f8876c7
CZ
7506 {
7507 fputs ("\tb\t@", file);
7508 assemble_name (file, XSTR (fnaddr, 0));
7509 if (flag_pic)
7510 fputs ("@plt\n", file);
7511 }
526b7aee 7512 fputc ('\n', file);
f7430263 7513 assemble_end_function (thunk, fnname);
526b7aee
SV
7514}
7515
7516/* Return true if a 32 bit "long_call" should be generated for
7517 this calling SYM_REF. We generate a long_call if the function:
7518
7519 a. has an __attribute__((long call))
7520 or b. the -mlong-calls command line switch has been specified
7521
7522 However we do not generate a long call if the function has an
7523 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7524
7525 This function will be called by C fragments contained in the machine
7526 description file. */
7527
7528bool
7529arc_is_longcall_p (rtx sym_ref)
7530{
7531 if (GET_CODE (sym_ref) != SYMBOL_REF)
7532 return false;
7533
7534 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7535 || (TARGET_LONG_CALLS_SET
7536 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7537 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7538
7539}
7540
7541/* Likewise for short calls. */
7542
7543bool
7544arc_is_shortcall_p (rtx sym_ref)
7545{
7546 if (GET_CODE (sym_ref) != SYMBOL_REF)
7547 return false;
7548
7549 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7550 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7551 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7552 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7553
7554}
7555
526b7aee
SV
7556/* Worker function for TARGET_RETURN_IN_MEMORY. */
7557
7558static bool
7559arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7560{
7561 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7562 return true;
7563 else
7564 {
7565 HOST_WIDE_INT size = int_size_in_bytes (type);
f50bb868 7566 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
526b7aee
SV
7567 }
7568}
7569
526b7aee
SV
7570static bool
7571arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
ef4bddc2 7572 machine_mode mode ATTRIBUTE_UNUSED,
526b7aee
SV
7573 const_tree type,
7574 bool named ATTRIBUTE_UNUSED)
7575{
7576 return (type != 0
7577 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
7578 || TREE_ADDRESSABLE (type)));
7579}
7580
1d0216c8
RS
7581/* Implement TARGET_CAN_USE_DOLOOP_P. */
7582
7583static bool
a2de90a4
CZ
7584arc_can_use_doloop_p (const widest_int &,
7585 const widest_int &iterations_max,
1d0216c8
RS
7586 unsigned int loop_depth, bool entered_at_top)
7587{
a2de90a4
CZ
7588 /* Considering limitations in the hardware, only use doloop
7589 for innermost loops which must be entered from the top. */
7590 if (loop_depth > 1 || !entered_at_top)
1d0216c8 7591 return false;
a2de90a4
CZ
7592
7593 /* Check for lp_count width boundary. */
7594 if (arc_lpcwidth != 32
7595 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7596 || wi::eq_p (iterations_max, 0)))
1d0216c8
RS
7597 return false;
7598 return true;
7599}
526b7aee 7600
a2de90a4
CZ
7601/* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7602 return why doloop cannot be applied. */
526b7aee
SV
7603
7604static const char *
ac44248e 7605arc_invalid_within_doloop (const rtx_insn *insn)
526b7aee
SV
7606{
7607 if (CALL_P (insn))
7608 return "Function call in the loop.";
a2de90a4
CZ
7609
7610 /* FIXME! add here all the ZOL exceptions. */
526b7aee
SV
7611 return NULL;
7612}
7613
635aeaa2
CZ
7614/* Return the next active insn, skiping the inline assembly code. */
7615
7616static rtx_insn *
7617arc_active_insn (rtx_insn *insn)
7618{
7619 rtx_insn *nxt = next_active_insn (insn);
7620
7621 if (nxt && GET_CODE (PATTERN (nxt)) == ASM_INPUT)
7622 nxt = next_active_insn (nxt);
7623 return nxt;
7624}
7625
7626/* Search for a sequence made out of two stores and a given number of
7627 loads, insert a nop if required. */
7628
7629static void
7630check_store_cacheline_hazard (void)
7631{
7632 rtx_insn *insn, *succ0, *insn1;
7633 bool found = false;
7634
7635 for (insn = get_insns (); insn; insn = arc_active_insn (insn))
7636 {
7637 succ0 = arc_active_insn (insn);
7638
7639 if (!succ0)
7640 return;
7641
7642 if (!single_set (insn) || !single_set (succ0))
7643 continue;
7644
7645 if ((get_attr_type (insn) != TYPE_STORE)
7646 || (get_attr_type (succ0) != TYPE_STORE))
7647 continue;
7648
7649 /* Found at least two consecutive stores. Goto the end of the
7650 store sequence. */
7651 for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1))
7652 if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE)
7653 break;
7654
7655 /* Now, check the next two instructions for the following cases:
7656 1. next instruction is a LD => insert 2 nops between store
7657 sequence and load.
7658 2. next-next instruction is a LD => inset 1 nop after the store
7659 sequence. */
7660 if (insn1 && single_set (insn1)
7661 && (get_attr_type (insn1) == TYPE_LOAD))
7662 {
7663 found = true;
7664 emit_insn_before (gen_nopv (), insn1);
7665 emit_insn_before (gen_nopv (), insn1);
7666 }
7667 else
7668 {
7669 if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE))
7670 {
7671 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7672 reorg, so it is safe to reuse it for avoiding the
7673 current compare insn to be part of a BRcc
7674 optimization. */
7675 add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3));
7676 }
7677 insn1 = arc_active_insn (insn1);
7678 if (insn1 && single_set (insn1)
7679 && (get_attr_type (insn1) == TYPE_LOAD))
7680 {
7681 found = true;
7682 emit_insn_before (gen_nopv (), insn1);
7683 }
7684 }
7685
7686 insn = insn1;
7687 if (found)
7688 found = false;
7689 }
7690}
7691
e9472c81
AB
7692/* Return true if a load instruction (CONSUMER) uses the same address as a
7693 store instruction (PRODUCER). This function is used to avoid st/ld
7694 address hazard in ARC700 cores. */
635aeaa2
CZ
7695
7696static bool
7697arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer)
e9472c81
AB
7698{
7699 rtx in_set, out_set;
7700 rtx out_addr, in_addr;
7701
7702 if (!producer)
7703 return false;
7704
7705 if (!consumer)
7706 return false;
7707
7708 /* Peel the producer and the consumer for the address. */
7709 out_set = single_set (producer);
7710 if (out_set)
7711 {
7712 out_addr = SET_DEST (out_set);
7713 if (!out_addr)
7714 return false;
7715 if (GET_CODE (out_addr) == ZERO_EXTEND
7716 || GET_CODE (out_addr) == SIGN_EXTEND)
7717 out_addr = XEXP (out_addr, 0);
7718
7719 if (!MEM_P (out_addr))
7720 return false;
7721
7722 in_set = single_set (consumer);
7723 if (in_set)
7724 {
7725 in_addr = SET_SRC (in_set);
7726 if (!in_addr)
7727 return false;
7728 if (GET_CODE (in_addr) == ZERO_EXTEND
7729 || GET_CODE (in_addr) == SIGN_EXTEND)
7730 in_addr = XEXP (in_addr, 0);
7731
7732 if (!MEM_P (in_addr))
7733 return false;
7734 /* Get rid of the MEM and check if the addresses are
7735 equivalent. */
7736 in_addr = XEXP (in_addr, 0);
7737 out_addr = XEXP (out_addr, 0);
7738
7739 return exp_equiv_p (in_addr, out_addr, 0, true);
7740 }
7741 }
7742 return false;
7743}
7744
635aeaa2
CZ
7745/* Return TRUE is we have an store address hazard. */
7746
7747bool
7748arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7749{
7750 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
7751 return true;
7752 return arc_store_addr_hazard_internal_p (producer, consumer);
7753}
7754
f50bb868
CZ
7755/* The same functionality as arc_hazard. It is called in machine
7756 reorg before any other optimization. Hence, the NOP size is taken
7757 into account when doing branch shortening. */
7758
7759static void
7760workaround_arc_anomaly (void)
7761{
7762 rtx_insn *insn, *succ0;
635aeaa2 7763 rtx_insn *succ1;
f50bb868
CZ
7764
7765 /* For any architecture: call arc_hazard here. */
7766 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7767 {
7768 succ0 = next_real_insn (insn);
7769 if (arc_hazard (insn, succ0))
7770 {
7771 emit_insn_before (gen_nopv (), succ0);
7772 }
7773 }
e9472c81 7774
635aeaa2
CZ
7775 if (!TARGET_ARC700)
7776 return;
e9472c81 7777
635aeaa2
CZ
7778 /* Old A7 are suffering of a cache hazard, and we need to insert two
7779 nops between any sequence of stores and a load. */
7780 if (arc_tune != ARC_TUNE_ARC7XX)
7781 check_store_cacheline_hazard ();
e9472c81 7782
635aeaa2
CZ
7783 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7784 {
7785 succ0 = next_real_insn (insn);
7786 if (arc_store_addr_hazard_internal_p (insn, succ0))
7787 {
7788 emit_insn_after (gen_nopv (), insn);
7789 emit_insn_after (gen_nopv (), insn);
7790 continue;
e9472c81 7791 }
635aeaa2
CZ
7792
7793 /* Avoid adding nops if the instruction between the ST and LD is
7794 a call or jump. */
7795 succ1 = next_real_insn (succ0);
7796 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0)
7797 && arc_store_addr_hazard_internal_p (insn, succ1))
7798 emit_insn_after (gen_nopv (), insn);
e9472c81 7799 }
f50bb868
CZ
7800}
7801
a2de90a4
CZ
7802/* A callback for the hw-doloop pass. Called when a loop we have discovered
7803 turns out not to be optimizable; we have to split the loop_end pattern into
7804 a subtract and a test. */
7805
7806static void
7807hwloop_fail (hwloop_info loop)
7808{
7809 rtx test;
7810 rtx insn = loop->loop_end;
7811
62f26645 7812 if (TARGET_DBNZ
a2de90a4
CZ
7813 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7814 && REG_P (loop->iter_reg))
7815 {
62f26645 7816 /* TARGET_V2 core3 has dbnz instructions. */
a2de90a4
CZ
7817 test = gen_dbnz (loop->iter_reg, loop->start_label);
7818 insn = emit_jump_insn_before (test, loop->loop_end);
7819 }
7820 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7821 {
7822 /* We have the lp_count as loop iterator, try to use it. */
7823 emit_insn_before (gen_loop_fail (), loop->loop_end);
7824 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7825 const0_rtx);
7826 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7827 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7828 pc_rtx);
7829 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7830 loop->loop_end);
7831 }
7832 else
7833 {
7834 emit_insn_before (gen_addsi3 (loop->iter_reg,
7835 loop->iter_reg,
7836 constm1_rtx),
7837 loop->loop_end);
7838 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7839 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7840 loop->iter_reg,
7841 const0_rtx,
7842 loop->start_label),
7843 loop->loop_end);
7844 }
7845 JUMP_LABEL (insn) = loop->start_label;
7846 LABEL_NUSES (loop->start_label)++;
7847 delete_insn (loop->loop_end);
7848}
7849
73dac59b
CZ
7850/* Return the next insn after INSN that is not a NOTE, but stop the
7851 search before we enter another basic block. This routine does not
7852 look inside SEQUENCEs. */
7853
7854static rtx_insn *
7855next_nonnote_insn_bb (rtx_insn *insn)
7856{
7857 while (insn)
7858 {
7859 insn = NEXT_INSN (insn);
7860 if (insn == 0 || !NOTE_P (insn))
7861 break;
7862 if (NOTE_INSN_BASIC_BLOCK_P (insn))
7863 return NULL;
7864 }
7865
7866 return insn;
7867}
7868
a2de90a4
CZ
7869/* Optimize LOOP. */
7870
7871static bool
7872hwloop_optimize (hwloop_info loop)
7873{
7874 int i;
7875 edge entry_edge;
7876 basic_block entry_bb, bb;
4dea3bff
DM
7877 rtx iter_reg;
7878 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label;
a2de90a4
CZ
7879 unsigned int length;
7880 bool need_fix = false;
7881 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7882
7883 if (loop->depth > 1)
7884 {
7885 if (dump_file)
73dac59b
CZ
7886 fprintf (dump_file, ";; loop %d is not innermost\n",
7887 loop->loop_no);
a2de90a4
CZ
7888 return false;
7889 }
7890
7891 if (!loop->incoming_dest)
7892 {
7893 if (dump_file)
73dac59b
CZ
7894 fprintf (dump_file, ";; loop %d has more than one entry\n",
7895 loop->loop_no);
a2de90a4
CZ
7896 return false;
7897 }
7898
7899 if (loop->incoming_dest != loop->head)
7900 {
7901 if (dump_file)
73dac59b
CZ
7902 fprintf (dump_file, ";; loop %d is not entered from head\n",
7903 loop->loop_no);
a2de90a4
CZ
7904 return false;
7905 }
7906
7907 if (loop->has_call || loop->has_asm)
7908 {
7909 if (dump_file)
73dac59b
CZ
7910 fprintf (dump_file, ";; loop %d has invalid insn\n",
7911 loop->loop_no);
a2de90a4
CZ
7912 return false;
7913 }
7914
7915 /* Scan all the blocks to make sure they don't use iter_reg. */
7916 if (loop->iter_reg_used || loop->iter_reg_used_outside)
7917 {
7918 if (dump_file)
73dac59b
CZ
7919 fprintf (dump_file, ";; loop %d uses iterator\n",
7920 loop->loop_no);
a2de90a4
CZ
7921 return false;
7922 }
7923
7924 /* Check if start_label appears before doloop_end. */
7925 length = 0;
7926 for (insn = loop->start_label;
7927 insn && insn != loop->loop_end;
7928 insn = NEXT_INSN (insn))
dddc1815
CZ
7929 {
7930 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
7931 if (JUMP_TABLES_IN_TEXT_SECTION
7932 && JUMP_TABLE_DATA_P (insn))
7933 {
7934 if (dump_file)
7935 fprintf (dump_file, ";; loop %d has a jump table\n",
7936 loop->loop_no);
7937 return false;
7938 }
7939 }
a2de90a4
CZ
7940
7941 if (!insn)
7942 {
7943 if (dump_file)
73dac59b
CZ
7944 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
7945 loop->loop_no);
a2de90a4
CZ
7946 return false;
7947 }
7948
7949 loop->length = length;
7950 if (loop->length > ARC_MAX_LOOP_LENGTH)
7951 {
7952 if (dump_file)
7953 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7954 return false;
7955 }
5b5905bb
CZ
7956 else if (!loop->length)
7957 {
7958 if (dump_file)
7959 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
7960 return false;
7961 }
a2de90a4 7962
73dac59b 7963 /* Check if we use a register or not. */
a2de90a4
CZ
7964 if (!REG_P (loop->iter_reg))
7965 {
7966 if (dump_file)
73dac59b
CZ
7967 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7968 loop->loop_no);
7969 return false;
7970 }
7971
7972 /* Check if we use a register or not. */
7973 if (!REG_P (loop->iter_reg))
7974 {
7975 if (dump_file)
7976 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7977 loop->loop_no);
a2de90a4
CZ
7978 return false;
7979 }
7980
7981 /* Check if loop register is lpcount. */
7982 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
7983 {
7984 if (dump_file)
7985 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
7986 " iterator\n",
7987 loop->loop_no);
7988 /* This loop doesn't use the lp_count, check though if we can
7989 fix it. */
7990 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
7991 /* In very unique cases we may have LP_COUNT alive. */
7992 || (loop->incoming_src
7993 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
7994 LP_COUNT)))
73dac59b
CZ
7995 {
7996 if (dump_file)
7997 fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no);
7998 return false;
7999 }
a2de90a4
CZ
8000 else
8001 need_fix = true;
8002 }
8003
8004 /* Check for control like instruction as the last instruction of a
8005 ZOL. */
8006 bb = loop->tail;
8007 last_insn = PREV_INSN (loop->loop_end);
8008
8009 while (1)
8010 {
8011 for (; last_insn != BB_HEAD (bb);
8012 last_insn = PREV_INSN (last_insn))
8013 if (NONDEBUG_INSN_P (last_insn))
8014 break;
8015
8016 if (last_insn != BB_HEAD (bb))
8017 break;
8018
8019 if (single_pred_p (bb)
8020 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
8021 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
8022 {
8023 bb = single_pred (bb);
8024 last_insn = BB_END (bb);
8025 continue;
8026 }
8027 else
8028 {
8029 last_insn = NULL;
8030 break;
8031 }
8032 }
8033
8034 if (!last_insn)
8035 {
8036 if (dump_file)
8037 fprintf (dump_file, ";; loop %d has no last instruction\n",
8038 loop->loop_no);
8039 return false;
8040 }
8041
8042 if ((TARGET_ARC600_FAMILY || TARGET_HS)
8043 && INSN_P (last_insn)
8044 && (JUMP_P (last_insn) || CALL_P (last_insn)
8045 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
5b5905bb
CZ
8046 /* At this stage we can have (insn (clobber (mem:BLK
8047 (reg)))) instructions, ignore them. */
8048 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
8049 && (get_attr_type (last_insn) == TYPE_BRCC
8050 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
a2de90a4
CZ
8051 {
8052 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
8053 {
8054 if (dump_file)
8055 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
8056 return false;
8057 }
8058 if (dump_file)
8059 fprintf (dump_file, ";; loop %d has a control like last insn;"
8060 "add a nop\n",
8061 loop->loop_no);
8062
8063 last_insn = emit_insn_after (gen_nopv (), last_insn);
8064 }
8065
8066 if (LABEL_P (last_insn))
8067 {
8068 if (dump_file)
8069 fprintf (dump_file, ";; loop %d has a label as last insn;"
8070 "add a nop\n",
8071 loop->loop_no);
8072 last_insn = emit_insn_after (gen_nopv (), last_insn);
8073 }
a0920243
CZ
8074
8075 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
8076 and we can use it to indicate the last ZOL instruction cannot be
8077 part of a delay slot. */
8078 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
8079
a2de90a4
CZ
8080 loop->last_insn = last_insn;
8081
8082 /* Get the loop iteration register. */
8083 iter_reg = loop->iter_reg;
8084
8085 gcc_assert (REG_P (iter_reg));
8086
8087 entry_edge = NULL;
8088
8089 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
8090 if (entry_edge->flags & EDGE_FALLTHRU)
8091 break;
8092
8093 if (entry_edge == NULL)
8094 {
8095 if (dump_file)
8096 fprintf (dump_file, ";; loop %d has no fallthru edge jumping"
8097 "into the loop\n",
8098 loop->loop_no);
8099 return false;
8100 }
8101 /* The loop is good. */
8102 end_label = gen_label_rtx ();
8103 loop->end_label = end_label;
8104
8105 /* Place the zero_cost_loop_start instruction before the loop. */
8106 entry_bb = entry_edge->src;
8107
8108 start_sequence ();
8109
8110 if (need_fix)
8111 {
8112 /* The loop uses a R-register, but the lp_count is free, thus
8113 use lp_count. */
73dac59b 8114 emit_insn (gen_rtx_SET (lp_reg, iter_reg));
a2de90a4
CZ
8115 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
8116 iter_reg = lp_reg;
8117 if (dump_file)
8118 {
8119 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
8120 loop->loop_no);
8121 }
8122 }
8123
73dac59b 8124 insn = emit_insn (gen_arc_lp (loop->start_label,
a2de90a4
CZ
8125 loop->end_label));
8126
8127 seq = get_insns ();
8128 end_sequence ();
8129
8130 entry_after = BB_END (entry_bb);
8131 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
8132 || !entry_after)
8133 {
8134 basic_block new_bb;
8135 edge e;
8136 edge_iterator ei;
8137
8138 emit_insn_before (seq, BB_HEAD (loop->head));
8139 seq = emit_label_before (gen_label_rtx (), seq);
8140 new_bb = create_basic_block (seq, insn, entry_bb);
8141 FOR_EACH_EDGE (e, ei, loop->incoming)
73dac59b
CZ
8142 {
8143 if (!(e->flags & EDGE_FALLTHRU))
8144 redirect_edge_and_branch_force (e, new_bb);
8145 else
8146 redirect_edge_succ (e, new_bb);
8147 }
a2de90a4
CZ
8148
8149 make_edge (new_bb, loop->head, 0);
8150 }
8151 else
8152 {
8153#if 0
8154 while (DEBUG_INSN_P (entry_after)
73dac59b
CZ
8155 || (NOTE_P (entry_after)
8156 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
8157 /* Make sure we don't split a call and its corresponding
8158 CALL_ARG_LOCATION note. */
8159 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
a2de90a4
CZ
8160 entry_after = NEXT_INSN (entry_after);
8161#endif
73dac59b 8162 entry_after = next_nonnote_insn_bb (entry_after);
a2de90a4
CZ
8163
8164 gcc_assert (entry_after);
8165 emit_insn_before (seq, entry_after);
8166 }
8167
a2de90a4
CZ
8168 /* Insert the loop end label before the last instruction of the
8169 loop. */
8170 emit_label_after (end_label, loop->last_insn);
5d4c34aa
CZ
8171 /* Make sure we mark the begining and end label as used. */
8172 LABEL_NUSES (loop->end_label)++;
8173 LABEL_NUSES (loop->start_label)++;
a2de90a4
CZ
8174
8175 return true;
8176}
8177
8178/* A callback for the hw-doloop pass. This function examines INSN; if
8179 it is a loop_end pattern we recognize, return the reg rtx for the
8180 loop counter. Otherwise, return NULL_RTX. */
8181
8182static rtx
8183hwloop_pattern_reg (rtx_insn *insn)
8184{
8185 rtx reg;
8186
8187 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
8188 return NULL_RTX;
8189
8190 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
8191 if (!REG_P (reg))
8192 return NULL_RTX;
8193 return reg;
8194}
8195
8196static struct hw_doloop_hooks arc_doloop_hooks =
8197{
8198 hwloop_pattern_reg,
8199 hwloop_optimize,
8200 hwloop_fail
8201};
8202
8203/* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8204 and tries to rewrite the RTL of these loops so that proper Blackfin
8205 hardware loops are generated. */
8206
8207static void
8208arc_reorg_loops (void)
8209{
8210 reorg_loops (true, &arc_doloop_hooks);
8211}
8212
6b55f8c9
CZ
8213/* Scan all calls and add symbols to be emitted in the jli section if
8214 needed. */
8215
8216static void
8217jli_call_scan (void)
8218{
8219 rtx_insn *insn;
8220
8221 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8222 {
8223 if (!CALL_P (insn))
8224 continue;
8225
8226 rtx pat = PATTERN (insn);
8227 if (GET_CODE (pat) == COND_EXEC)
8228 pat = COND_EXEC_CODE (pat);
8229 pat = XVECEXP (pat, 0, 0);
8230 if (GET_CODE (pat) == SET)
8231 pat = SET_SRC (pat);
8232
8233 pat = XEXP (XEXP (pat, 0), 0);
8234 if (GET_CODE (pat) == SYMBOL_REF
8235 && arc_is_jli_call_p (pat))
8236 arc_add_jli_section (pat);
8237 }
8238}
8239
16493b57
CZ
8240/* Add padding if necessary to avoid a mispredict. A return could
8241 happen immediately after the function start. A call/return and
8242 return/return must be 6 bytes apart to avoid mispredict. */
8243
8244static void
8245pad_return (void)
8246{
8247 rtx_insn *insn;
8248 long offset;
8249
8250 if (!TARGET_PAD_RETURN)
8251 return;
8252
8253 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8254 {
8255 rtx_insn *prev0 = prev_active_insn (insn);
8256 bool wantlong = false;
8257
8258 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN)
8259 continue;
8260
8261 if (!prev0)
8262 {
8263 prev0 = emit_insn_before (gen_nopv (), insn);
8264 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8265 so it is safe to reuse it for forcing a particular length
8266 for an instruction. */
8267 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8268 emit_insn_before (gen_nopv (), insn);
8269 continue;
8270 }
8271 offset = get_attr_length (prev0);
8272
8273 if (get_attr_length (prev0) == 2
8274 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE)
8275 {
8276 /* Force long version of the insn. */
8277 wantlong = true;
8278 offset += 2;
8279 }
8280
8281 rtx_insn *prev = prev_active_insn (prev0);
8282 if (prev)
8283 offset += get_attr_length (prev);
8284
8285 prev = prev_active_insn (prev);
8286 if (prev)
8287 offset += get_attr_length (prev);
8288
8289 switch (offset)
8290 {
8291 case 2:
8292 prev = emit_insn_before (gen_nopv (), insn);
8293 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1));
8294 break;
8295 case 4:
8296 emit_insn_before (gen_nopv (), insn);
8297 break;
8298 default:
8299 continue;
8300 }
8301
8302 if (wantlong)
8303 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8304
8305 /* Emit a blockage to avoid delay slot scheduling. */
8306 emit_insn_before (gen_blockage (), insn);
8307 }
8308}
8309
526b7aee
SV
8310static int arc_reorg_in_progress = 0;
8311
8312/* ARC's machince specific reorg function. */
8313
8314static void
8315arc_reorg (void)
8316{
b3458f61
DM
8317 rtx_insn *insn;
8318 rtx pattern;
526b7aee
SV
8319 rtx pc_target;
8320 long offset;
8321 int changed;
8322
8323 cfun->machine->arc_reorg_started = 1;
8324 arc_reorg_in_progress = 1;
8325
a2de90a4 8326 compute_bb_for_insn ();
526b7aee 8327
a2de90a4 8328 df_analyze ();
526b7aee 8329
a2de90a4
CZ
8330 /* Doloop optimization. */
8331 arc_reorg_loops ();
526b7aee 8332
a2de90a4 8333 workaround_arc_anomaly ();
6b55f8c9 8334 jli_call_scan ();
16493b57 8335 pad_return ();
526b7aee
SV
8336
8337/* FIXME: should anticipate ccfsm action, generate special patterns for
8338 to-be-deleted branches that have no delay slot and have at least the
8339 length of the size increase forced on other insns that are conditionalized.
8340 This can also have an insn_list inside that enumerates insns which are
8341 not actually conditionalized because the destinations are dead in the
8342 not-execute case.
8343 Could also tag branches that we want to be unaligned if they get no delay
8344 slot, or even ones that we don't want to do delay slot sheduling for
8345 because we can unalign them.
8346
8347 However, there are cases when conditional execution is only possible after
8348 delay slot scheduling:
8349
8350 - If a delay slot is filled with a nocond/set insn from above, the previous
8351 basic block can become elegible for conditional execution.
8352 - If a delay slot is filled with a nocond insn from the fall-through path,
8353 the branch with that delay slot can become eligble for conditional
8354 execution (however, with the same sort of data flow analysis that dbr
8355 does, we could have figured out before that we don't need to
8356 conditionalize this insn.)
8357 - If a delay slot insn is filled with an insn from the target, the
8358 target label gets its uses decremented (even deleted if falling to zero),
8359 thus possibly creating more condexec opportunities there.
8360 Therefore, we should still be prepared to apply condexec optimization on
8361 non-prepared branches if the size increase of conditionalized insns is no
8362 more than the size saved from eliminating the branch. An invocation option
8363 could also be used to reserve a bit of extra size for condbranches so that
8364 this'll work more often (could also test in arc_reorg if the block is
8365 'close enough' to be eligible for condexec to make this likely, and
8366 estimate required size increase). */
8367 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8368 if (TARGET_NO_BRCC_SET)
8369 return;
8370
8371 do
8372 {
8373 init_insn_lengths();
8374 changed = 0;
8375
8376 if (optimize > 1 && !TARGET_NO_COND_EXEC)
8377 {
8378 arc_ifcvt ();
8379 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
8380 df_finish_pass ((flags & TODO_df_verify) != 0);
782bdf21
CZ
8381
8382 if (dump_file)
8383 {
8384 fprintf (dump_file, ";; After if conversion:\n\n");
8385 print_rtl (dump_file, get_insns ());
8386 }
526b7aee
SV
8387 }
8388
8389 /* Call shorten_branches to calculate the insn lengths. */
8390 shorten_branches (get_insns());
8391 cfun->machine->ccfsm_current_insn = NULL_RTX;
8392
8393 if (!INSN_ADDRESSES_SET_P())
2fa9c1f6
CZ
8394 fatal_error (input_location,
8395 "insn addresses not set after shorten_branches");
526b7aee
SV
8396
8397 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8398 {
8399 rtx label;
8400 enum attr_type insn_type;
8401
8402 /* If a non-jump insn (or a casesi jump table), continue. */
8403 if (GET_CODE (insn) != JUMP_INSN ||
8404 GET_CODE (PATTERN (insn)) == ADDR_VEC
8405 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
8406 continue;
8407
8408 /* If we already have a brcc, note if it is suitable for brcc_s.
8409 Be a bit generous with the brcc_s range so that we can take
8410 advantage of any code shortening from delay slot scheduling. */
8411 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
8412 {
8413 rtx pat = PATTERN (insn);
8414 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
8415 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
8416
8417 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8418 if ((offset >= -140 && offset < 140)
8419 && rtx_equal_p (XEXP (op, 1), const0_rtx)
8420 && compact_register_operand (XEXP (op, 0), VOIDmode)
8421 && equality_comparison_operator (op, VOIDmode))
8422 PUT_MODE (*ccp, CC_Zmode);
8423 else if (GET_MODE (*ccp) == CC_Zmode)
8424 PUT_MODE (*ccp, CC_ZNmode);
8425 continue;
8426 }
8427 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
8428 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
8429 continue;
8430
8431 /* OK. so we have a jump insn. */
8432 /* We need to check that it is a bcc. */
8433 /* Bcc => set (pc) (if_then_else ) */
8434 pattern = PATTERN (insn);
8435 if (GET_CODE (pattern) != SET
8436 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
8437 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
8438 continue;
8439
8440 /* Now check if the jump is beyond the s9 range. */
339ba33b 8441 if (CROSSING_JUMP_P (insn))
526b7aee
SV
8442 continue;
8443 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8444
8445 if(offset > 253 || offset < -254)
8446 continue;
8447
8448 pc_target = SET_SRC (pattern);
8449
8f3304d0
CZ
8450 /* Avoid FPU instructions. */
8451 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
8452 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
8453 continue;
8454
526b7aee
SV
8455 /* Now go back and search for the set cc insn. */
8456
8457 label = XEXP (pc_target, 1);
8458
8459 {
b3458f61
DM
8460 rtx pat;
8461 rtx_insn *scan, *link_insn = NULL;
526b7aee
SV
8462
8463 for (scan = PREV_INSN (insn);
8464 scan && GET_CODE (scan) != CODE_LABEL;
8465 scan = PREV_INSN (scan))
8466 {
8467 if (! INSN_P (scan))
8468 continue;
8469 pat = PATTERN (scan);
8470 if (GET_CODE (pat) == SET
8471 && cc_register (SET_DEST (pat), VOIDmode))
8472 {
8473 link_insn = scan;
8474 break;
8475 }
8476 }
8f3304d0 8477 if (!link_insn)
526b7aee
SV
8478 continue;
8479 else
526b7aee 8480 {
635aeaa2 8481 /* Check if this is a data dependency. */
526b7aee
SV
8482 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
8483 rtx cmp0, cmp1;
8484
635aeaa2
CZ
8485 /* Make sure we can use it for brcc insns. */
8486 if (find_reg_note (link_insn, REG_SAVE_NOTE, GEN_INT (3)))
8487 continue;
8488
526b7aee
SV
8489 /* Ok this is the set cc. copy args here. */
8490 op = XEXP (pc_target, 0);
8491
8492 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
8493 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
8494 if (GET_CODE (op0) == ZERO_EXTRACT
8495 && XEXP (op0, 1) == const1_rtx
8496 && (GET_CODE (op) == EQ
8497 || GET_CODE (op) == NE))
8498 {
8499 /* btst / b{eq,ne} -> bbit{0,1} */
8500 op0 = XEXP (cmp0, 0);
8501 op1 = XEXP (cmp0, 2);
8502 }
8503 else if (!register_operand (op0, VOIDmode)
8504 || !general_operand (op1, VOIDmode))
8505 continue;
8506 /* Be careful not to break what cmpsfpx_raw is
8507 trying to create for checking equality of
8508 single-precision floats. */
8509 else if (TARGET_SPFP
8510 && GET_MODE (op0) == SFmode
8511 && GET_MODE (op1) == SFmode)
8512 continue;
8513
8514 /* None of the two cmp operands should be set between the
8515 cmp and the branch. */
8516 if (reg_set_between_p (op0, link_insn, insn))
8517 continue;
8518
8519 if (reg_set_between_p (op1, link_insn, insn))
8520 continue;
8521
8522 /* Since the MODE check does not work, check that this is
8523 CC reg's last set location before insn, and also no
8524 instruction between the cmp and branch uses the
8525 condition codes. */
8526 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
8527 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
8528 continue;
8529
8530 /* CC reg should be dead after insn. */
8531 if (!find_regno_note (insn, REG_DEAD, CC_REG))
8532 continue;
8533
8534 op = gen_rtx_fmt_ee (GET_CODE (op),
8535 GET_MODE (op), cmp0, cmp1);
8536 /* If we create a LIMM where there was none before,
8537 we only benefit if we can avoid a scheduling bubble
8538 for the ARC600. Otherwise, we'd only forgo chances
8539 at short insn generation, and risk out-of-range
8540 branches. */
8541 if (!brcc_nolimm_operator (op, VOIDmode)
8542 && !long_immediate_operand (op1, VOIDmode)
8543 && (TARGET_ARC700
8544 || next_active_insn (link_insn) != insn))
8545 continue;
8546
8547 /* Emit bbit / brcc (or brcc_s if possible).
8548 CC_Zmode indicates that brcc_s is possible. */
8549
8550 if (op0 != cmp0)
8551 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
8552 else if ((offset >= -140 && offset < 140)
8553 && rtx_equal_p (op1, const0_rtx)
8554 && compact_register_operand (op0, VOIDmode)
8555 && (GET_CODE (op) == EQ
8556 || GET_CODE (op) == NE))
8557 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
8558 else
8559 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
8560
8561 brcc_insn
8562 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
f7df4a84 8563 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
526b7aee
SV
8564 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
8565 brcc_insn
8566 = gen_rtx_PARALLEL
8567 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
8568 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
8569
8570 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
8571 note = find_reg_note (insn, REG_BR_PROB, 0);
8572 if (note)
8573 {
8574 XEXP (note, 1) = REG_NOTES (brcc_insn);
8575 REG_NOTES (brcc_insn) = note;
8576 }
8577 note = find_reg_note (link_insn, REG_DEAD, op0);
8578 if (note)
8579 {
8580 remove_note (link_insn, note);
8581 XEXP (note, 1) = REG_NOTES (brcc_insn);
8582 REG_NOTES (brcc_insn) = note;
8583 }
8584 note = find_reg_note (link_insn, REG_DEAD, op1);
8585 if (note)
8586 {
8587 XEXP (note, 1) = REG_NOTES (brcc_insn);
8588 REG_NOTES (brcc_insn) = note;
8589 }
8590
8591 changed = 1;
8592
8593 /* Delete the bcc insn. */
8594 set_insn_deleted (insn);
8595
8596 /* Delete the cmp insn. */
8597 set_insn_deleted (link_insn);
8598
8599 }
8600 }
8601 }
8602 /* Clear out insn_addresses. */
8603 INSN_ADDRESSES_FREE ();
8604
8605 } while (changed);
8606
8607 if (INSN_ADDRESSES_SET_P())
40fecdd6 8608 fatal_error (input_location, "insn addresses not freed");
526b7aee
SV
8609
8610 arc_reorg_in_progress = 0;
8611}
8612
8613 /* Check if the operands are valid for BRcc.d generation
8614 Valid Brcc.d patterns are
8615 Brcc.d b, c, s9
8616 Brcc.d b, u6, s9
8617
67914693 8618 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
526b7aee
SV
8619 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8620 does not have a delay slot
8621
8622 Assumed precondition: Second operand is either a register or a u6 value. */
8623
8624bool
8625valid_brcc_with_delay_p (rtx *operands)
8626{
8627 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
8628 return false;
8629 return brcc_nolimm_operator (operands[0], VOIDmode);
8630}
8631
526b7aee
SV
8632/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8633 access DECL using %gp_rel(...)($gp). */
8634
8635static bool
8636arc_in_small_data_p (const_tree decl)
8637{
8638 HOST_WIDE_INT size;
8180c03f 8639 tree attr;
526b7aee 8640
9f532472
CZ
8641 /* Only variables are going into small data area. */
8642 if (TREE_CODE (decl) != VAR_DECL)
526b7aee
SV
8643 return false;
8644
526b7aee
SV
8645 if (TARGET_NO_SDATA_SET)
8646 return false;
8647
526b7aee
SV
8648 /* Disable sdata references to weak variables. */
8649 if (DECL_WEAK (decl))
8650 return false;
8651
9f532472
CZ
8652 /* Don't put constants into the small data section: we want them to
8653 be in ROM rather than RAM. */
8654 if (TREE_READONLY (decl))
8655 return false;
8656
8657 /* To ensure -mvolatile-cache works ld.di does not have a
8658 gp-relative variant. */
8659 if (!TARGET_VOLATILE_CACHE_SET
8660 && TREE_THIS_VOLATILE (decl))
8661 return false;
526b7aee 8662
8180c03f
CZ
8663 /* Likewise for uncached data. */
8664 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
8665 if (lookup_attribute ("uncached", attr))
8666 return false;
8667
b6fb257b
CZ
8668 /* and for aux regs. */
8669 attr = DECL_ATTRIBUTES (decl);
8670 if (lookup_attribute ("aux", attr))
8671 return false;
8672
9f532472
CZ
8673 if (DECL_SECTION_NAME (decl) != 0)
8674 {
8675 const char *name = DECL_SECTION_NAME (decl);
8676 if (strcmp (name, ".sdata") == 0
8677 || strcmp (name, ".sbss") == 0)
8678 return true;
8679 }
8680 /* If it's not public, there's no need to put it in the small data
8681 section. */
8682 else if (TREE_PUBLIC (decl))
8683 {
8684 size = int_size_in_bytes (TREE_TYPE (decl));
8685 return (size > 0 && size <= g_switch_value);
8686 }
8687 return false;
526b7aee
SV
8688}
8689
526b7aee
SV
8690/* Return true if OP is an acceptable memory operand for ARCompact
8691 16-bit gp-relative load instructions.
e0be3321 8692*/
526b7aee
SV
8693/* volatile cache option still to be handled. */
8694
8695bool
b6fb7933 8696compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
526b7aee
SV
8697{
8698 rtx addr;
8699 int size;
b6fb7933
CZ
8700 int align = 0;
8701 int mask = 0;
526b7aee
SV
8702
8703 /* Eliminate non-memory operations. */
8704 if (GET_CODE (op) != MEM)
8705 return false;
8706
8707 if (mode == VOIDmode)
8708 mode = GET_MODE (op);
8709
8710 size = GET_MODE_SIZE (mode);
8711
8712 /* dword operations really put out 2 instructions, so eliminate them. */
8713 if (size > UNITS_PER_WORD)
8714 return false;
8715
8716 /* Decode the address now. */
8717 addr = XEXP (op, 0);
8718
e0be3321 8719 if (!legitimate_small_data_address_p (addr))
b6fb7933
CZ
8720 return false;
8721
8722 if (!short_p || size == 1)
8723 return true;
8724
8725 /* Now check for the alignment, the short loads using gp require the
8726 addresses to be aligned. */
e0be3321 8727 align = get_symbol_alignment (addr);
b6fb7933
CZ
8728 switch (mode)
8729 {
8730 case E_HImode:
8731 mask = 1;
8732 break;
8733 default:
8734 mask = 3;
8735 break;
8736 }
8737
8738 if (align && ((align & mask) == 0))
8739 return true;
8740 return false;
526b7aee
SV
8741}
8742
b6fb257b
CZ
8743/* Return TRUE if PAT is accessing an aux-reg. */
8744
8745static bool
8746arc_is_aux_reg_p (rtx pat)
8747{
8748 tree attrs = NULL_TREE;
8749 tree addr;
8750
8751 if (!MEM_P (pat))
8752 return false;
8753
8754 /* Get the memory attributes. */
8755 addr = MEM_EXPR (pat);
8756 if (!addr)
8757 return false;
8758
8759 /* Get the attributes. */
8760 if (TREE_CODE (addr) == VAR_DECL)
8761 attrs = DECL_ATTRIBUTES (addr);
8762 else if (TREE_CODE (addr) == MEM_REF)
8763 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8764 else
8765 return false;
8766
8767 if (lookup_attribute ("aux", attrs))
8768 return true;
8769 return false;
8770}
8771
526b7aee
SV
8772/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8773
8774void
8775arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8776 unsigned HOST_WIDE_INT size,
8777 unsigned HOST_WIDE_INT align,
8778 unsigned HOST_WIDE_INT globalize_p)
8779{
b6fb257b
CZ
8780 int in_small_data = arc_in_small_data_p (decl);
8781 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8782
8783 /* Don't output aux-reg symbols. */
8784 if (mem != NULL_RTX && MEM_P (mem)
8785 && SYMBOL_REF_P (XEXP (mem, 0))
8786 && arc_is_aux_reg_p (mem))
8787 return;
526b7aee
SV
8788
8789 if (in_small_data)
8790 switch_to_section (get_named_section (NULL, ".sbss", 0));
8791 /* named_section (0,".sbss",0); */
8792 else
8793 switch_to_section (bss_section);
8794
8795 if (globalize_p)
8796 (*targetm.asm_out.globalize_label) (stream, name);
8797
8798 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8799 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8800 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8801 ASM_OUTPUT_LABEL (stream, name);
8802
8803 if (size != 0)
8804 ASM_OUTPUT_SKIP (stream, size);
8805}
8806
526b7aee
SV
8807static bool
8808arc_preserve_reload_p (rtx in)
8809{
8810 return (GET_CODE (in) == PLUS
8811 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8812 && CONST_INT_P (XEXP (in, 1))
8813 && !((INTVAL (XEXP (in, 1)) & 511)));
8814}
8815
b9bc3b12
CZ
8816/* Implement TARGET_REGISTER_MOVE_COST. */
8817
8818static int
ef4bddc2 8819arc_register_move_cost (machine_mode,
b9bc3b12 8820 reg_class_t from_class, reg_class_t to_class)
526b7aee 8821{
526b7aee 8822 /* Force an attempt to 'mov Dy,Dx' to spill. */
c4014855 8823 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
526b7aee
SV
8824 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8825 return 100;
8826
8827 return 2;
8828}
8829
8830/* Emit code for an addsi3 instruction with OPERANDS.
8831 COND_P indicates if this will use conditional execution.
8832 Return the length of the instruction.
8833 If OUTPUT_P is false, don't actually output the instruction, just return
8834 its length. */
8835int
8836arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8837{
3bbe0b82 8838 char format[35];
526b7aee
SV
8839
8840 int match = operands_match_p (operands[0], operands[1]);
8841 int match2 = operands_match_p (operands[0], operands[2]);
8842 int intval = (REG_P (operands[2]) ? 1
8843 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8844 int neg_intval = -intval;
8845 int short_0 = satisfies_constraint_Rcq (operands[0]);
8846 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
8847 int ret = 0;
8848
a0caeef6
CZ
8849#define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8850 && REGNO (OP) != 30) \
8851 || !TARGET_V2))
8852
526b7aee
SV
8853#define ADDSI_OUTPUT1(FORMAT) do {\
8854 if (output_p) \
8855 output_asm_insn (FORMAT, operands);\
8856 return ret; \
8857} while (0)
8858#define ADDSI_OUTPUT(LIST) do {\
8859 if (output_p) \
8860 sprintf LIST;\
8861 ADDSI_OUTPUT1 (format);\
8862 return ret; \
8863} while (0)
8864
8865 /* First try to emit a 16 bit insn. */
8866 ret = 2;
8867 if (!cond_p
8868 /* If we are actually about to output this insn, don't try a 16 bit
8869 variant if we already decided that we don't want that
8870 (I.e. we upsized this insn to align some following insn.)
8871 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8872 but add1 r0,sp,35 doesn't. */
8873 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8874 {
a0caeef6
CZ
8875 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8876 patterns. */
526b7aee 8877 if (short_p
a0caeef6
CZ
8878 && ((REG_H_P (operands[2])
8879 && (match || satisfies_constraint_Rcq (operands[2])))
8880 || (CONST_INT_P (operands[2])
8881 && ((unsigned) intval <= (match ? 127 : 7)))))
8882 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8883
8884 /* Generate add_s b,b,h patterns. */
8885 if (short_0 && match2 && REG_H_P (operands[1]))
8886 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8887
8888 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
526b7aee
SV
8889 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8890 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
a0caeef6 8891 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
526b7aee
SV
8892
8893 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8894 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8895 && match && !(neg_intval & ~124)))
a0caeef6 8896 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
fa9c1b3c 8897
a0caeef6
CZ
8898 /* Generate add_s h,h,s3 patterns. */
8899 if (REG_H_P (operands[0]) && match && TARGET_V2
8900 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8901 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
fa9c1b3c 8902
a0caeef6
CZ
8903 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8904 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8905 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
fa9c1b3c
CZ
8906 && satisfies_constraint_Rcq (operands[1])
8907 && satisfies_constraint_L (operands[2]))
a0caeef6 8908 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
526b7aee
SV
8909 }
8910
8911 /* Now try to emit a 32 bit insn without long immediate. */
8912 ret = 4;
8913 if (!match && match2 && REG_P (operands[1]))
8914 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8915 if (match || !cond_p)
8916 {
8917 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8918 int range_factor = neg_intval & intval;
8919 int shift;
8920
c419f71c 8921 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
526b7aee
SV
8922 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8923
8924 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8925 same size, do, so - the insn latency is lower. */
8926 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8927 0x800 is not. */
8928 if ((intval >= 0 && intval <= limit)
8929 || (intval == -0x800 && limit == 0x7ff))
8930 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8931 else if ((intval < 0 && neg_intval <= limit)
8932 || (intval == 0x800 && limit == 0x7ff))
8933 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8934 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
8935 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
8936 gcc_assert ((((1 << shift) - 1) & intval) == 0);
8937 if (((intval < 0 && intval != -0x4000)
8938 /* sub[123] is slower than add_s / sub, only use it if it
8939 avoids a long immediate. */
8940 && neg_intval <= limit << shift)
8941 || (intval == 0x4000 && limit == 0x7ff))
8942 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
8943 shift, neg_intval >> shift));
8944 else if ((intval >= 0 && intval <= limit << shift)
8945 || (intval == -0x4000 && limit == 0x7ff))
8946 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
8947 }
8948 /* Try to emit a 16 bit opcode with long immediate. */
8949 ret = 6;
8950 if (short_p && match)
6b55f8c9 8951 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
526b7aee
SV
8952
8953 /* We have to use a 32 bit opcode, and with a long immediate. */
8954 ret = 8;
6b55f8c9 8955 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
526b7aee
SV
8956}
8957
8958/* Emit code for an commutative_cond_exec instruction with OPERANDS.
8959 Return the length of the instruction.
8960 If OUTPUT_P is false, don't actually output the instruction, just return
8961 its length. */
8962int
8963arc_output_commutative_cond_exec (rtx *operands, bool output_p)
8964{
8965 enum rtx_code commutative_op = GET_CODE (operands[3]);
8966 const char *pat = NULL;
8967
8968 /* Canonical rtl should not have a constant in the first operand position. */
8969 gcc_assert (!CONSTANT_P (operands[1]));
8970
8971 switch (commutative_op)
8972 {
8973 case AND:
8974 if (satisfies_constraint_C1p (operands[2]))
8975 pat = "bmsk%? %0,%1,%Z2";
fc1c2d04
CZ
8976 else if (satisfies_constraint_C2p (operands[2]))
8977 {
8978 operands[2] = GEN_INT ((~INTVAL (operands[2])));
8979 pat = "bmskn%? %0,%1,%Z2";
8980 }
526b7aee
SV
8981 else if (satisfies_constraint_Ccp (operands[2]))
8982 pat = "bclr%? %0,%1,%M2";
8983 else if (satisfies_constraint_CnL (operands[2]))
8984 pat = "bic%? %0,%1,%n2-1";
8985 break;
8986 case IOR:
8987 if (satisfies_constraint_C0p (operands[2]))
8988 pat = "bset%? %0,%1,%z2";
8989 break;
8990 case XOR:
8991 if (satisfies_constraint_C0p (operands[2]))
8992 pat = "bxor%? %0,%1,%z2";
8993 break;
8994 case PLUS:
8995 return arc_output_addsi (operands, true, output_p);
8996 default: break;
8997 }
8998 if (output_p)
8999 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
9000 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
9001 return 4;
9002 return 8;
9003}
9004
76715c32 9005/* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
526b7aee
SV
9006 Emit code and return an potentially modified address such that offsets
9007 up to SIZE are can be added to yield a legitimate address.
9008 if REUSE is set, ADDR is a register that may be modified. */
9009
9010static rtx
9011force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
9012{
9013 rtx base = addr;
9014 rtx offs = const0_rtx;
9015
9016 if (GET_CODE (base) == PLUS)
9017 {
9018 offs = XEXP (base, 1);
9019 base = XEXP (base, 0);
9020 }
9021 if (!REG_P (base)
9022 || (REGNO (base) != STACK_POINTER_REGNUM
4173ddaf 9023 && REGNO_PTR_FRAME_P (REGNO (base)))
526b7aee
SV
9024 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
9025 || !SMALL_INT (INTVAL (offs) + size))
9026 {
9027 if (reuse)
9028 emit_insn (gen_add2_insn (addr, offs));
9029 else
9030 addr = copy_to_mode_reg (Pmode, addr);
9031 }
9032 return addr;
9033}
9034
d34a0fdc
CZ
9035/* Like move_by_pieces, but take account of load latency, and actual
9036 offset ranges. Return true on success. */
526b7aee
SV
9037
9038bool
76715c32 9039arc_expand_cpymem (rtx *operands)
526b7aee
SV
9040{
9041 rtx dst = operands[0];
9042 rtx src = operands[1];
9043 rtx dst_addr, src_addr;
9044 HOST_WIDE_INT size;
9045 int align = INTVAL (operands[3]);
9046 unsigned n_pieces;
9047 int piece = align;
9048 rtx store[2];
9049 rtx tmpx[2];
9050 int i;
9051
9052 if (!CONST_INT_P (operands[2]))
9053 return false;
9054 size = INTVAL (operands[2]);
9055 /* move_by_pieces_ninsns is static, so we can't use it. */
9056 if (align >= 4)
d34a0fdc
CZ
9057 {
9058 if (TARGET_LL64)
9059 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
9060 else
9061 n_pieces = (size + 2) / 4U + (size & 1);
9062 }
526b7aee
SV
9063 else if (align == 2)
9064 n_pieces = (size + 1) / 2U;
9065 else
9066 n_pieces = size;
9067 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
9068 return false;
d34a0fdc
CZ
9069 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
9070 possible. */
9071 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
9072 piece = 8;
9073 else if (piece > 4)
526b7aee
SV
9074 piece = 4;
9075 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
9076 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
9077 store[0] = store[1] = NULL_RTX;
9078 tmpx[0] = tmpx[1] = NULL_RTX;
9079 for (i = 0; size > 0; i ^= 1, size -= piece)
9080 {
9081 rtx tmp;
ef4bddc2 9082 machine_mode mode;
526b7aee 9083
d34a0fdc
CZ
9084 while (piece > size)
9085 piece >>= 1;
f67f4dff 9086 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
526b7aee
SV
9087 /* If we don't re-use temporaries, the scheduler gets carried away,
9088 and the register pressure gets unnecessarily high. */
9089 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
9090 tmp = tmpx[i];
9091 else
9092 tmpx[i] = tmp = gen_reg_rtx (mode);
9093 dst_addr = force_offsettable (dst_addr, piece, 1);
9094 src_addr = force_offsettable (src_addr, piece, 1);
9095 if (store[i])
9096 emit_insn (store[i]);
9097 emit_move_insn (tmp, change_address (src, mode, src_addr));
9098 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
9099 dst_addr = plus_constant (Pmode, dst_addr, piece);
9100 src_addr = plus_constant (Pmode, src_addr, piece);
9101 }
9102 if (store[i])
9103 emit_insn (store[i]);
9104 if (store[i^1])
9105 emit_insn (store[i^1]);
9106 return true;
9107}
9108
b6fb257b
CZ
9109static bool
9110arc_get_aux_arg (rtx pat, int *auxr)
9111{
9112 tree attr, addr = MEM_EXPR (pat);
9113 if (TREE_CODE (addr) != VAR_DECL)
9114 return false;
9115
9116 attr = DECL_ATTRIBUTES (addr);
9117 if (lookup_attribute ("aux", attr))
9118 {
9119 tree arg = TREE_VALUE (attr);
9120 if (arg)
9121 {
9122 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
9123 return true;
9124 }
9125 }
9126
9127 return false;
9128}
9129
526b7aee
SV
9130/* Prepare operands for move in MODE. Return true iff the move has
9131 been emitted. */
9132
9133bool
ef4bddc2 9134prepare_move_operands (rtx *operands, machine_mode mode)
526b7aee 9135{
b6fb257b
CZ
9136 /* First handle aux attribute. */
9137 if (mode == SImode
9138 && (MEM_P (operands[0]) || MEM_P (operands[1])))
9139 {
9140 rtx tmp;
9141 int auxr = 0;
9142 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
9143 {
9144 /* Save operation. */
9145 if (arc_get_aux_arg (operands[0], &auxr))
9146 {
9147 tmp = gen_reg_rtx (SImode);
9148 emit_move_insn (tmp, GEN_INT (auxr));
9149 }
9150 else
9151 {
9152 tmp = XEXP (operands[0], 0);
9153 }
9154
9155 operands[1] = force_reg (SImode, operands[1]);
9156 emit_insn (gen_rtx_UNSPEC_VOLATILE
9157 (VOIDmode, gen_rtvec (2, operands[1], tmp),
9158 VUNSPEC_ARC_SR));
9159 return true;
9160 }
9161 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
9162 {
9163 if (arc_get_aux_arg (operands[1], &auxr))
9164 {
9165 tmp = gen_reg_rtx (SImode);
9166 emit_move_insn (tmp, GEN_INT (auxr));
9167 }
9168 else
9169 {
9170 tmp = XEXP (operands[1], 0);
9171 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
9172 }
9173 /* Load operation. */
9174 gcc_assert (REG_P (operands[0]));
9175 emit_insn (gen_rtx_SET (operands[0],
9176 gen_rtx_UNSPEC_VOLATILE
9177 (SImode, gen_rtvec (1, tmp),
9178 VUNSPEC_ARC_LR)));
9179 return true;
9180 }
9181 }
9182
673f01b8 9183 if (GET_CODE (operands[1]) == SYMBOL_REF)
526b7aee 9184 {
673f01b8 9185 enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
4be6c9b9 9186 if (MEM_P (operands[0]))
673f01b8
CZ
9187 operands[1] = force_reg (mode, operands[1]);
9188 else if (model)
9189 operands[1] = arc_legitimize_tls_address (operands[1], model);
28633bbd
CZ
9190 }
9191
673f01b8
CZ
9192 operands[1] = arc_legitimize_pic_address (operands[1]);
9193
9194 /* Store instructions are limited, they only accept as address an
9195 immediate, a register or a register plus a small immediate. */
526b7aee 9196 if (MEM_P (operands[0])
673f01b8 9197 && !move_dest_operand (operands[0], mode))
526b7aee 9198 {
673f01b8
CZ
9199 rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9200 rtx tmp1 = change_address (operands[0], mode, tmp0);
9201 MEM_COPY_ATTRIBUTES (tmp1, operands[0]);
9202 operands[0] = tmp1;
526b7aee
SV
9203 }
9204
673f01b8
CZ
9205 /* Check if it is constant but it is not legitimized. */
9206 if (CONSTANT_P (operands[1])
9207 && !arc_legitimate_constant_p (mode, operands[1]))
9208 operands[1] = force_reg (mode, XEXP (operands[1], 0));
9209 else if (MEM_P (operands[0])
9210 && ((CONSTANT_P (operands[1])
9211 && !satisfies_constraint_Cm3 (operands[1]))
9212 || MEM_P (operands[1])))
9213 operands[1] = force_reg (mode, operands[1]);
9214
526b7aee
SV
9215 return false;
9216}
9217
526b7aee
SV
9218/* Output a library call to a function called FNAME that has been arranged
9219 to be local to any dso. */
9220
9221const char *
9222arc_output_libcall (const char *fname)
9223{
9224 unsigned len = strlen (fname);
9225 static char buf[64];
9226
9227 gcc_assert (len < sizeof buf - 35);
9228 if (TARGET_LONG_CALLS_SET
9229 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
9230 {
9231 if (flag_pic)
f5e336b1 9232 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
526b7aee
SV
9233 else
9234 sprintf (buf, "jl%%! @%s", fname);
9235 }
9236 else
9237 sprintf (buf, "bl%%!%%* @%s", fname);
9238 return buf;
9239}
9240
9241/* Return the SImode highpart of the DImode value IN. */
9242
9243rtx
9244disi_highpart (rtx in)
9245{
9246 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
9247}
9248
526b7aee
SV
9249/* Return length adjustment for INSN.
9250 For ARC600:
9251 A write to a core reg greater or equal to 32 must not be immediately
9252 followed by a use. Anticipate the length requirement to insert a nop
9253 between PRED and SUCC to prevent a hazard. */
9254
9255static int
647d790d 9256arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee
SV
9257{
9258 if (!TARGET_ARC600)
9259 return 0;
526b7aee 9260 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
647d790d 9261 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
526b7aee 9262 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
647d790d 9263 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
526b7aee
SV
9264 if (recog_memoized (pred) == CODE_FOR_mulsi_600
9265 || recog_memoized (pred) == CODE_FOR_umul_600
9266 || recog_memoized (pred) == CODE_FOR_mac_600
9267 || recog_memoized (pred) == CODE_FOR_mul64_600
9268 || recog_memoized (pred) == CODE_FOR_mac64_600
9269 || recog_memoized (pred) == CODE_FOR_umul64_600
9270 || recog_memoized (pred) == CODE_FOR_umac64_600)
9271 return 0;
36cc6254
RS
9272 subrtx_iterator::array_type array;
9273 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
9274 {
9275 const_rtx x = *iter;
9276 switch (GET_CODE (x))
9277 {
9278 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9279 break;
9280 default:
9281 /* This is also fine for PRE/POST_MODIFY, because they
9282 contain a SET. */
9283 continue;
9284 }
9285 rtx dest = XEXP (x, 0);
9286 /* Check if this sets a an extension register. N.B. we use 61 for the
9287 condition codes, which is definitely not an extension register. */
9288 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
9289 /* Check if the same register is used by the PAT. */
9290 && (refers_to_regno_p
9291 (REGNO (dest),
9292 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
9293 PATTERN (succ), 0)))
9294 return 4;
9295 }
9296 return 0;
526b7aee
SV
9297}
9298
f50bb868
CZ
9299/* Given a rtx, check if it is an assembly instruction or not. */
9300
9301static int
9302arc_asm_insn_p (rtx x)
9303{
9304 int i, j;
9305
9306 if (x == 0)
9307 return 0;
9308
9309 switch (GET_CODE (x))
9310 {
9311 case ASM_OPERANDS:
9312 case ASM_INPUT:
9313 return 1;
9314
9315 case SET:
9316 return arc_asm_insn_p (SET_SRC (x));
9317
9318 case PARALLEL:
9319 j = 0;
9320 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
9321 j += arc_asm_insn_p (XVECEXP (x, 0, i));
9322 if ( j > 0)
9323 return 1;
9324 break;
9325
9326 default:
9327 break;
9328 }
9329
9330 return 0;
9331}
9332
526b7aee
SV
9333/* For ARC600:
9334 A write to a core reg greater or equal to 32 must not be immediately
9335 followed by a use. Anticipate the length requirement to insert a nop
9336 between PRED and SUCC to prevent a hazard. */
9337
9338int
647d790d 9339arc_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee 9340{
526b7aee
SV
9341 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
9342 return 0;
f50bb868 9343
f50bb868
CZ
9344 if (TARGET_ARC600)
9345 return arc600_corereg_hazard (pred, succ);
9346
9347 return 0;
526b7aee
SV
9348}
9349
9350/* Return length adjustment for INSN. */
9351
9352int
647d790d 9353arc_adjust_insn_length (rtx_insn *insn, int len, bool)
526b7aee
SV
9354{
9355 if (!INSN_P (insn))
9356 return len;
9357 /* We already handle sequences by ignoring the delay sequence flag. */
9358 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
9359 return len;
9360
526b7aee
SV
9361 /* Check for return with but one preceding insn since function
9362 start / call. */
9363 if (TARGET_PAD_RETURN
9364 && JUMP_P (insn)
9365 && GET_CODE (PATTERN (insn)) != ADDR_VEC
9366 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
9367 && get_attr_type (insn) == TYPE_RETURN)
9368 {
84034c69 9369 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
9370
9371 if (!prev || !(prev = prev_active_insn (prev))
9372 || ((NONJUMP_INSN_P (prev)
9373 && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
9374 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9375 NON_SIBCALL)
526b7aee
SV
9376 : CALL_ATTR (prev, NON_SIBCALL)))
9377 return len + 4;
9378 }
9379 if (TARGET_ARC600)
9380 {
b3458f61 9381 rtx_insn *succ = next_real_insn (insn);
526b7aee
SV
9382
9383 /* One the ARC600, a write to an extension register must be separated
9384 from a read. */
9385 if (succ && INSN_P (succ))
9386 len += arc600_corereg_hazard (insn, succ);
9387 }
9388
9389 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9390 can go awry. */
9391 extract_constrain_insn_cached (insn);
9392
9393 return len;
9394}
9395
526b7aee
SV
9396/* Return a copy of COND from *STATEP, inverted if that is indicated by the
9397 CC field of *STATEP. */
9398
9399static rtx
9400arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
9401{
9402 rtx cond = statep->cond;
9403 int raw_cc = get_arc_condition_code (cond);
9404 if (reverse)
9405 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
9406
9407 if (statep->cc == raw_cc)
9408 return copy_rtx (cond);
9409
9410 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
9411
ef4bddc2 9412 machine_mode ccm = GET_MODE (XEXP (cond, 0));
526b7aee
SV
9413 enum rtx_code code = reverse_condition (GET_CODE (cond));
9414 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9415 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9416
9417 return gen_rtx_fmt_ee (code, GET_MODE (cond),
9418 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
9419}
9420
bae56bbb
JR
9421/* Return version of PAT conditionalized with COND, which is part of INSN.
9422 ANNULLED indicates if INSN is an annulled delay-slot insn.
9423 Register further changes if necessary. */
9424static rtx
9425conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
9426{
9427 /* For commutative operators, we generally prefer to have
9428 the first source match the destination. */
9429 if (GET_CODE (pat) == SET)
9430 {
9431 rtx src = SET_SRC (pat);
9432
9433 if (COMMUTATIVE_P (src))
9434 {
9435 rtx src0 = XEXP (src, 0);
9436 rtx src1 = XEXP (src, 1);
9437 rtx dst = SET_DEST (pat);
9438
9439 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
9440 /* Leave add_n alone - the canonical form is to
9441 have the complex summand first. */
9442 && REG_P (src0))
f7df4a84 9443 pat = gen_rtx_SET (dst,
bae56bbb
JR
9444 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
9445 src1, src0));
9446 }
9447 }
9448
9449 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
9450 what to do with COND_EXEC. */
9451 if (RTX_FRAME_RELATED_P (insn))
9452 {
9453 /* If this is the delay slot insn of an anulled branch,
9454 dwarf2out.c:scan_trace understands the anulling semantics
9455 without the COND_EXEC. */
9456 gcc_assert (annulled);
9457 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
9458 REG_NOTES (insn));
9459 validate_change (insn, &REG_NOTES (insn), note, 1);
9460 }
9461 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9462 return pat;
9463}
9464
526b7aee
SV
9465/* Use the ccfsm machinery to do if conversion. */
9466
9467static unsigned
9468arc_ifcvt (void)
9469{
9470 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
526b7aee
SV
9471
9472 memset (statep, 0, sizeof *statep);
b3458f61 9473 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
526b7aee
SV
9474 {
9475 arc_ccfsm_advance (insn, statep);
9476
9477 switch (statep->state)
9478 {
9479 case 0:
526b7aee
SV
9480 break;
9481 case 1: case 2:
9482 {
9483 /* Deleted branch. */
526b7aee 9484 arc_ccfsm_post_advance (insn, statep);
53ea364f 9485 gcc_assert (!IN_RANGE (statep->state, 1, 2));
b3458f61 9486 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
782bdf21 9487 if (GET_CODE (PATTERN (seq)) == SEQUENCE)
526b7aee
SV
9488 {
9489 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
9490 rtx pat = PATTERN (slot);
9491 if (INSN_ANNULLED_BRANCH_P (insn))
9492 {
9493 rtx cond
9494 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
9495 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9496 }
9497 if (!validate_change (seq, &PATTERN (seq), pat, 0))
9498 gcc_unreachable ();
9499 PUT_CODE (slot, NOTE);
9500 NOTE_KIND (slot) = NOTE_INSN_DELETED;
526b7aee
SV
9501 }
9502 else
9503 {
782bdf21 9504 set_insn_deleted (insn);
526b7aee
SV
9505 }
9506 continue;
9507 }
9508 case 3:
9509 if (LABEL_P (insn)
9510 && statep->target_label == CODE_LABEL_NUMBER (insn))
9511 {
9512 arc_ccfsm_post_advance (insn, statep);
782bdf21
CZ
9513 if (--LABEL_NUSES (insn) == 0)
9514 delete_insn (insn);
526b7aee
SV
9515 continue;
9516 }
9517 /* Fall through. */
9518 case 4: case 5:
9519 if (!NONDEBUG_INSN_P (insn))
9520 break;
9521
9522 /* Conditionalized insn. */
9523
b3458f61
DM
9524 rtx_insn *prev, *pprev;
9525 rtx *patp, pat, cond;
bae56bbb 9526 bool annulled; annulled = false;
526b7aee
SV
9527
9528 /* If this is a delay slot insn in a non-annulled branch,
9529 don't conditionalize it. N.B., this should be fine for
9530 conditional return too. However, don't do this for
9531 unconditional branches, as these would be encountered when
9532 processing an 'else' part. */
9533 prev = PREV_INSN (insn);
9534 pprev = PREV_INSN (prev);
9535 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
bae56bbb
JR
9536 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
9537 {
9538 if (!INSN_ANNULLED_BRANCH_P (prev))
9539 break;
9540 annulled = true;
9541 }
526b7aee
SV
9542
9543 patp = &PATTERN (insn);
9544 pat = *patp;
9545 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
9546 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
9547 {
9548 /* ??? don't conditionalize if all side effects are dead
9549 in the not-execute case. */
9bf218f9 9550
bae56bbb 9551 pat = conditionalize_nonjump (pat, cond, insn, annulled);
526b7aee
SV
9552 }
9553 else if (simplejump_p (insn))
9554 {
9555 patp = &SET_SRC (pat);
9556 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
9557 }
9558 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
9559 {
9560 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
f7df4a84 9561 pat = gen_rtx_SET (pc_rtx, pat);
526b7aee
SV
9562 }
9563 else
9564 gcc_unreachable ();
9565 validate_change (insn, patp, pat, 1);
9566 if (!apply_change_group ())
9567 gcc_unreachable ();
9568 if (JUMP_P (insn))
9569 {
b3458f61 9570 rtx_insn *next = next_nonnote_insn (insn);
526b7aee
SV
9571 if (GET_CODE (next) == BARRIER)
9572 delete_insn (next);
9573 if (statep->state == 3)
9574 continue;
9575 }
9576 break;
9577 default:
9578 gcc_unreachable ();
9579 }
9580 arc_ccfsm_post_advance (insn, statep);
9581 }
9582 return 0;
9583}
9584
0bc69b81
JR
9585/* Find annulled delay insns and convert them to use the appropriate predicate.
9586 This allows branch shortening to size up these insns properly. */
9587
9588static unsigned
9589arc_predicate_delay_insns (void)
9590{
b3458f61 9591 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
0bc69b81
JR
9592 {
9593 rtx pat, jump, dlay, src, cond, *patp;
9594 int reverse;
9595
9596 if (!NONJUMP_INSN_P (insn)
9597 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9598 continue;
9599 jump = XVECEXP (pat, 0, 0);
9600 dlay = XVECEXP (pat, 0, 1);
9601 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9602 continue;
9603 /* If the branch insn does the annulling, leave the delay insn alone. */
9604 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9605 continue;
9606 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9607 on the other path. */
9608 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9609 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9610 src = SET_SRC (PATTERN (jump));
9611 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9612 cond = XEXP (src, 0);
9613 if (XEXP (src, 2) == pc_rtx)
9614 reverse = 0;
9615 else if (XEXP (src, 1) == pc_rtx)
9616 reverse = 1;
9617 else
9618 gcc_unreachable ();
9af539fe 9619 if (reverse != !INSN_FROM_TARGET_P (dlay))
0bc69b81 9620 {
ef4bddc2 9621 machine_mode ccm = GET_MODE (XEXP (cond, 0));
0bc69b81
JR
9622 enum rtx_code code = reverse_condition (GET_CODE (cond));
9623 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9624 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9625
9626 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9627 copy_rtx (XEXP (cond, 0)),
9628 copy_rtx (XEXP (cond, 1)));
9629 }
9630 else
9631 cond = copy_rtx (cond);
9632 patp = &PATTERN (dlay);
9633 pat = *patp;
eeac7d15 9634 pat = conditionalize_nonjump (pat, cond, dlay, true);
0bc69b81
JR
9635 validate_change (dlay, patp, pat, 1);
9636 if (!apply_change_group ())
9637 gcc_unreachable ();
9638 }
9639 return 0;
9640}
9641
526b7aee
SV
9642/* For ARC600: If a write to a core reg >=32 appears in a delay slot
9643 (other than of a forward brcc), it creates a hazard when there is a read
9644 of the same register at the branch target. We can't know what is at the
9645 branch target of calls, and for branches, we don't really know before the
9646 end of delay slot scheduling, either. Not only can individual instruction
9647 be hoisted out into a delay slot, a basic block can also be emptied this
9648 way, and branch and/or fall through targets be redirected. Hence we don't
9649 want such writes in a delay slot. */
526b7aee
SV
9650
9651/* Return nonzreo iff INSN writes to an extension core register. */
9652
9653int
9654arc_write_ext_corereg (rtx insn)
9655{
24dbe738
RS
9656 subrtx_iterator::array_type array;
9657 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9658 {
9659 const_rtx x = *iter;
9660 switch (GET_CODE (x))
9661 {
9662 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9663 break;
9664 default:
9665 /* This is also fine for PRE/POST_MODIFY, because they
9666 contain a SET. */
9667 continue;
9668 }
9669 const_rtx dest = XEXP (x, 0);
9670 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9671 return 1;
9672 }
9673 return 0;
526b7aee
SV
9674}
9675
9676/* This is like the hook, but returns NULL when it can't / won't generate
9677 a legitimate address. */
9678
9679static rtx
9680arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 9681 machine_mode mode)
526b7aee
SV
9682{
9683 rtx addr, inner;
9684
526b7aee
SV
9685 addr = x;
9686 if (GET_CODE (addr) == CONST)
9687 addr = XEXP (addr, 0);
673f01b8 9688
526b7aee
SV
9689 if (GET_CODE (addr) == PLUS
9690 && CONST_INT_P (XEXP (addr, 1))
9691 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9692 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9693 || (REG_P (XEXP (addr, 0))
9694 && (INTVAL (XEXP (addr, 1)) & 252))))
9695 {
9696 HOST_WIDE_INT offs, upper;
9697 int size = GET_MODE_SIZE (mode);
9698
9699 offs = INTVAL (XEXP (addr, 1));
9700 upper = (offs + 256 * size) & ~511 * size;
9701 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9702#if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9703 if (GET_CODE (x) == CONST)
9704 inner = gen_rtx_CONST (Pmode, inner);
9705#endif
9706 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9707 x = addr;
9708 }
9709 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9710 x = force_reg (Pmode, x);
ef4bddc2 9711 if (memory_address_p ((machine_mode) mode, x))
526b7aee
SV
9712 return x;
9713 return NULL_RTX;
9714}
9715
9716static rtx
ef4bddc2 9717arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
526b7aee
SV
9718{
9719 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9720
9721 if (new_x)
9722 return new_x;
9723 return orig_x;
9724}
9725
9726static rtx
20565692
CZ
9727arc_delegitimize_address_0 (rtx op)
9728{
9729 switch (GET_CODE (op))
9730 {
9731 case CONST:
9732 return arc_delegitimize_address_0 (XEXP (op, 0));
9733
9734 case UNSPEC:
9735 switch (XINT (op, 1))
9736 {
9737 case ARC_UNSPEC_GOT:
9738 case ARC_UNSPEC_GOTOFFPC:
9739 return XVECEXP (op, 0, 0);
9740 default:
9741 break;
9742 }
9743 break;
9744
9745 case PLUS:
9746 {
9747 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9748 rtx t2 = XEXP (op, 1);
9749
9750 if (t1 && t2)
9751 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9752 break;
9753 }
9754
9755 default:
9756 break;
9757 }
526b7aee
SV
9758 return NULL_RTX;
9759}
9760
9761static rtx
20565692 9762arc_delegitimize_address (rtx orig_x)
526b7aee 9763{
20565692
CZ
9764 rtx x = orig_x;
9765
9766 if (MEM_P (x))
526b7aee 9767 x = XEXP (x, 0);
20565692 9768
526b7aee 9769 x = arc_delegitimize_address_0 (x);
20565692
CZ
9770 if (!x)
9771 return orig_x;
9772
9773 if (MEM_P (orig_x))
9774 x = replace_equiv_address_nv (orig_x, x);
9775 return x;
526b7aee
SV
9776}
9777
9778/* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9779 differ from the hardware register number in order to allow the generic
9780 code to correctly split the concatenation of acc1 and acc2. */
9781
9782rtx
9783gen_acc1 (void)
9784{
9785 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9786}
9787
9788/* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9789 differ from the hardware register number in order to allow the generic
9790 code to correctly split the concatenation of acc1 and acc2. */
9791
9792rtx
9793gen_acc2 (void)
9794{
9795 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9796}
9797
9798/* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9799 differ from the hardware register number in order to allow the generic
9800 code to correctly split the concatenation of mhi and mlo. */
9801
9802rtx
9803gen_mlo (void)
9804{
9805 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
9806}
9807
9808/* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9809 differ from the hardware register number in order to allow the generic
9810 code to correctly split the concatenation of mhi and mlo. */
9811
9812rtx
9813gen_mhi (void)
9814{
9815 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
9816}
9817
9818/* FIXME: a parameter should be added, and code added to final.c,
9819 to reproduce this functionality in shorten_branches. */
9820#if 0
9821/* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9822 a previous instruction. */
9823int
9824arc_unalign_branch_p (rtx branch)
9825{
9826 rtx note;
9827
9828 if (!TARGET_UNALIGN_BRANCH)
9829 return 0;
9830 /* Do not do this if we have a filled delay slot. */
9831 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
4654c0cf 9832 && !NEXT_INSN (branch)->deleted ())
526b7aee
SV
9833 return 0;
9834 note = find_reg_note (branch, REG_BR_PROB, 0);
9835 return (!note
9836 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
9837 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
9838}
9839#endif
9840
9841/* When estimating sizes during arc_reorg, when optimizing for speed, there
9842 are three reasons why we need to consider branches to be length 6:
9843 - annull-false delay slot insns are implemented using conditional execution,
9844 thus preventing short insn formation where used.
9845 - for ARC600: annul-true delay slot insns are implemented where possible
9846 using conditional execution, preventing short insn formation where used.
9847 - for ARC700: likely or somewhat likely taken branches are made long and
9848 unaligned if possible to avoid branch penalty. */
9849
9850bool
9851arc_branch_size_unknown_p (void)
9852{
9853 return !optimize_size && arc_reorg_in_progress;
9854}
9855
526b7aee
SV
9856/* The usual; we set up our machine_function data. */
9857
9858static struct machine_function *
9859arc_init_machine_status (void)
9860{
9861 struct machine_function *machine;
766090c2 9862 machine = ggc_cleared_alloc<machine_function> ();
526b7aee 9863 machine->fn_type = ARC_FUNCTION_UNKNOWN;
526b7aee
SV
9864
9865 return machine;
9866}
9867
9868/* Implements INIT_EXPANDERS. We just set up to call the above
9869 function. */
9870
9871void
9872arc_init_expanders (void)
9873{
9874 init_machine_status = arc_init_machine_status;
9875}
9876
9877/* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9878 indicates a number of elements to ignore - that allows to have a
9879 sibcall pattern that starts with (return). LOAD_P is zero for store
9880 multiple (for prologues), and one for load multiples (for epilogues),
9881 and two for load multiples where no final clobber of blink is required.
9882 We also skip the first load / store element since this is supposed to
9883 be checked in the instruction pattern. */
9884
9885int
9886arc_check_millicode (rtx op, int offset, int load_p)
9887{
9888 int len = XVECLEN (op, 0) - offset;
9889 int i;
9890
9891 if (load_p == 2)
9892 {
9893 if (len < 2 || len > 13)
9894 return 0;
9895 load_p = 1;
9896 }
9897 else
9898 {
9899 rtx elt = XVECEXP (op, 0, --len);
9900
9901 if (GET_CODE (elt) != CLOBBER
9902 || !REG_P (XEXP (elt, 0))
9903 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9904 || len < 3 || len > 13)
9905 return 0;
9906 }
9907 for (i = 1; i < len; i++)
9908 {
9909 rtx elt = XVECEXP (op, 0, i + offset);
9910 rtx reg, mem, addr;
9911
9912 if (GET_CODE (elt) != SET)
9913 return 0;
9914 mem = XEXP (elt, load_p);
9915 reg = XEXP (elt, 1-load_p);
9916 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9917 return 0;
9918 addr = XEXP (mem, 0);
9919 if (GET_CODE (addr) != PLUS
9920 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9921 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9922 return 0;
9923 }
9924 return 1;
9925}
9926
9927/* Accessor functions for cfun->machine->unalign. */
9928
526b7aee
SV
9929void
9930arc_clear_unalign (void)
9931{
9932 if (cfun)
9933 cfun->machine->unalign = 0;
9934}
9935
9936void
9937arc_toggle_unalign (void)
9938{
9939 cfun->machine->unalign ^= 2;
9940}
9941
9942/* Operands 0..2 are the operands of a addsi which uses a 12 bit
9943 constant in operand 2, but which would require a LIMM because of
9944 operand mismatch.
9945 operands 3 and 4 are new SET_SRCs for operands 0. */
9946
9947void
9948split_addsi (rtx *operands)
9949{
9950 int val = INTVAL (operands[2]);
9951
9952 /* Try for two short insns first. Lengths being equal, we prefer
9953 expansions with shorter register lifetimes. */
9954 if (val > 127 && val <= 255
9955 && satisfies_constraint_Rcq (operands[0]))
9956 {
9957 operands[3] = operands[2];
9958 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9959 }
9960 else
9961 {
9962 operands[3] = operands[1];
9963 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
9964 }
9965}
9966
9967/* Operands 0..2 are the operands of a subsi which uses a 12 bit
9968 constant in operand 1, but which would require a LIMM because of
9969 operand mismatch.
9970 operands 3 and 4 are new SET_SRCs for operands 0. */
9971
9972void
9973split_subsi (rtx *operands)
9974{
9975 int val = INTVAL (operands[1]);
9976
9977 /* Try for two short insns first. Lengths being equal, we prefer
9978 expansions with shorter register lifetimes. */
9979 if (satisfies_constraint_Rcq (operands[0])
9980 && satisfies_constraint_Rcq (operands[2]))
9981 {
9982 if (val >= -31 && val <= 127)
9983 {
9984 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9985 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9986 return;
9987 }
9988 else if (val >= 0 && val < 255)
9989 {
9990 operands[3] = operands[1];
9991 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9992 return;
9993 }
9994 }
9995 /* If the destination is not an ARCompact16 register, we might
9996 still have a chance to make a short insn if the source is;
9997 we need to start with a reg-reg move for this. */
9998 operands[3] = operands[2];
9999 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
10000}
10001
10002/* Handle DOUBLE_REGS uses.
10003 Operand 0: destination register
10004 Operand 1: source register */
10005
d34a0fdc 10006static bool
526b7aee
SV
10007arc_process_double_reg_moves (rtx *operands)
10008{
526b7aee
SV
10009 enum usesDxState { none, srcDx, destDx, maxDx };
10010 enum usesDxState state = none;
73dac59b
CZ
10011 rtx dest = operands[0];
10012 rtx src = operands[1];
526b7aee
SV
10013
10014 if (refers_to_regno_p (40, 44, src, 0))
73dac59b
CZ
10015 {
10016 state = srcDx;
10017 gcc_assert (REG_P (dest));
10018 }
526b7aee
SV
10019 if (refers_to_regno_p (40, 44, dest, 0))
10020 {
10021 /* Via arc_register_move_cost, we should never see D,D moves. */
73dac59b 10022 gcc_assert (REG_P (src));
526b7aee
SV
10023 gcc_assert (state == none);
10024 state = destDx;
10025 }
10026
10027 if (state == none)
d34a0fdc 10028 return false;
526b7aee
SV
10029
10030 if (state == srcDx)
10031 {
10032 /* Without the LR insn, we need to split this into a
10033 sequence of insns which will use the DEXCLx and DADDHxy
10034 insns to be able to read the Dx register in question. */
10035 if (TARGET_DPFP_DISABLE_LRSR)
10036 {
10037 /* gen *movdf_insn_nolrsr */
f7df4a84 10038 rtx set = gen_rtx_SET (dest, src);
526b7aee
SV
10039 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
10040 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
10041 }
10042 else
10043 {
10044 /* When we have 'mov D, r' or 'mov D, D' then get the target
10045 register pair for use with LR insn. */
7d81a567
CZ
10046 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
10047 TARGET_BIG_ENDIAN ? 0 : 4);
10048 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
10049 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee
SV
10050
10051 /* Produce the two LR insns to get the high and low parts. */
f7df4a84 10052 emit_insn (gen_rtx_SET (destHigh,
c69899f0
CZ
10053 gen_rtx_UNSPEC_VOLATILE (Pmode,
10054 gen_rtvec (1, src),
10055 VUNSPEC_ARC_LR_HIGH)));
f7df4a84 10056 emit_insn (gen_rtx_SET (destLow,
c69899f0
CZ
10057 gen_rtx_UNSPEC_VOLATILE (Pmode,
10058 gen_rtvec (1, src),
10059 VUNSPEC_ARC_LR)));
526b7aee
SV
10060 }
10061 }
10062 else if (state == destDx)
10063 {
10064 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
10065 LR insn get the target register pair. */
7d81a567
CZ
10066 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
10067 TARGET_BIG_ENDIAN ? 0 : 4);
10068 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
10069 TARGET_BIG_ENDIAN ? 4 : 0);
526b7aee 10070
491483b0 10071 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
526b7aee
SV
10072 }
10073 else
10074 gcc_unreachable ();
10075
d34a0fdc 10076 return true;
526b7aee
SV
10077}
10078
10079/* operands 0..1 are the operands of a 64 bit move instruction.
10080 split it into two moves with operands 2/3 and 4/5. */
10081
d34a0fdc 10082void
526b7aee
SV
10083arc_split_move (rtx *operands)
10084{
ef4bddc2 10085 machine_mode mode = GET_MODE (operands[0]);
526b7aee
SV
10086 int i;
10087 int swap = 0;
10088 rtx xop[4];
526b7aee
SV
10089
10090 if (TARGET_DPFP)
10091 {
d34a0fdc
CZ
10092 if (arc_process_double_reg_moves (operands))
10093 return;
526b7aee
SV
10094 }
10095
d34a0fdc
CZ
10096 if (TARGET_LL64
10097 && ((memory_operand (operands[0], mode)
2295aa75
CZ
10098 && (even_register_operand (operands[1], mode)
10099 || satisfies_constraint_Cm3 (operands[1])))
d34a0fdc
CZ
10100 || (memory_operand (operands[1], mode)
10101 && even_register_operand (operands[0], mode))))
10102 {
10103 emit_move_insn (operands[0], operands[1]);
10104 return;
10105 }
10106
00c072ae
CZ
10107 if (TARGET_PLUS_QMACW
10108 && GET_CODE (operands[1]) == CONST_VECTOR)
10109 {
10110 HOST_WIDE_INT intval0, intval1;
10111 if (GET_MODE (operands[1]) == V2SImode)
10112 {
10113 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
10114 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
10115 }
10116 else
10117 {
10118 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
10119 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
10120 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
10121 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
10122 }
10123 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
10124 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
10125 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
10126 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
10127 emit_move_insn (xop[0], xop[2]);
10128 emit_move_insn (xop[3], xop[1]);
10129 return;
10130 }
10131
526b7aee
SV
10132 for (i = 0; i < 2; i++)
10133 {
10134 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
10135 {
10136 rtx addr = XEXP (operands[i], 0);
10137 rtx r, o;
10138 enum rtx_code code;
10139
10140 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
10141 switch (GET_CODE (addr))
10142 {
10143 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
10144 case PRE_INC: o = GEN_INT (8); goto pre_modify;
10145 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
10146 pre_modify:
10147 code = PRE_MODIFY;
10148 break;
10149 case POST_DEC: o = GEN_INT (-8); goto post_modify;
10150 case POST_INC: o = GEN_INT (8); goto post_modify;
10151 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
10152 post_modify:
10153 code = POST_MODIFY;
10154 swap = 2;
10155 break;
10156 default:
10157 gcc_unreachable ();
10158 }
10159 r = XEXP (addr, 0);
10160 xop[0+i] = adjust_automodify_address_nv
10161 (operands[i], SImode,
10162 gen_rtx_fmt_ee (code, Pmode, r,
10163 gen_rtx_PLUS (Pmode, r, o)),
10164 0);
10165 xop[2+i] = adjust_automodify_address_nv
10166 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
10167 }
10168 else
10169 {
10170 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
10171 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
10172 }
10173 }
10174 if (reg_overlap_mentioned_p (xop[0], xop[3]))
10175 {
10176 swap = 2;
10177 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
10178 }
526b7aee 10179
d34a0fdc
CZ
10180 emit_move_insn (xop[0 + swap], xop[1 + swap]);
10181 emit_move_insn (xop[2 - swap], xop[3 - swap]);
526b7aee 10182
526b7aee
SV
10183}
10184
10185/* Select between the instruction output templates s_tmpl (for short INSNs)
10186 and l_tmpl (for long INSNs). */
10187
10188const char *
b3458f61 10189arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
526b7aee
SV
10190{
10191 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
10192
10193 extract_constrain_insn_cached (insn);
10194 return is_short ? s_tmpl : l_tmpl;
10195}
10196
10197/* Searches X for any reference to REGNO, returning the rtx of the
10198 reference found if any. Otherwise, returns NULL_RTX. */
10199
10200rtx
10201arc_regno_use_in (unsigned int regno, rtx x)
10202{
10203 const char *fmt;
10204 int i, j;
10205 rtx tem;
10206
c9bd6bcd 10207 if (REG_P (x) && refers_to_regno_p (regno, x))
526b7aee
SV
10208 return x;
10209
10210 fmt = GET_RTX_FORMAT (GET_CODE (x));
10211 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
10212 {
10213 if (fmt[i] == 'e')
10214 {
10215 if ((tem = regno_use_in (regno, XEXP (x, i))))
10216 return tem;
10217 }
10218 else if (fmt[i] == 'E')
10219 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
10220 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
10221 return tem;
10222 }
10223
10224 return NULL_RTX;
10225}
10226
10227/* Return the integer value of the "type" attribute for INSN, or -1 if
10228 INSN can't have attributes. */
10229
b51addd6 10230static int
84034c69 10231arc_attr_type (rtx_insn *insn)
526b7aee
SV
10232{
10233 if (NONJUMP_INSN_P (insn)
10234 ? (GET_CODE (PATTERN (insn)) == USE
10235 || GET_CODE (PATTERN (insn)) == CLOBBER)
10236 : JUMP_P (insn)
10237 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
10238 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
10239 : !CALL_P (insn))
10240 return -1;
10241 return get_attr_type (insn);
10242}
10243
10244/* Return true if insn sets the condition codes. */
10245
10246bool
84034c69 10247arc_sets_cc_p (rtx_insn *insn)
526b7aee 10248{
84034c69
DM
10249 if (NONJUMP_INSN_P (insn))
10250 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
10251 insn = seq->insn (seq->len () - 1);
526b7aee
SV
10252 return arc_attr_type (insn) == TYPE_COMPARE;
10253}
10254
10255/* Return true if INSN is an instruction with a delay slot we may want
10256 to fill. */
10257
10258bool
b3458f61 10259arc_need_delay (rtx_insn *insn)
526b7aee 10260{
b3458f61 10261 rtx_insn *next;
526b7aee
SV
10262
10263 if (!flag_delayed_branch)
10264 return false;
10265 /* The return at the end of a function needs a delay slot. */
10266 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
10267 && (!(next = next_active_insn (insn))
10268 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
10269 && arc_attr_type (next) == TYPE_RETURN))
10270 && (!TARGET_PAD_RETURN
10271 || (prev_active_insn (insn)
10272 && prev_active_insn (prev_active_insn (insn))
10273 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
10274 return true;
10275 if (NONJUMP_INSN_P (insn)
10276 ? (GET_CODE (PATTERN (insn)) == USE
10277 || GET_CODE (PATTERN (insn)) == CLOBBER
10278 || GET_CODE (PATTERN (insn)) == SEQUENCE)
10279 : JUMP_P (insn)
10280 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
10281 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
10282 : !CALL_P (insn))
10283 return false;
10284 return num_delay_slots (insn) != 0;
10285}
10286
10287/* Return true if the scheduling pass(es) has/have already run,
10288 i.e. where possible, we should try to mitigate high latencies
10289 by different instruction selection. */
10290
10291bool
10292arc_scheduling_not_expected (void)
10293{
10294 return cfun->machine->arc_reorg_started;
10295}
10296
3f445374
CZ
10297/* Code has a minimum p2 alignment of 1, which we must restore after
10298 an ADDR_DIFF_VEC. */
10299
526b7aee 10300int
82082f65 10301arc_label_align (rtx_insn *label)
526b7aee 10302{
3f445374 10303 if (align_labels.levels[0].log < 1)
526b7aee 10304 {
b3458f61 10305 rtx_insn *next = next_nonnote_nondebug_insn (label);
526b7aee
SV
10306 if (INSN_P (next) && recog_memoized (next) >= 0)
10307 return 1;
10308 }
3f445374 10309 return align_labels.levels[0].log;
526b7aee
SV
10310}
10311
10312/* Return true if LABEL is in executable code. */
10313
10314bool
b32d5189 10315arc_text_label (rtx_insn *label)
526b7aee 10316{
b3458f61 10317 rtx_insn *next;
526b7aee
SV
10318
10319 /* ??? We use deleted labels like they were still there, see
10320 gcc.c-torture/compile/20000326-2.c . */
10321 gcc_assert (GET_CODE (label) == CODE_LABEL
10322 || (GET_CODE (label) == NOTE
10323 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
10324 next = next_nonnote_insn (label);
10325 if (next)
10326 return (!JUMP_TABLE_DATA_P (next)
10327 || GET_CODE (PATTERN (next)) != ADDR_VEC);
10328 else if (!PREV_INSN (label))
10329 /* ??? sometimes text labels get inserted very late, see
10330 gcc.dg/torture/stackalign/comp-goto-1.c */
10331 return true;
10332 return false;
10333}
10334
526b7aee
SV
10335/* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
10336 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
339ba33b 10337 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
526b7aee
SV
10338 to redirect two breqs. */
10339
10340static bool
c1ce59ab 10341arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
526b7aee
SV
10342{
10343 /* ??? get_attr_type is declared to take an rtx. */
c1ce59ab 10344 union { const rtx_insn *c; rtx_insn *r; } u;
526b7aee
SV
10345
10346 u.c = follower;
339ba33b 10347 if (CROSSING_JUMP_P (followee))
526b7aee
SV
10348 switch (get_attr_type (u.r))
10349 {
28f4ff35
CZ
10350 case TYPE_BRANCH:
10351 if (get_attr_length (u.r) != 2)
10352 break;
41bc2c0b 10353 /* Fall through. */
526b7aee
SV
10354 case TYPE_BRCC:
10355 case TYPE_BRCC_NO_DELAY_SLOT:
10356 return false;
10357 default:
10358 return true;
10359 }
10360 return true;
10361}
10362
c7314bc1 10363
1825c61e 10364/* Implement EPILOGUE_USES.
526b7aee
SV
10365 Return true if REGNO should be added to the deemed uses of the epilogue.
10366
1825c61e
CZ
10367 We have to make sure all the register restore instructions are
10368 known to be live in interrupt functions, plus the blink register if
10369 it is clobbered by the isr. */
526b7aee
SV
10370
10371bool
10372arc_epilogue_uses (int regno)
10373{
1825c61e 10374 unsigned int fn_type;
ce9dbf20 10375 fn_type = arc_compute_function_type (cfun);
1825c61e 10376
28633bbd
CZ
10377 if (regno == arc_tp_regno)
10378 return true;
1825c61e 10379
ce9dbf20
CZ
10380 if (regno == RETURN_ADDR_REGNUM)
10381 return true;
10382
10383 if (regno == arc_return_address_register (fn_type))
10384 return true;
10385
10386 if (epilogue_completed && ARC_INTERRUPT_P (fn_type))
526b7aee 10387 {
ce9dbf20
CZ
10388 /* An interrupt function restores more registers. */
10389 if (df_regs_ever_live_p (regno) || call_used_regs[regno])
10390 return true;
526b7aee 10391 }
ce9dbf20
CZ
10392
10393 return false;
526b7aee
SV
10394}
10395
28633bbd
CZ
10396/* Helper for EH_USES macro. */
10397
10398bool
10399arc_eh_uses (int regno)
10400{
10401 if (regno == arc_tp_regno)
10402 return true;
10403 return false;
10404}
10405
73dac59b 10406/* Return true if we use LRA instead of reload pass. */
526b7aee 10407
73dac59b 10408bool
526b7aee
SV
10409arc_lra_p (void)
10410{
73dac59b 10411 return arc_lra_flag;
526b7aee
SV
10412}
10413
10414/* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10415 Rcq registers, because some insn are shorter with them. OTOH we already
10416 have separate alternatives for this purpose, and other insns don't
10417 mind, so maybe we should rather prefer the other registers?
10418 We need more data, and we can only get that if we allow people to
10419 try all options. */
10420static int
10421arc_register_priority (int r)
10422{
10423 switch (arc_lra_priority_tag)
10424 {
10425 case ARC_LRA_PRIORITY_NONE:
10426 return 0;
10427 case ARC_LRA_PRIORITY_NONCOMPACT:
10428 return ((((r & 7) ^ 4) - 4) & 15) != r;
10429 case ARC_LRA_PRIORITY_COMPACT:
10430 return ((((r & 7) ^ 4) - 4) & 15) == r;
10431 default:
10432 gcc_unreachable ();
10433 }
10434}
10435
10436static reg_class_t
ef4bddc2 10437arc_spill_class (reg_class_t /* orig_class */, machine_mode)
526b7aee
SV
10438{
10439 return GENERAL_REGS;
10440}
10441
10442bool
ef4bddc2 10443arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
526b7aee
SV
10444 int itype)
10445{
10446 rtx x = *p;
10447 enum reload_type type = (enum reload_type) itype;
10448
10449 if (GET_CODE (x) == PLUS
10450 && CONST_INT_P (XEXP (x, 1))
10451 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
10452 || (REG_P (XEXP (x, 0))
10453 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
10454 {
10455 int scale = GET_MODE_SIZE (mode);
10456 int shift;
10457 rtx index_rtx = XEXP (x, 1);
10458 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
10459 rtx reg, sum, sum2;
10460
10461 if (scale > 4)
10462 scale = 4;
10463 if ((scale-1) & offset)
10464 scale = 1;
10465 shift = scale >> 1;
c419f71c
JL
10466 offset_base
10467 = ((offset + (256 << shift))
4e671509 10468 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
526b7aee
SV
10469 /* Sometimes the normal form does not suit DImode. We
10470 could avoid that by using smaller ranges, but that
10471 would give less optimized code when SImode is
10472 prevalent. */
10473 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
10474 {
10475 int regno;
10476
10477 reg = XEXP (x, 0);
10478 regno = REGNO (reg);
10479 sum2 = sum = plus_constant (Pmode, reg, offset_base);
10480
10481 if (reg_equiv_constant (regno))
10482 {
10483 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
10484 offset_base);
10485 if (GET_CODE (sum2) == PLUS)
10486 sum2 = gen_rtx_CONST (Pmode, sum2);
10487 }
10488 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
10489 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
10490 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
10491 type);
10492 return true;
10493 }
10494 }
10495 /* We must re-recognize what we created before. */
10496 else if (GET_CODE (x) == PLUS
10497 && GET_CODE (XEXP (x, 0)) == PLUS
10498 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
10499 && REG_P (XEXP (XEXP (x, 0), 0))
10500 && CONST_INT_P (XEXP (x, 1)))
10501 {
10502 /* Because this address is so complex, we know it must have
10503 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10504 it is already unshared, and needs no further unsharing. */
10505 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
10506 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10507 return true;
10508 }
10509 return false;
10510}
10511
ad23f5d4
JG
10512/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10513
10514static bool
445d7826 10515arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
ad23f5d4
JG
10516 unsigned int align,
10517 enum by_pieces_operation op,
10518 bool speed_p)
10519{
76715c32 10520 /* Let the cpymem expander handle small block moves. */
ad23f5d4
JG
10521 if (op == MOVE_BY_PIECES)
10522 return false;
10523
10524 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10525}
10526
b8a64b7f
CZ
10527/* Emit a (pre) memory barrier around an atomic sequence according to
10528 MODEL. */
10529
10530static void
10531arc_pre_atomic_barrier (enum memmodel model)
10532{
10533 if (need_atomic_barrier_p (model, true))
10534 emit_insn (gen_memory_barrier ());
10535}
10536
10537/* Emit a (post) memory barrier around an atomic sequence according to
10538 MODEL. */
10539
10540static void
10541arc_post_atomic_barrier (enum memmodel model)
10542{
10543 if (need_atomic_barrier_p (model, false))
10544 emit_insn (gen_memory_barrier ());
10545}
10546
10547/* Expand a compare and swap pattern. */
10548
10549static void
10550emit_unlikely_jump (rtx insn)
10551{
f370536c 10552 rtx_insn *jump = emit_jump_insn (insn);
5fa396ad 10553 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
b8a64b7f
CZ
10554}
10555
10556/* Expand code to perform a 8 or 16-bit compare and swap by doing
10557 32-bit compare and swap on the word containing the byte or
10558 half-word. The difference between a weak and a strong CAS is that
10559 the weak version may simply fail. The strong version relies on two
10560 loops, one checks if the SCOND op is succsfully or not, the other
10561 checks if the 32 bit accessed location which contains the 8 or 16
10562 bit datum is not changed by other thread. The first loop is
10563 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10564 loops is implemented by this routine. */
10565
10566static void
10567arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10568 rtx oldval, rtx newval, rtx weak,
10569 rtx mod_s, rtx mod_f)
10570{
10571 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10572 rtx addr = gen_reg_rtx (Pmode);
10573 rtx off = gen_reg_rtx (SImode);
10574 rtx oldv = gen_reg_rtx (SImode);
10575 rtx newv = gen_reg_rtx (SImode);
10576 rtx oldvalue = gen_reg_rtx (SImode);
10577 rtx newvalue = gen_reg_rtx (SImode);
10578 rtx res = gen_reg_rtx (SImode);
10579 rtx resv = gen_reg_rtx (SImode);
10580 rtx memsi, val, mask, end_label, loop_label, cc, x;
10581 machine_mode mode;
10582 bool is_weak = (weak != const0_rtx);
10583
10584 /* Truncate the address. */
10585 emit_insn (gen_rtx_SET (addr,
10586 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10587
10588 /* Compute the datum offset. */
10589 emit_insn (gen_rtx_SET (off,
10590 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10591 if (TARGET_BIG_ENDIAN)
10592 emit_insn (gen_rtx_SET (off,
10593 gen_rtx_MINUS (SImode,
10594 (GET_MODE (mem) == QImode) ?
10595 GEN_INT (3) : GEN_INT (2), off)));
10596
10597 /* Normal read from truncated address. */
10598 memsi = gen_rtx_MEM (SImode, addr);
10599 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10600 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10601
10602 val = copy_to_reg (memsi);
10603
10604 /* Convert the offset in bits. */
10605 emit_insn (gen_rtx_SET (off,
10606 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10607
10608 /* Get the proper mask. */
10609 if (GET_MODE (mem) == QImode)
10610 mask = force_reg (SImode, GEN_INT (0xff));
10611 else
10612 mask = force_reg (SImode, GEN_INT (0xffff));
10613
10614 emit_insn (gen_rtx_SET (mask,
10615 gen_rtx_ASHIFT (SImode, mask, off)));
10616
10617 /* Prepare the old and new values. */
10618 emit_insn (gen_rtx_SET (val,
10619 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10620 val)));
10621
10622 oldval = gen_lowpart (SImode, oldval);
10623 emit_insn (gen_rtx_SET (oldv,
10624 gen_rtx_ASHIFT (SImode, oldval, off)));
10625
10626 newval = gen_lowpart_common (SImode, newval);
10627 emit_insn (gen_rtx_SET (newv,
10628 gen_rtx_ASHIFT (SImode, newval, off)));
10629
10630 emit_insn (gen_rtx_SET (oldv,
10631 gen_rtx_AND (SImode, oldv, mask)));
10632
10633 emit_insn (gen_rtx_SET (newv,
10634 gen_rtx_AND (SImode, newv, mask)));
10635
10636 if (!is_weak)
10637 {
10638 end_label = gen_label_rtx ();
10639 loop_label = gen_label_rtx ();
10640 emit_label (loop_label);
10641 }
10642
10643 /* Make the old and new values. */
10644 emit_insn (gen_rtx_SET (oldvalue,
10645 gen_rtx_IOR (SImode, oldv, val)));
10646
10647 emit_insn (gen_rtx_SET (newvalue,
10648 gen_rtx_IOR (SImode, newv, val)));
10649
10650 /* Try an 32bit atomic compare and swap. It clobbers the CC
10651 register. */
10652 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10653 weak, mod_s, mod_f));
10654
10655 /* Regardless of the weakness of the operation, a proper boolean
10656 result needs to be provided. */
10657 x = gen_rtx_REG (CC_Zmode, CC_REG);
10658 x = gen_rtx_EQ (SImode, x, const0_rtx);
10659 emit_insn (gen_rtx_SET (bool_result, x));
10660
10661 if (!is_weak)
10662 {
10663 /* Check the results: if the atomic op is successfully the goto
10664 to end label. */
10665 x = gen_rtx_REG (CC_Zmode, CC_REG);
10666 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10667 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10668 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10669 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10670
10671 /* Wait for the right moment when the accessed 32-bit location
10672 is stable. */
10673 emit_insn (gen_rtx_SET (resv,
10674 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10675 res)));
10676 mode = SELECT_CC_MODE (NE, resv, val);
10677 cc = gen_rtx_REG (mode, CC_REG);
10678 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10679
10680 /* Set the new value of the 32 bit location, proper masked. */
10681 emit_insn (gen_rtx_SET (val, resv));
10682
10683 /* Try again if location is unstable. Fall through if only
10684 scond op failed. */
10685 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10686 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10687 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10688 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10689
10690 emit_label (end_label);
10691 }
10692
10693 /* End: proper return the result for the given mode. */
10694 emit_insn (gen_rtx_SET (res,
10695 gen_rtx_AND (SImode, res, mask)));
10696
10697 emit_insn (gen_rtx_SET (res,
10698 gen_rtx_LSHIFTRT (SImode, res, off)));
10699
10700 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10701}
10702
10703/* Helper function used by "atomic_compare_and_swap" expand
10704 pattern. */
10705
10706void
10707arc_expand_compare_and_swap (rtx operands[])
10708{
10709 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10710 machine_mode mode;
10711
10712 bval = operands[0];
10713 rval = operands[1];
10714 mem = operands[2];
10715 oldval = operands[3];
10716 newval = operands[4];
10717 is_weak = operands[5];
10718 mod_s = operands[6];
10719 mod_f = operands[7];
10720 mode = GET_MODE (mem);
10721
10722 if (reg_overlap_mentioned_p (rval, oldval))
10723 oldval = copy_to_reg (oldval);
10724
10725 if (mode == SImode)
10726 {
10727 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10728 is_weak, mod_s, mod_f));
10729 x = gen_rtx_REG (CC_Zmode, CC_REG);
10730 x = gen_rtx_EQ (SImode, x, const0_rtx);
10731 emit_insn (gen_rtx_SET (bval, x));
10732 }
10733 else
10734 {
10735 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10736 is_weak, mod_s, mod_f);
10737 }
10738}
10739
10740/* Helper function used by the "atomic_compare_and_swapsi_1"
10741 pattern. */
10742
10743void
10744arc_split_compare_and_swap (rtx operands[])
10745{
10746 rtx rval, mem, oldval, newval;
10747 machine_mode mode;
10748 enum memmodel mod_s, mod_f;
10749 bool is_weak;
10750 rtx label1, label2, x, cond;
10751
10752 rval = operands[0];
10753 mem = operands[1];
10754 oldval = operands[2];
10755 newval = operands[3];
10756 is_weak = (operands[4] != const0_rtx);
10757 mod_s = (enum memmodel) INTVAL (operands[5]);
10758 mod_f = (enum memmodel) INTVAL (operands[6]);
10759 mode = GET_MODE (mem);
10760
10761 /* ARC atomic ops work only with 32-bit aligned memories. */
10762 gcc_assert (mode == SImode);
10763
10764 arc_pre_atomic_barrier (mod_s);
10765
10766 label1 = NULL_RTX;
10767 if (!is_weak)
10768 {
10769 label1 = gen_label_rtx ();
10770 emit_label (label1);
10771 }
10772 label2 = gen_label_rtx ();
10773
10774 /* Load exclusive. */
10775 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10776
10777 /* Check if it is oldval. */
10778 mode = SELECT_CC_MODE (NE, rval, oldval);
10779 cond = gen_rtx_REG (mode, CC_REG);
10780 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10781
10782 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10783 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10784 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10785 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10786
10787 /* Exclusively store new item. Store clobbers CC reg. */
10788 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10789
10790 if (!is_weak)
10791 {
10792 /* Check the result of the store. */
10793 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10794 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10795 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10796 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10797 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10798 }
10799
10800 if (mod_f != MEMMODEL_RELAXED)
10801 emit_label (label2);
10802
10803 arc_post_atomic_barrier (mod_s);
10804
10805 if (mod_f == MEMMODEL_RELAXED)
10806 emit_label (label2);
10807}
10808
10809/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10810 to perform. MEM is the memory on which to operate. VAL is the second
10811 operand of the binary operator. BEFORE and AFTER are optional locations to
10812 return the value of MEM either before of after the operation. MODEL_RTX
10813 is a CONST_INT containing the memory model to use. */
10814
10815void
10816arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10817 rtx orig_before, rtx orig_after, rtx model_rtx)
10818{
10819 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10820 machine_mode mode = GET_MODE (mem);
10821 rtx label, x, cond;
10822 rtx before = orig_before, after = orig_after;
10823
10824 /* ARC atomic ops work only with 32-bit aligned memories. */
10825 gcc_assert (mode == SImode);
10826
10827 arc_pre_atomic_barrier (model);
10828
10829 label = gen_label_rtx ();
10830 emit_label (label);
10831 label = gen_rtx_LABEL_REF (VOIDmode, label);
10832
10833 if (before == NULL_RTX)
10834 before = gen_reg_rtx (mode);
10835
10836 if (after == NULL_RTX)
10837 after = gen_reg_rtx (mode);
10838
10839 /* Load exclusive. */
10840 emit_insn (gen_arc_load_exclusivesi (before, mem));
10841
10842 switch (code)
10843 {
10844 case NOT:
10845 x = gen_rtx_AND (mode, before, val);
10846 emit_insn (gen_rtx_SET (after, x));
10847 x = gen_rtx_NOT (mode, after);
10848 emit_insn (gen_rtx_SET (after, x));
10849 break;
10850
10851 case MINUS:
10852 if (CONST_INT_P (val))
10853 {
10854 val = GEN_INT (-INTVAL (val));
10855 code = PLUS;
10856 }
10857
10858 /* FALLTHRU. */
10859 default:
10860 x = gen_rtx_fmt_ee (code, mode, before, val);
10861 emit_insn (gen_rtx_SET (after, x));
10862 break;
10863 }
10864
10865 /* Exclusively store new item. Store clobbers CC reg. */
10866 emit_insn (gen_arc_store_exclusivesi (mem, after));
10867
10868 /* Check the result of the store. */
10869 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10870 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10871 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10872 label, pc_rtx);
10873 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10874
10875 arc_post_atomic_barrier (model);
10876}
10877
bf9e9dc5
CZ
10878/* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10879
10880static bool
10881arc_no_speculation_in_delay_slots_p ()
10882{
10883 return true;
10884}
10885
d34a0fdc
CZ
10886/* Return a parallel of registers to represent where to find the
10887 register pieces if required, otherwise NULL_RTX. */
10888
10889static rtx
10890arc_dwarf_register_span (rtx rtl)
10891{
cd1e4d41 10892 machine_mode mode = GET_MODE (rtl);
d34a0fdc
CZ
10893 unsigned regno;
10894 rtx p;
10895
10896 if (GET_MODE_SIZE (mode) != 8)
10897 return NULL_RTX;
10898
10899 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10900 regno = REGNO (rtl);
10901 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10902 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10903
10904 return p;
10905}
10906
fc1c2d04
CZ
10907/* Return true if OP is an acceptable memory operand for ARCompact
10908 16-bit load instructions of MODE.
10909
10910 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10911 non scaled instructions.
10912
10913 SCALED: TRUE if address can be scaled. */
10914
10915bool
10916compact_memory_operand_p (rtx op, machine_mode mode,
10917 bool av2short, bool scaled)
10918{
10919 rtx addr, plus0, plus1;
10920 int size, off;
10921
10922 /* Eliminate non-memory operations. */
10923 if (GET_CODE (op) != MEM)
10924 return 0;
10925
10926 /* .di instructions have no 16-bit form. */
10927 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10928 return false;
10929
3e4a5f54
CZ
10930 /* likewise for uncached types. */
10931 if (arc_is_uncached_mem_p (op))
10932 return false;
10933
fc1c2d04
CZ
10934 if (mode == VOIDmode)
10935 mode = GET_MODE (op);
10936
10937 size = GET_MODE_SIZE (mode);
10938
10939 /* dword operations really put out 2 instructions, so eliminate
10940 them. */
10941 if (size > UNITS_PER_WORD)
10942 return false;
10943
10944 /* Decode the address now. */
10945 addr = XEXP (op, 0);
10946 switch (GET_CODE (addr))
10947 {
10948 case REG:
10949 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10950 || COMPACT_GP_REG_P (REGNO (addr))
10951 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10952 case PLUS:
10953 plus0 = XEXP (addr, 0);
10954 plus1 = XEXP (addr, 1);
10955
10956 if ((GET_CODE (plus0) == REG)
10957 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10958 || COMPACT_GP_REG_P (REGNO (plus0)))
10959 && ((GET_CODE (plus1) == REG)
10960 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10961 || COMPACT_GP_REG_P (REGNO (plus1)))))
10962 {
10963 return !av2short;
10964 }
10965
10966 if ((GET_CODE (plus0) == REG)
10967 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10968 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10969 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10970 && (GET_CODE (plus1) == CONST_INT))
10971 {
10972 bool valid = false;
10973
10974 off = INTVAL (plus1);
10975
10976 /* Negative offset is not supported in 16-bit load/store insns. */
10977 if (off < 0)
10978 return 0;
10979
10980 /* Only u5 immediates allowed in code density instructions. */
10981 if (av2short)
10982 {
10983 switch (size)
10984 {
10985 case 1:
10986 return false;
10987 case 2:
10988 /* This is an ldh_s.x instruction, check the u6
10989 immediate. */
10990 if (COMPACT_GP_REG_P (REGNO (plus0)))
10991 valid = true;
10992 break;
10993 case 4:
10994 /* Only u5 immediates allowed in 32bit access code
10995 density instructions. */
10996 if (REGNO (plus0) <= 31)
10997 return ((off < 32) && (off % 4 == 0));
10998 break;
10999 default:
11000 return false;
11001 }
11002 }
11003 else
11004 if (COMPACT_GP_REG_P (REGNO (plus0)))
11005 valid = true;
11006
11007 if (valid)
11008 {
11009
11010 switch (size)
11011 {
11012 case 1:
11013 return (off < 32);
11014 case 2:
11015 /* The 6-bit constant get shifted to fit the real
11016 5-bits field. Check also for the alignment. */
11017 return ((off < 64) && (off % 2 == 0));
11018 case 4:
11019 return ((off < 128) && (off % 4 == 0));
11020 default:
11021 return false;
11022 }
11023 }
11024 }
11025
11026 if (REG_P (plus0) && CONST_INT_P (plus1)
11027 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
11028 || SP_REG_P (REGNO (plus0)))
11029 && !av2short)
11030 {
11031 off = INTVAL (plus1);
11032 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
11033 }
11034
11035 if ((GET_CODE (plus0) == MULT)
11036 && (GET_CODE (XEXP (plus0, 0)) == REG)
11037 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
11038 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
11039 && (GET_CODE (plus1) == REG)
11040 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
11041 || COMPACT_GP_REG_P (REGNO (plus1))))
11042 return scaled;
11043 default:
11044 break ;
11045 /* TODO: 'gp' and 'pcl' are to supported as base address operand
11046 for 16-bit load instructions. */
11047 }
11048 return false;
11049}
11050
6b55f8c9
CZ
11051/* Return nonzero if a jli call should be generated for a call from
11052 the current function to DECL. */
11053
11054bool
11055arc_is_jli_call_p (rtx pat)
11056{
11057 tree attrs;
11058 tree decl = SYMBOL_REF_DECL (pat);
11059
11060 /* If it is not a well defined public function then return false. */
11061 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
11062 return false;
11063
11064 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
11065 if (lookup_attribute ("jli_always", attrs))
11066 return true;
11067
11068 if (lookup_attribute ("jli_fixed", attrs))
11069 return true;
11070
11071 return TARGET_JLI_ALWAYS;
11072}
11073
11074/* Handle and "jli" attribute; arguments as in struct
11075 attribute_spec.handler. */
11076
11077static tree
11078arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
11079 tree name, tree args, int,
11080 bool *no_add_attrs)
11081{
11082 if (!TARGET_V2)
11083 {
11084 warning (OPT_Wattributes,
11085 "%qE attribute only valid for ARCv2 architecture",
11086 name);
11087 *no_add_attrs = true;
11088 }
11089
11090 if (args == NULL_TREE)
11091 {
11092 warning (OPT_Wattributes,
11093 "argument of %qE attribute is missing",
11094 name);
11095 *no_add_attrs = true;
11096 }
11097 else
11098 {
11099 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11100 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11101 tree arg = TREE_VALUE (args);
11102 if (TREE_CODE (arg) != INTEGER_CST)
11103 {
11104 warning (0, "%qE attribute allows only an integer constant argument",
11105 name);
11106 *no_add_attrs = true;
11107 }
11108 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11109 }
11110 return NULL_TREE;
11111}
11112
7778a1ad
CZ
11113/* Handle and "scure" attribute; arguments as in struct
11114 attribute_spec.handler. */
11115
11116static tree
11117arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
11118 tree name, tree args, int,
11119 bool *no_add_attrs)
11120{
11121 if (!TARGET_EM)
11122 {
11123 warning (OPT_Wattributes,
11124 "%qE attribute only valid for ARC EM architecture",
11125 name);
11126 *no_add_attrs = true;
11127 }
11128
11129 if (args == NULL_TREE)
11130 {
11131 warning (OPT_Wattributes,
11132 "argument of %qE attribute is missing",
11133 name);
11134 *no_add_attrs = true;
11135 }
11136 else
11137 {
11138 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11139 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11140 tree arg = TREE_VALUE (args);
11141 if (TREE_CODE (arg) != INTEGER_CST)
11142 {
11143 warning (0, "%qE attribute allows only an integer constant argument",
11144 name);
11145 *no_add_attrs = true;
11146 }
11147 }
11148 return NULL_TREE;
11149}
11150
11151/* Return nonzero if the symbol is a secure function. */
11152
11153bool
11154arc_is_secure_call_p (rtx pat)
11155{
11156 tree attrs;
11157 tree decl = SYMBOL_REF_DECL (pat);
11158
11159 if (!decl)
11160 return false;
11161
11162 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
11163 if (lookup_attribute ("secure_call", attrs))
11164 return true;
11165
11166 return false;
11167}
11168
8180c03f
CZ
11169/* Handle "uncached" qualifier. */
11170
11171static tree
11172arc_handle_uncached_attribute (tree *node,
11173 tree name, tree args,
11174 int flags ATTRIBUTE_UNUSED,
11175 bool *no_add_attrs)
11176{
11177 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
11178 {
11179 error ("%qE attribute only applies to types",
11180 name);
11181 *no_add_attrs = true;
11182 }
11183 else if (args)
11184 {
11185 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
11186 }
11187 return NULL_TREE;
11188}
11189
11190/* Return TRUE if PAT is a memory addressing an uncached data. */
11191
11192bool
11193arc_is_uncached_mem_p (rtx pat)
11194{
3e4a5f54
CZ
11195 tree attrs = NULL_TREE;
11196 tree addr;
8180c03f
CZ
11197
11198 if (!MEM_P (pat))
11199 return false;
11200
11201 /* Get the memory attributes. */
3e4a5f54
CZ
11202 addr = MEM_EXPR (pat);
11203 if (!addr)
8180c03f
CZ
11204 return false;
11205
3e4a5f54
CZ
11206 /* Get the attributes. */
11207 if (TREE_CODE (addr) == MEM_REF)
11208 {
11209 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
11210 if (lookup_attribute ("uncached", attrs))
11211 return true;
8180c03f 11212
3e4a5f54
CZ
11213 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
11214 if (lookup_attribute ("uncached", attrs))
11215 return true;
11216 }
11217
11218 /* For COMPONENT_REF, use the FIELD_DECL from tree operand 1. */
11219 if (TREE_CODE (addr) == COMPONENT_REF)
11220 {
11221 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
11222 if (lookup_attribute ("uncached", attrs))
11223 return true;
11224 }
8180c03f
CZ
11225 return false;
11226}
11227
b6fb257b
CZ
11228/* Handle aux attribute. The auxiliary registers are addressed using
11229 special instructions lr and sr. The attribute 'aux' indicates if a
11230 variable refers to the aux-regs and what is the register number
11231 desired. */
11232
11233static tree
11234arc_handle_aux_attribute (tree *node,
11235 tree name, tree args, int,
11236 bool *no_add_attrs)
11237{
11238 /* Isn't it better to use address spaces for the aux-regs? */
11239 if (DECL_P (*node))
11240 {
11241 if (TREE_CODE (*node) != VAR_DECL)
11242 {
11243 error ("%qE attribute only applies to variables", name);
11244 *no_add_attrs = true;
11245 }
11246 else if (args)
11247 {
11248 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11249 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11250 tree arg = TREE_VALUE (args);
11251 if (TREE_CODE (arg) != INTEGER_CST)
11252 {
d65485c5 11253 warning (OPT_Wattributes, "%qE attribute allows only an integer "
b6fb257b
CZ
11254 "constant argument", name);
11255 *no_add_attrs = true;
11256 }
11257 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11258 }
11259
11260 if (TREE_CODE (*node) == VAR_DECL)
11261 {
11262 tree fntype = TREE_TYPE (*node);
11263 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
11264 {
11265 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
11266 TYPE_ATTRIBUTES (fntype));
11267 TYPE_ATTRIBUTES (fntype) = attrs;
11268 }
11269 }
11270 }
11271 return NULL_TREE;
11272}
11273
7cfbf676
CZ
11274/* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
11275 anchors for small data: the GP register acts as an anchor in that
11276 case. We also don't want to use them for PC-relative accesses,
11277 where the PC acts as an anchor. Prohibit also TLS symbols to use
11278 anchors. */
11279
11280static bool
11281arc_use_anchors_for_symbol_p (const_rtx symbol)
11282{
11283 if (SYMBOL_REF_TLS_MODEL (symbol))
11284 return false;
11285
11286 if (flag_pic)
11287 return false;
11288
11289 if (SYMBOL_REF_SMALL_P (symbol))
11290 return false;
11291
11292 return default_use_anchors_for_symbol_p (symbol);
11293}
11294
31e72f4f
CZ
11295/* Return true if SUBST can't safely replace its equivalent during RA. */
11296static bool
11297arc_cannot_substitute_mem_equiv_p (rtx)
11298{
11299 /* If SUBST is mem[base+index], the address may not fit ISA,
11300 thus return true. */
11301 return true;
11302}
11303
8fa2c211
CZ
11304/* Checks whether the operands are valid for use in an LDD/STD
11305 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
11306 by the patterns. Assumes that the address in the base register RN
11307 is word aligned. Pattern guarantees that both memory accesses use
11308 the same base register, the offsets are constants within the range,
11309 and the gap between the offsets is 4. If reload complete then
11310 check that registers are legal. */
11311
11312static bool
11313operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT offset)
11314{
11315 unsigned int t, t2;
11316
11317 if (!reload_completed)
11318 return true;
11319
11320 if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & (~0x03),
11321 (offset & (GET_MODE_SIZE (DImode) - 1) & 3
11322 ? 0 : -(-GET_MODE_SIZE (DImode) | (~0x03)) >> 1))))
11323 return false;
11324
11325 t = REGNO (rt);
11326 t2 = REGNO (rt2);
11327
73dac59b 11328 if ((t2 == PCL_REG)
8fa2c211
CZ
11329 || (t % 2 != 0) /* First destination register is not even. */
11330 || (t2 != t + 1))
11331 return false;
11332
11333 return true;
11334}
11335
11336/* Helper for gen_operands_ldd_std. Returns true iff the memory
11337 operand MEM's address contains an immediate offset from the base
11338 register and has no side effects, in which case it sets BASE and
11339 OFFSET accordingly. */
11340
11341static bool
11342mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset)
11343{
11344 rtx addr;
11345
11346 gcc_assert (base != NULL && offset != NULL);
11347
11348 /* TODO: Handle more general memory operand patterns, such as
11349 PRE_DEC and PRE_INC. */
11350
11351 if (side_effects_p (mem))
11352 return false;
11353
11354 /* Can't deal with subregs. */
11355 if (GET_CODE (mem) == SUBREG)
11356 return false;
11357
11358 gcc_assert (MEM_P (mem));
11359
11360 *offset = const0_rtx;
11361
11362 addr = XEXP (mem, 0);
11363
11364 /* If addr isn't valid for DImode, then we can't handle it. */
11365 if (!arc_legitimate_address_p (DImode, addr,
11366 reload_in_progress || reload_completed))
11367 return false;
11368
11369 if (REG_P (addr))
11370 {
11371 *base = addr;
11372 return true;
11373 }
11374 else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
11375 {
11376 *base = XEXP (addr, 0);
11377 *offset = XEXP (addr, 1);
11378 return (REG_P (*base) && CONST_INT_P (*offset));
11379 }
11380
11381 return false;
11382}
11383
11384/* Called from peephole2 to replace two word-size accesses with a
11385 single LDD/STD instruction. Returns true iff we can generate a new
11386 instruction sequence. That is, both accesses use the same base
11387 register and the gap between constant offsets is 4. OPERANDS are
11388 the operands found by the peephole matcher; OPERANDS[0,1] are
11389 register operands, and OPERANDS[2,3] are the corresponding memory
11390 operands. LOAD indicates whether the access is load or store. */
11391
11392bool
11393gen_operands_ldd_std (rtx *operands, bool load, bool commute)
11394{
11395 int i, gap;
11396 HOST_WIDE_INT offsets[2], offset;
11397 int nops = 2;
11398 rtx cur_base, cur_offset, tmp;
11399 rtx base = NULL_RTX;
11400
11401 /* Check that the memory references are immediate offsets from the
11402 same base register. Extract the base register, the destination
11403 registers, and the corresponding memory offsets. */
11404 for (i = 0; i < nops; i++)
11405 {
11406 if (!mem_ok_for_ldd_std (operands[nops+i], &cur_base, &cur_offset))
11407 return false;
11408
11409 if (i == 0)
11410 base = cur_base;
11411 else if (REGNO (base) != REGNO (cur_base))
11412 return false;
11413
11414 offsets[i] = INTVAL (cur_offset);
11415 if (GET_CODE (operands[i]) == SUBREG)
11416 {
11417 tmp = SUBREG_REG (operands[i]);
11418 gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp));
11419 operands[i] = tmp;
11420 }
11421 }
11422
11423 /* Make sure there is no dependency between the individual loads. */
11424 if (load && REGNO (operands[0]) == REGNO (base))
11425 return false; /* RAW. */
11426
11427 if (load && REGNO (operands[0]) == REGNO (operands[1]))
11428 return false; /* WAW. */
11429
11430 /* Make sure the instructions are ordered with lower memory access first. */
11431 if (offsets[0] > offsets[1])
11432 {
11433 gap = offsets[0] - offsets[1];
11434 offset = offsets[1];
11435
11436 /* Swap the instructions such that lower memory is accessed first. */
11437 std::swap (operands[0], operands[1]);
11438 std::swap (operands[2], operands[3]);
11439 }
11440 else
11441 {
11442 gap = offsets[1] - offsets[0];
11443 offset = offsets[0];
11444 }
11445
11446 /* Make sure accesses are to consecutive memory locations. */
11447 if (gap != 4)
11448 return false;
11449
11450 /* Make sure we generate legal instructions. */
11451 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11452 return true;
11453
11454 if (load && commute)
11455 {
11456 /* Try reordering registers. */
11457 std::swap (operands[0], operands[1]);
11458 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11459 return true;
11460 }
11461
11462 return false;
11463}
11464
864e2eaa
CZ
11465/* This order of allocation is used when we compile for size. It
11466 allocates first the registers which are most probably to end up in
11467 a short instruction. */
11468static const int size_alloc_order[] =
11469{
11470 0, 1, 2, 3, 12, 13, 14, 15,
11471 4, 5, 6, 7, 8, 9, 10, 11
11472};
11473
11474/* Adjust register allocation order when compiling for size. */
11475void
11476arc_adjust_reg_alloc_order (void)
11477{
11478 const int arc_default_alloc_order[] = REG_ALLOC_ORDER;
11479 memcpy (reg_alloc_order, arc_default_alloc_order, sizeof (reg_alloc_order));
11480 if (optimize_size)
11481 memcpy (reg_alloc_order, size_alloc_order, sizeof (size_alloc_order));
11482}
11483
b9bc3b12
CZ
11484/* Implement TARGET_MEMORY_MOVE_COST. */
11485
11486static int
11487arc_memory_move_cost (machine_mode mode,
11488 reg_class_t rclass ATTRIBUTE_UNUSED,
11489 bool in ATTRIBUTE_UNUSED)
11490{
11491 if ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
11492 || ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD * 2) && TARGET_LL64))
11493 return 6;
11494
11495 return (2 * GET_MODE_SIZE (mode));
11496}
11497
03301dcc
CZ
11498/* Split an OR instruction into multiple BSET/OR instructions in a
11499 attempt to avoid long immediate constants. The next strategies are
11500 employed when destination is 'q' reg.
11501
11502 1. if there are up to three bits set in the mask, a succession of
11503 three bset instruction will be emitted:
11504 OR rA, rB, mask ->
11505 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
11506
11507 2. if the lower 6 bits of the mask is set and there is only one
11508 bit set in the upper remaining bits then we will emit one bset and
11509 one OR instruction:
11510 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
11511
11512 3. otherwise an OR with limm will be emmitted. */
11513
11514void
11515arc_split_ior (rtx *operands)
11516{
11517 unsigned HOST_WIDE_INT mask, maskx;
11518 rtx op1 = operands[1];
11519
11520 gcc_assert (CONST_INT_P (operands[2]));
11521 mask = INTVAL (operands[2]) & 0xffffffff;
11522
11523 if (__builtin_popcount (mask) > 3 || (mask & 0x3f))
11524 {
11525 maskx = mask & 0x3f;
11526 emit_insn (gen_rtx_SET (operands[0],
11527 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11528 op1 = operands[0];
11529 mask &= ~maskx;
11530 }
11531
11532 switch (__builtin_popcount (mask))
11533 {
11534 case 3:
11535 maskx = 1 << (__builtin_ffs (mask) - 1);
11536 emit_insn (gen_rtx_SET (operands[0],
11537 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11538 mask &= ~maskx;
11539 op1 = operands[0];
11540 /* FALLTHRU */
11541 case 2:
11542 maskx = 1 << (__builtin_ffs (mask) - 1);
11543 emit_insn (gen_rtx_SET (operands[0],
11544 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11545 mask &= ~maskx;
11546 op1 = operands[0];
11547 /* FALLTHRU */
11548 case 1:
11549 maskx = 1 << (__builtin_ffs (mask) - 1);
11550 emit_insn (gen_rtx_SET (operands[0],
11551 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11552 break;
11553 default:
11554 break;
11555 }
11556}
11557
11558/* Helper to check C0x constraint. */
11559
11560bool
11561arc_check_ior_const (HOST_WIDE_INT ival)
11562{
11563 unsigned int mask = (unsigned int) (ival & 0xffffffff);
11564 if (__builtin_popcount (mask) <= 3)
11565 return true;
11566 if (__builtin_popcount (mask & ~0x3f) <= 1)
11567 return true;
11568 return false;
11569}
11570
11571/* Split a mov with long immediate instruction into smaller, size
11572 friendly instructions. */
11573
11574bool
11575arc_split_mov_const (rtx *operands)
11576{
11577 unsigned HOST_WIDE_INT ival;
11578 HOST_WIDE_INT shimm;
11579 machine_mode mode = GET_MODE (operands[0]);
11580
11581 /* Manage a constant. */
11582 gcc_assert (CONST_INT_P (operands[1]));
11583 ival = INTVAL (operands[1]) & 0xffffffff;
11584
11585 if (SIGNED_INT12 (ival))
11586 return false;
11587
11588 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11589 if (TARGET_BARREL_SHIFTER && TARGET_V2
11590 && ((ival & ~0x3f000000) == 0))
11591 {
11592 shimm = (ival >> 24) & 0x3f;
11593 emit_insn (gen_rtx_SET (operands[0],
11594 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11595 GEN_INT (8))));
11596 return true;
11597 }
11598 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11599 if (TARGET_BARREL_SHIFTER && TARGET_V2
11600 && ((ival & ~0x3f00) == 0))
11601 {
11602 shimm = (ival >> 8) & 0x3f;
11603 emit_insn (gen_rtx_SET (operands[0],
11604 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11605 GEN_INT (8))));
11606 return true;
11607 }
11608
11609 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11610 if (TARGET_BARREL_SHIFTER && TARGET_V2
11611 && ((ival & ~0x3f0000) == 0))
11612 {
11613 shimm = (ival >> 16) & 0x3f;
11614 emit_insn (gen_rtx_SET (operands[0],
11615 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11616 GEN_INT (16))));
11617 return true;
11618 }
11619
11620 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11621 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0
11622 && TARGET_BARREL_SHIFTER)
11623 {
11624 HOST_WIDE_INT shift = __builtin_ffs (ival);
11625 shimm = (ival >> (shift - 1)) & 0xff;
11626 emit_insn (gen_rtx_SET (operands[0], GEN_INT (shimm)));
11627 emit_insn (gen_rtx_SET (operands[0],
11628 gen_rtx_ASHIFT (mode, operands[0],
11629 GEN_INT (shift - 1))));
11630 return true;
11631 }
11632
11633 /* 5. Check if we can just rotate the limm, useful when no barrel
11634 shifter is present. */
11635 if ((ival & ~0x8000001f) == 0)
11636 {
11637 shimm = (ival * 2 + 1) & 0x3f;
11638 emit_insn (gen_rtx_SET (operands[0],
11639 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11640 const1_rtx)));
11641 return true;
11642 }
11643
11644 /* 6. Check if we can do something with bmask. */
11645 if (IS_POWEROF2_P (ival + 1))
11646 {
11647 emit_insn (gen_rtx_SET (operands[0], constm1_rtx));
11648 emit_insn (gen_rtx_SET (operands[0],
11649 gen_rtx_AND (mode, operands[0],
11650 GEN_INT (ival))));
11651 return true;
11652 }
11653
11654 return false;
11655}
11656
11657/* Helper to check Cax constraint. */
11658
11659bool
11660arc_check_mov_const (HOST_WIDE_INT ival)
11661{
11662 ival = ival & 0xffffffff;
11663
11664 if ((ival & ~0x8000001f) == 0)
11665 return true;
11666
11667 if (IS_POWEROF2_P (ival + 1))
11668 return true;
11669
11670 /* The next rules requires a barrel shifter. */
11671 if (!TARGET_BARREL_SHIFTER)
11672 return false;
11673
11674 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0)
11675 return true;
11676
11677 if ((ival & ~0x3f00) == 0)
11678 return true;
11679
11680 if ((ival & ~0x3f0000) == 0)
11681 return true;
11682
11683 if ((ival & ~0x3f000000) == 0)
11684 return true;
11685
11686 return false;
11687}
11688
ce9dbf20
CZ
11689/* Return nonzero if this function is known to have a null epilogue.
11690 This allows the optimizer to omit jumps to jumps if no stack
11691 was created. */
11692
11693bool
11694arc_can_use_return_insn (void)
11695{
11696 return (reload_completed && cfun->machine->frame_info.total_size == 0
11697 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
11698}
03301dcc 11699
7cfbf676
CZ
11700#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11701#define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11702
58e17cf8
RS
11703#undef TARGET_CONSTANT_ALIGNMENT
11704#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11705
31e72f4f
CZ
11706#undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11707#define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11708
efcc2e30
CZ
11709#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11710#define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11711
8e95721a
CZ
11712#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11713#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11714
b9bc3b12
CZ
11715#undef TARGET_REGISTER_MOVE_COST
11716#define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11717
11718#undef TARGET_MEMORY_MOVE_COST
11719#define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11720
526b7aee
SV
11721struct gcc_target targetm = TARGET_INITIALIZER;
11722
11723#include "gt-arc.h"