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