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