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