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