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