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