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