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