]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/arc.c
Machine modes for address printing.
[thirdparty/gcc.git] / gcc / config / arc / arc.c
CommitLineData
526b7aee 1/* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
5624e564 2 Copyright (C) 1994-2015 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
31#include "config.h"
526b7aee
SV
32#include "system.h"
33#include "coretypes.h"
c7131fb2 34#include "backend.h"
e11c4407 35#include "target.h"
c7131fb2 36#include "rtl.h"
e11c4407
AM
37#include "tree.h"
38#include "cfghooks.h"
c7131fb2 39#include "df.h"
e11c4407
AM
40#include "tm_p.h"
41#include "stringpool.h"
42#include "optabs.h"
43#include "regs.h"
44#include "emit-rtl.h"
45#include "recog.h"
46#include "diagnostic.h"
40e23961 47#include "fold-const.h"
d8a2d370
DN
48#include "varasm.h"
49#include "stor-layout.h"
d8a2d370 50#include "calls.h"
526b7aee
SV
51#include "output.h"
52#include "insn-attr.h"
53#include "flags.h"
36566b39 54#include "explow.h"
526b7aee 55#include "expr.h"
526b7aee 56#include "langhooks.h"
526b7aee
SV
57#include "tm-constrs.h"
58#include "reload.h" /* For operands_match_p */
60393bbc 59#include "cfgrtl.h"
526b7aee
SV
60#include "tree-pass.h"
61#include "context.h"
9b2b7279 62#include "builtins.h"
6733978e 63#include "rtl-iter.h"
526b7aee 64
fb155425 65/* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
526b7aee
SV
66static const char *arc_cpu_string = "";
67
68/* ??? Loads can handle any constant, stores can only handle small ones. */
69/* OTOH, LIMMs cost extra, so their usefulness is limited. */
70#define RTX_OK_FOR_OFFSET_P(MODE, X) \
71(GET_CODE (X) == CONST_INT \
72 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
73 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
74 ? 0 \
75 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
76
77#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, INDEX, STRICT) \
78(GET_CODE (X) == PLUS \
79 && RTX_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
80 && ((INDEX && RTX_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT)) \
81 && GET_MODE_SIZE ((MODE)) <= 4) \
82 || RTX_OK_FOR_OFFSET_P (MODE, XEXP (X, 1))))
83
84#define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
85(GET_CODE (X) == PLUS \
86 && GET_CODE (XEXP (X, 0)) == MULT \
87 && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
88 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
89 && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
90 || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
91 && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
92 || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
93
94#define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
95 (GET_CODE (X) == PLUS \
96 && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
97 && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
98 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
99 || (GET_CODE (XEXP ((X), 1)) == CONST \
100 && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
101 && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
102 && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
103 && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
104
105/* Array of valid operand punctuation characters. */
106char arc_punct_chars[256];
107
108/* State used by arc_ccfsm_advance to implement conditional execution. */
109struct GTY (()) arc_ccfsm
110{
111 int state;
112 int cc;
113 rtx cond;
b3458f61 114 rtx_insn *target_insn;
526b7aee
SV
115 int target_label;
116};
117
118#define arc_ccfsm_current cfun->machine->ccfsm_current
119
120#define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
121 ((STATE)->state == 1 || (STATE)->state == 2)
122
123/* Indicate we're conditionalizing insns now. */
124#define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
125 ((STATE)->state += 2)
126
127#define ARC_CCFSM_COND_EXEC_P(STATE) \
128 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
129 || current_insn_predicate)
130
131/* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
132#define CCFSM_ISCOMPACT(INSN,STATE) \
133 (ARC_CCFSM_COND_EXEC_P (STATE) \
134 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
135 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
136 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
137
138/* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
139#define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
140 ((ARC_CCFSM_COND_EXEC_P (STATE) \
141 || (JUMP_P (JUMP) \
142 && INSN_ANNULLED_BRANCH_P (JUMP) \
143 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
144 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
145 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
146 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
147
148/* The maximum number of insns skipped which will be conditionalised if
149 possible. */
150/* When optimizing for speed:
151 Let p be the probability that the potentially skipped insns need to
152 be executed, pn the cost of a correctly predicted non-taken branch,
153 mt the cost of a mis/non-predicted taken branch,
154 mn mispredicted non-taken, pt correctly predicted taken ;
155 costs expressed in numbers of instructions like the ones considered
156 skipping.
157 Unfortunately we don't have a measure of predictability - this
158 is linked to probability only in that in the no-eviction-scenario
159 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
160 value that can be assumed *if* the distribution is perfectly random.
161 A predictability of 1 is perfectly plausible not matter what p is,
162 because the decision could be dependent on an invocation parameter
163 of the program.
164 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
165 For small p, we want MAX_INSNS_SKIPPED == pt
166
167 When optimizing for size:
168 We want to skip insn unless we could use 16 opcodes for the
169 non-conditionalized insn to balance the branch length or more.
170 Performance can be tie-breaker. */
171/* If the potentially-skipped insns are likely to be executed, we'll
172 generally save one non-taken branch
173 o
174 this to be no less than the 1/p */
175#define MAX_INSNS_SKIPPED 3
176
177/* The values of unspec's first field. */
178enum {
179 ARC_UNSPEC_PLT = 3,
180 ARC_UNSPEC_GOT,
181 ARC_UNSPEC_GOTOFF
182} ;
183
184
185enum arc_builtins {
186 ARC_BUILTIN_NOP = 2,
187 ARC_BUILTIN_NORM = 3,
188 ARC_BUILTIN_NORMW = 4,
189 ARC_BUILTIN_SWAP = 5,
190 ARC_BUILTIN_BRK = 6,
191 ARC_BUILTIN_DIVAW = 7,
192 ARC_BUILTIN_EX = 8,
193 ARC_BUILTIN_MUL64 = 9,
194 ARC_BUILTIN_MULU64 = 10,
195 ARC_BUILTIN_RTIE = 11,
196 ARC_BUILTIN_SYNC = 12,
197 ARC_BUILTIN_CORE_READ = 13,
198 ARC_BUILTIN_CORE_WRITE = 14,
199 ARC_BUILTIN_FLAG = 15,
200 ARC_BUILTIN_LR = 16,
201 ARC_BUILTIN_SR = 17,
202 ARC_BUILTIN_SLEEP = 18,
203 ARC_BUILTIN_SWI = 19,
204 ARC_BUILTIN_TRAP_S = 20,
205 ARC_BUILTIN_UNIMP_S = 21,
206 ARC_BUILTIN_ALIGNED = 22,
207
208 /* Sentinel to mark start of simd builtins. */
209 ARC_SIMD_BUILTIN_BEGIN = 1000,
210
211 ARC_SIMD_BUILTIN_VADDAW = 1001,
212 ARC_SIMD_BUILTIN_VADDW = 1002,
213 ARC_SIMD_BUILTIN_VAVB = 1003,
214 ARC_SIMD_BUILTIN_VAVRB = 1004,
215 ARC_SIMD_BUILTIN_VDIFAW = 1005,
216 ARC_SIMD_BUILTIN_VDIFW = 1006,
217 ARC_SIMD_BUILTIN_VMAXAW = 1007,
218 ARC_SIMD_BUILTIN_VMAXW = 1008,
219 ARC_SIMD_BUILTIN_VMINAW = 1009,
220 ARC_SIMD_BUILTIN_VMINW = 1010,
221 ARC_SIMD_BUILTIN_VMULAW = 1011,
222 ARC_SIMD_BUILTIN_VMULFAW = 1012,
223 ARC_SIMD_BUILTIN_VMULFW = 1013,
224 ARC_SIMD_BUILTIN_VMULW = 1014,
225 ARC_SIMD_BUILTIN_VSUBAW = 1015,
226 ARC_SIMD_BUILTIN_VSUBW = 1016,
227 ARC_SIMD_BUILTIN_VSUMMW = 1017,
228 ARC_SIMD_BUILTIN_VAND = 1018,
229 ARC_SIMD_BUILTIN_VANDAW = 1019,
230 ARC_SIMD_BUILTIN_VBIC = 1020,
231 ARC_SIMD_BUILTIN_VBICAW = 1021,
232 ARC_SIMD_BUILTIN_VOR = 1022,
233 ARC_SIMD_BUILTIN_VXOR = 1023,
234 ARC_SIMD_BUILTIN_VXORAW = 1024,
235 ARC_SIMD_BUILTIN_VEQW = 1025,
236 ARC_SIMD_BUILTIN_VLEW = 1026,
237 ARC_SIMD_BUILTIN_VLTW = 1027,
238 ARC_SIMD_BUILTIN_VNEW = 1028,
239 ARC_SIMD_BUILTIN_VMR1AW = 1029,
240 ARC_SIMD_BUILTIN_VMR1W = 1030,
241 ARC_SIMD_BUILTIN_VMR2AW = 1031,
242 ARC_SIMD_BUILTIN_VMR2W = 1032,
243 ARC_SIMD_BUILTIN_VMR3AW = 1033,
244 ARC_SIMD_BUILTIN_VMR3W = 1034,
245 ARC_SIMD_BUILTIN_VMR4AW = 1035,
246 ARC_SIMD_BUILTIN_VMR4W = 1036,
247 ARC_SIMD_BUILTIN_VMR5AW = 1037,
248 ARC_SIMD_BUILTIN_VMR5W = 1038,
249 ARC_SIMD_BUILTIN_VMR6AW = 1039,
250 ARC_SIMD_BUILTIN_VMR6W = 1040,
251 ARC_SIMD_BUILTIN_VMR7AW = 1041,
252 ARC_SIMD_BUILTIN_VMR7W = 1042,
253 ARC_SIMD_BUILTIN_VMRB = 1043,
254 ARC_SIMD_BUILTIN_VH264F = 1044,
255 ARC_SIMD_BUILTIN_VH264FT = 1045,
256 ARC_SIMD_BUILTIN_VH264FW = 1046,
257 ARC_SIMD_BUILTIN_VVC1F = 1047,
258 ARC_SIMD_BUILTIN_VVC1FT = 1048,
259
260 /* Va, Vb, rlimm instructions. */
261 ARC_SIMD_BUILTIN_VBADDW = 1050,
262 ARC_SIMD_BUILTIN_VBMAXW = 1051,
263 ARC_SIMD_BUILTIN_VBMINW = 1052,
264 ARC_SIMD_BUILTIN_VBMULAW = 1053,
265 ARC_SIMD_BUILTIN_VBMULFW = 1054,
266 ARC_SIMD_BUILTIN_VBMULW = 1055,
267 ARC_SIMD_BUILTIN_VBRSUBW = 1056,
268 ARC_SIMD_BUILTIN_VBSUBW = 1057,
269
270 /* Va, Vb, Ic instructions. */
271 ARC_SIMD_BUILTIN_VASRW = 1060,
272 ARC_SIMD_BUILTIN_VSR8 = 1061,
273 ARC_SIMD_BUILTIN_VSR8AW = 1062,
274
275 /* Va, Vb, u6 instructions. */
276 ARC_SIMD_BUILTIN_VASRRWi = 1065,
277 ARC_SIMD_BUILTIN_VASRSRWi = 1066,
278 ARC_SIMD_BUILTIN_VASRWi = 1067,
279 ARC_SIMD_BUILTIN_VASRPWBi = 1068,
280 ARC_SIMD_BUILTIN_VASRRPWBi = 1069,
281 ARC_SIMD_BUILTIN_VSR8AWi = 1070,
282 ARC_SIMD_BUILTIN_VSR8i = 1071,
283
284 /* Va, Vb, u8 (simm) instructions. */
285 ARC_SIMD_BUILTIN_VMVAW = 1075,
286 ARC_SIMD_BUILTIN_VMVW = 1076,
287 ARC_SIMD_BUILTIN_VMVZW = 1077,
288 ARC_SIMD_BUILTIN_VD6TAPF = 1078,
289
290 /* Va, rlimm, u8 (simm) instructions. */
291 ARC_SIMD_BUILTIN_VMOVAW = 1080,
292 ARC_SIMD_BUILTIN_VMOVW = 1081,
293 ARC_SIMD_BUILTIN_VMOVZW = 1082,
294
295 /* Va, Vb instructions. */
296 ARC_SIMD_BUILTIN_VABSAW = 1085,
297 ARC_SIMD_BUILTIN_VABSW = 1086,
298 ARC_SIMD_BUILTIN_VADDSUW = 1087,
299 ARC_SIMD_BUILTIN_VSIGNW = 1088,
300 ARC_SIMD_BUILTIN_VEXCH1 = 1089,
301 ARC_SIMD_BUILTIN_VEXCH2 = 1090,
302 ARC_SIMD_BUILTIN_VEXCH4 = 1091,
303 ARC_SIMD_BUILTIN_VUPBAW = 1092,
304 ARC_SIMD_BUILTIN_VUPBW = 1093,
305 ARC_SIMD_BUILTIN_VUPSBAW = 1094,
306 ARC_SIMD_BUILTIN_VUPSBW = 1095,
307
308 ARC_SIMD_BUILTIN_VDIRUN = 1100,
309 ARC_SIMD_BUILTIN_VDORUN = 1101,
310 ARC_SIMD_BUILTIN_VDIWR = 1102,
311 ARC_SIMD_BUILTIN_VDOWR = 1103,
312
313 ARC_SIMD_BUILTIN_VREC = 1105,
314 ARC_SIMD_BUILTIN_VRUN = 1106,
315 ARC_SIMD_BUILTIN_VRECRUN = 1107,
316 ARC_SIMD_BUILTIN_VENDREC = 1108,
317
318 ARC_SIMD_BUILTIN_VLD32WH = 1110,
319 ARC_SIMD_BUILTIN_VLD32WL = 1111,
320 ARC_SIMD_BUILTIN_VLD64 = 1112,
321 ARC_SIMD_BUILTIN_VLD32 = 1113,
322 ARC_SIMD_BUILTIN_VLD64W = 1114,
323 ARC_SIMD_BUILTIN_VLD128 = 1115,
324 ARC_SIMD_BUILTIN_VST128 = 1116,
325 ARC_SIMD_BUILTIN_VST64 = 1117,
326
327 ARC_SIMD_BUILTIN_VST16_N = 1120,
328 ARC_SIMD_BUILTIN_VST32_N = 1121,
329
330 ARC_SIMD_BUILTIN_VINTI = 1201,
331
332 ARC_SIMD_BUILTIN_END
333};
334
335/* A nop is needed between a 4 byte insn that sets the condition codes and
336 a branch that uses them (the same isn't true for an 8 byte insn that sets
337 the condition codes). Set by arc_ccfsm_advance. Used by
338 arc_print_operand. */
339
340static int get_arc_condition_code (rtx);
341
342static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
343
344/* Initialized arc_attribute_table to NULL since arc doesnot have any
345 machine specific supported attributes. */
346const struct attribute_spec arc_attribute_table[] =
347{
348 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
349 affects_type_identity } */
350 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute, true },
351 /* Function calls made to this symbol must be done indirectly, because
352 it may lie outside of the 21/25 bit addressing range of a normal function
353 call. */
354 { "long_call", 0, 0, false, true, true, NULL, false },
355 /* Whereas these functions are always known to reside within the 25 bit
356 addressing range of unconditionalized bl. */
357 { "medium_call", 0, 0, false, true, true, NULL, false },
358 /* And these functions are always known to reside within the 21 bit
359 addressing range of blcc. */
360 { "short_call", 0, 0, false, true, true, NULL, false },
361 { NULL, 0, 0, false, false, false, NULL, false }
362};
363static int arc_comp_type_attributes (const_tree, const_tree);
364static void arc_file_start (void);
365static void arc_internal_label (FILE *, const char *, unsigned long);
366static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
367 tree);
ef4bddc2 368static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
526b7aee
SV
369static void arc_encode_section_info (tree decl, rtx rtl, int first);
370
371static void arc_init_builtins (void);
ef4bddc2 372static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
526b7aee
SV
373
374static int branch_dest (rtx);
375
376static void arc_output_pic_addr_const (FILE *, rtx, int);
ef4bddc2 377void emit_pic_move (rtx *, machine_mode);
526b7aee
SV
378bool arc_legitimate_pic_operand_p (rtx);
379static bool arc_function_ok_for_sibcall (tree, tree);
380static rtx arc_function_value (const_tree, const_tree, bool);
381const char * output_shift (rtx *);
382static void arc_reorg (void);
383static bool arc_in_small_data_p (const_tree);
384
385static void arc_init_reg_tables (void);
386static bool arc_return_in_memory (const_tree, const_tree);
387static void arc_init_simd_builtins (void);
ef4bddc2 388static bool arc_vector_mode_supported_p (machine_mode);
526b7aee 389
807e902e
KZ
390static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
391 unsigned int, bool);
ac44248e 392static const char *arc_invalid_within_doloop (const rtx_insn *);
526b7aee
SV
393
394static void output_short_suffix (FILE *file);
395
396static bool arc_frame_pointer_required (void);
397
445d7826 398static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
ad23f5d4
JG
399 unsigned int,
400 enum by_pieces_operation op,
401 bool);
402
526b7aee
SV
403/* Implements target hook vector_mode_supported_p. */
404
405static bool
ef4bddc2 406arc_vector_mode_supported_p (machine_mode mode)
526b7aee
SV
407{
408 if (!TARGET_SIMD_SET)
409 return false;
410
411 if ((mode == V4SImode)
412 || (mode == V8HImode))
413 return true;
414
415 return false;
416}
417
418
419/* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
420static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
421static rtx arc_delegitimize_address (rtx);
c1ce59ab
DM
422static bool arc_can_follow_jump (const rtx_insn *follower,
423 const rtx_insn *followee);
526b7aee
SV
424
425static rtx frame_insn (rtx);
ef4bddc2 426static void arc_function_arg_advance (cumulative_args_t, machine_mode,
526b7aee 427 const_tree, bool);
ef4bddc2 428static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
526b7aee
SV
429
430static void arc_finalize_pic (void);
431
432/* initialize the GCC target structure. */
433#undef TARGET_COMP_TYPE_ATTRIBUTES
434#define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
435#undef TARGET_ASM_FILE_START
436#define TARGET_ASM_FILE_START arc_file_start
437#undef TARGET_ATTRIBUTE_TABLE
438#define TARGET_ATTRIBUTE_TABLE arc_attribute_table
439#undef TARGET_ASM_INTERNAL_LABEL
440#define TARGET_ASM_INTERNAL_LABEL arc_internal_label
441#undef TARGET_RTX_COSTS
442#define TARGET_RTX_COSTS arc_rtx_costs
443#undef TARGET_ADDRESS_COST
444#define TARGET_ADDRESS_COST arc_address_cost
445
446#undef TARGET_ENCODE_SECTION_INFO
447#define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
448
449#undef TARGET_CANNOT_FORCE_CONST_MEM
450#define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
451
452#undef TARGET_INIT_BUILTINS
453#define TARGET_INIT_BUILTINS arc_init_builtins
454
455#undef TARGET_EXPAND_BUILTIN
456#define TARGET_EXPAND_BUILTIN arc_expand_builtin
457
458#undef TARGET_ASM_OUTPUT_MI_THUNK
459#define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
460
461#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
462#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
463
464#undef TARGET_FUNCTION_OK_FOR_SIBCALL
465#define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
466
467#undef TARGET_MACHINE_DEPENDENT_REORG
468#define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
469
470#undef TARGET_IN_SMALL_DATA_P
471#define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
472
473#undef TARGET_PROMOTE_FUNCTION_MODE
474#define TARGET_PROMOTE_FUNCTION_MODE \
475 default_promote_function_mode_always_promote
476
477#undef TARGET_PROMOTE_PROTOTYPES
478#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
479
480#undef TARGET_RETURN_IN_MEMORY
481#define TARGET_RETURN_IN_MEMORY arc_return_in_memory
482#undef TARGET_PASS_BY_REFERENCE
483#define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
484
485#undef TARGET_SETUP_INCOMING_VARARGS
486#define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
487
488#undef TARGET_ARG_PARTIAL_BYTES
489#define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
490
491#undef TARGET_MUST_PASS_IN_STACK
492#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
493
494#undef TARGET_FUNCTION_VALUE
495#define TARGET_FUNCTION_VALUE arc_function_value
496
497#undef TARGET_SCHED_ADJUST_PRIORITY
498#define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
499
500#undef TARGET_VECTOR_MODE_SUPPORTED_P
501#define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
502
1d0216c8
RS
503#undef TARGET_CAN_USE_DOLOOP_P
504#define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
505
526b7aee
SV
506#undef TARGET_INVALID_WITHIN_DOLOOP
507#define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
508
509#undef TARGET_PRESERVE_RELOAD_P
510#define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
511
512#undef TARGET_CAN_FOLLOW_JUMP
513#define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
514
515#undef TARGET_DELEGITIMIZE_ADDRESS
516#define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
517
ad23f5d4
JG
518#undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
519#define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
520 arc_use_by_pieces_infrastructure_p
521
526b7aee
SV
522/* Usually, we will be able to scale anchor offsets.
523 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
524#undef TARGET_MIN_ANCHOR_OFFSET
525#define TARGET_MIN_ANCHOR_OFFSET (-1024)
526#undef TARGET_MAX_ANCHOR_OFFSET
527#define TARGET_MAX_ANCHOR_OFFSET (1020)
528
529#undef TARGET_SECONDARY_RELOAD
530#define TARGET_SECONDARY_RELOAD arc_secondary_reload
531
532#define TARGET_OPTION_OVERRIDE arc_override_options
533
534#define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
535
536#define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
537
538#define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
539
540#define TARGET_CAN_ELIMINATE arc_can_eliminate
541
542#define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
543
544#define TARGET_FUNCTION_ARG arc_function_arg
545
546#define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
547
548#define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
549
550#define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
551
552#define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
553
554#define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
555
556#define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
557
558#define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
559
53c8d5a7 560#undef TARGET_LRA_P
526b7aee
SV
561#define TARGET_LRA_P arc_lra_p
562#define TARGET_REGISTER_PRIORITY arc_register_priority
563/* Stores with scaled offsets have different displacement ranges. */
564#define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
565#define TARGET_SPILL_CLASS arc_spill_class
566
567#include "target-def.h"
568
569#undef TARGET_ASM_ALIGNED_HI_OP
570#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
571#undef TARGET_ASM_ALIGNED_SI_OP
572#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
573
574/* Try to keep the (mov:DF _, reg) as early as possible so
575 that the d<add/sub/mul>h-lr insns appear together and can
576 use the peephole2 pattern. */
577
578static int
ac44248e 579arc_sched_adjust_priority (rtx_insn *insn, int priority)
526b7aee
SV
580{
581 rtx set = single_set (insn);
582 if (set
583 && GET_MODE (SET_SRC(set)) == DFmode
584 && GET_CODE (SET_SRC(set)) == REG)
585 {
586 /* Incrementing priority by 20 (empirically derived). */
587 return priority + 20;
588 }
589
590 return priority;
591}
592
593static reg_class_t
ef4bddc2 594arc_secondary_reload (bool in_p, rtx x, reg_class_t cl, machine_mode,
526b7aee
SV
595 secondary_reload_info *)
596{
597 if (cl == DOUBLE_REGS)
598 return GENERAL_REGS;
599
600 /* The loop counter register can be stored, but not loaded directly. */
601 if ((cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS)
602 && in_p && MEM_P (x))
603 return GENERAL_REGS;
604 return NO_REGS;
605}
606
607static unsigned arc_ifcvt (void);
608
609namespace {
610
611const pass_data pass_data_arc_ifcvt =
612{
613 RTL_PASS,
614 "arc_ifcvt", /* name */
615 OPTGROUP_NONE, /* optinfo_flags */
526b7aee
SV
616 TV_IFCVT2, /* tv_id */
617 0, /* properties_required */
618 0, /* properties_provided */
619 0, /* properties_destroyed */
620 0, /* todo_flags_start */
621 TODO_df_finish /* todo_flags_finish */
622};
623
624class pass_arc_ifcvt : public rtl_opt_pass
625{
626public:
627 pass_arc_ifcvt(gcc::context *ctxt)
628 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt)
629 {}
630
631 /* opt_pass methods: */
cd4dd8f0 632 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); }
be55bfe6 633 virtual unsigned int execute (function *) { return arc_ifcvt (); }
526b7aee
SV
634};
635
636} // anon namespace
637
638rtl_opt_pass *
639make_pass_arc_ifcvt (gcc::context *ctxt)
640{
641 return new pass_arc_ifcvt (ctxt);
642}
643
0bc69b81
JR
644static unsigned arc_predicate_delay_insns (void);
645
646namespace {
647
648const pass_data pass_data_arc_predicate_delay_insns =
649{
650 RTL_PASS,
651 "arc_predicate_delay_insns", /* name */
652 OPTGROUP_NONE, /* optinfo_flags */
0bc69b81
JR
653 TV_IFCVT2, /* tv_id */
654 0, /* properties_required */
655 0, /* properties_provided */
656 0, /* properties_destroyed */
657 0, /* todo_flags_start */
658 TODO_df_finish /* todo_flags_finish */
659};
660
661class pass_arc_predicate_delay_insns : public rtl_opt_pass
662{
663public:
664 pass_arc_predicate_delay_insns(gcc::context *ctxt)
665 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
666 {}
667
668 /* opt_pass methods: */
be55bfe6
TS
669 virtual unsigned int execute (function *)
670 {
671 return arc_predicate_delay_insns ();
672 }
0bc69b81
JR
673};
674
675} // anon namespace
676
677rtl_opt_pass *
678make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
679{
680 return new pass_arc_predicate_delay_insns (ctxt);
681}
682
526b7aee
SV
683/* Called by OVERRIDE_OPTIONS to initialize various things. */
684
685void
686arc_init (void)
687{
688 enum attr_tune tune_dflt = TUNE_NONE;
689
fb155425 690 if (TARGET_ARC600)
526b7aee
SV
691 {
692 arc_cpu_string = "ARC600";
693 tune_dflt = TUNE_ARC600;
694 }
695 else if (TARGET_ARC601)
696 {
697 arc_cpu_string = "ARC601";
698 tune_dflt = TUNE_ARC600;
699 }
700 else if (TARGET_ARC700)
701 {
702 arc_cpu_string = "ARC700";
703 tune_dflt = TUNE_ARC700_4_2_STD;
704 }
705 else
706 gcc_unreachable ();
707 if (arc_tune == TUNE_NONE)
708 arc_tune = tune_dflt;
709 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
710 if (arc_multcost < 0)
711 switch (arc_tune)
712 {
713 case TUNE_ARC700_4_2_STD:
714 /* latency 7;
715 max throughput (1 multiply + 4 other insns) / 5 cycles. */
716 arc_multcost = COSTS_N_INSNS (4);
717 if (TARGET_NOMPY_SET)
718 arc_multcost = COSTS_N_INSNS (30);
719 break;
720 case TUNE_ARC700_4_2_XMAC:
721 /* latency 5;
722 max throughput (1 multiply + 2 other insns) / 3 cycles. */
723 arc_multcost = COSTS_N_INSNS (3);
724 if (TARGET_NOMPY_SET)
725 arc_multcost = COSTS_N_INSNS (30);
726 break;
727 case TUNE_ARC600:
728 if (TARGET_MUL64_SET)
729 {
730 arc_multcost = COSTS_N_INSNS (4);
731 break;
732 }
733 /* Fall through. */
734 default:
735 arc_multcost = COSTS_N_INSNS (30);
736 break;
737 }
738
fb155425 739 /* Support mul64 generation only for ARC600. */
526b7aee
SV
740 if (TARGET_MUL64_SET && TARGET_ARC700)
741 error ("-mmul64 not supported for ARC700");
742
743 /* MPY instructions valid only for ARC700. */
744 if (TARGET_NOMPY_SET && !TARGET_ARC700)
745 error ("-mno-mpy supported only for ARC700");
746
747 /* mul/mac instructions only for ARC600. */
748 if (TARGET_MULMAC_32BY16_SET && !(TARGET_ARC600 || TARGET_ARC601))
749 error ("-mmul32x16 supported only for ARC600 or ARC601");
750
751 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
2236746b 752 error ("-mno-dpfp-lrsr supported only with -mdpfp");
526b7aee
SV
753
754 /* FPX-1. No fast and compact together. */
755 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
756 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
757 error ("FPX fast and compact options cannot be specified together");
758
759 /* FPX-2. No fast-spfp for arc600 or arc601. */
760 if (TARGET_SPFP_FAST_SET && (TARGET_ARC600 || TARGET_ARC601))
761 error ("-mspfp_fast not available on ARC600 or ARC601");
762
763 /* FPX-3. No FPX extensions on pre-ARC600 cores. */
764 if ((TARGET_DPFP || TARGET_SPFP)
765 && !(TARGET_ARC600 || TARGET_ARC601 || TARGET_ARC700))
766 error ("FPX extensions not available on pre-ARC600 cores");
767
768 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
769 if (flag_pic && !TARGET_ARC700)
770 {
771 warning (DK_WARNING, "PIC is not supported for %s. Generating non-PIC code only..", arc_cpu_string);
772 flag_pic = 0;
773 }
774
775 arc_init_reg_tables ();
776
777 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
778 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
779 arc_punct_chars['#'] = 1;
780 arc_punct_chars['*'] = 1;
781 arc_punct_chars['?'] = 1;
782 arc_punct_chars['!'] = 1;
783 arc_punct_chars['^'] = 1;
784 arc_punct_chars['&'] = 1;
785
786 if (optimize > 1 && !TARGET_NO_COND_EXEC)
787 {
788 /* There are two target-independent ifcvt passes, and arc_reorg may do
789 one or more arc_ifcvt calls. */
790 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g);
791 struct register_pass_info arc_ifcvt4_info
792 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER };
793 struct register_pass_info arc_ifcvt5_info
794 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE };
795
796 register_pass (&arc_ifcvt4_info);
797 register_pass (&arc_ifcvt5_info);
798 }
0bc69b81
JR
799
800 if (flag_delayed_branch)
801 {
802 opt_pass *pass_arc_predicate_delay_insns
803 = make_pass_arc_predicate_delay_insns (g);
804 struct register_pass_info arc_predicate_delay_info
805 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER };
806
807 register_pass (&arc_predicate_delay_info);
808 }
526b7aee
SV
809}
810
811/* Check ARC options, generate derived target attributes. */
812
813static void
814arc_override_options (void)
815{
816 if (arc_cpu == PROCESSOR_NONE)
817 arc_cpu = PROCESSOR_ARC700;
818
819 if (arc_size_opt_level == 3)
820 optimize_size = 1;
821
822 if (flag_pic)
823 target_flags |= MASK_NO_SDATA_SET;
824
825 if (flag_no_common == 255)
826 flag_no_common = !TARGET_NO_SDATA_SET;
827
828 /* TARGET_COMPACT_CASESI needs the "q" register class. */ \
829 if (TARGET_MIXED_CODE)
830 TARGET_Q_CLASS = 1;
831 if (!TARGET_Q_CLASS)
832 TARGET_COMPACT_CASESI = 0;
833 if (TARGET_COMPACT_CASESI)
834 TARGET_CASE_VECTOR_PC_RELATIVE = 1;
835
836 /* These need to be done at start up. It's convenient to do them here. */
837 arc_init ();
838}
839
840/* The condition codes of the ARC, and the inverse function. */
841/* For short branches, the "c" / "nc" names are not defined in the ARC
842 Programmers manual, so we have to use "lo" / "hs"" instead. */
843static const char *arc_condition_codes[] =
844{
845 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
846 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
847};
848
849enum arc_cc_code_index
850{
851 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
852 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
853 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
854 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
855};
856
857#define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
858
859/* Returns the index of the ARC condition code string in
860 `arc_condition_codes'. COMPARISON should be an rtx like
861 `(eq (...) (...))'. */
862
863static int
864get_arc_condition_code (rtx comparison)
865{
866 switch (GET_MODE (XEXP (comparison, 0)))
867 {
868 case CCmode:
869 case SImode: /* For BRcc. */
870 switch (GET_CODE (comparison))
871 {
872 case EQ : return ARC_CC_EQ;
873 case NE : return ARC_CC_NE;
874 case GT : return ARC_CC_GT;
875 case LE : return ARC_CC_LE;
876 case GE : return ARC_CC_GE;
877 case LT : return ARC_CC_LT;
878 case GTU : return ARC_CC_HI;
879 case LEU : return ARC_CC_LS;
880 case LTU : return ARC_CC_LO;
881 case GEU : return ARC_CC_HS;
882 default : gcc_unreachable ();
883 }
884 case CC_ZNmode:
885 switch (GET_CODE (comparison))
886 {
887 case EQ : return ARC_CC_EQ;
888 case NE : return ARC_CC_NE;
889 case GE: return ARC_CC_P;
890 case LT: return ARC_CC_N;
891 case GT : return ARC_CC_PNZ;
892 default : gcc_unreachable ();
893 }
894 case CC_Zmode:
895 switch (GET_CODE (comparison))
896 {
897 case EQ : return ARC_CC_EQ;
898 case NE : return ARC_CC_NE;
899 default : gcc_unreachable ();
900 }
901 case CC_Cmode:
902 switch (GET_CODE (comparison))
903 {
904 case LTU : return ARC_CC_C;
905 case GEU : return ARC_CC_NC;
906 default : gcc_unreachable ();
907 }
908 case CC_FP_GTmode:
909 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
910 switch (GET_CODE (comparison))
911 {
912 case GT : return ARC_CC_N;
913 case UNLE: return ARC_CC_P;
914 default : gcc_unreachable ();
915 }
916 else
917 switch (GET_CODE (comparison))
918 {
919 case GT : return ARC_CC_HI;
920 case UNLE : return ARC_CC_LS;
921 default : gcc_unreachable ();
922 }
923 case CC_FP_GEmode:
924 /* Same for FPX and non-FPX. */
925 switch (GET_CODE (comparison))
926 {
927 case GE : return ARC_CC_HS;
928 case UNLT : return ARC_CC_LO;
929 default : gcc_unreachable ();
930 }
931 case CC_FP_UNEQmode:
932 switch (GET_CODE (comparison))
933 {
934 case UNEQ : return ARC_CC_EQ;
935 case LTGT : return ARC_CC_NE;
936 default : gcc_unreachable ();
937 }
938 case CC_FP_ORDmode:
939 switch (GET_CODE (comparison))
940 {
941 case UNORDERED : return ARC_CC_C;
942 case ORDERED : return ARC_CC_NC;
943 default : gcc_unreachable ();
944 }
945 case CC_FPXmode:
946 switch (GET_CODE (comparison))
947 {
948 case EQ : return ARC_CC_EQ;
949 case NE : return ARC_CC_NE;
950 case UNORDERED : return ARC_CC_C;
951 case ORDERED : return ARC_CC_NC;
952 case LTGT : return ARC_CC_HI;
953 case UNEQ : return ARC_CC_LS;
954 default : gcc_unreachable ();
955 }
956 default : gcc_unreachable ();
957 }
958 /*NOTREACHED*/
959 return (42);
960}
961
962/* Return true if COMPARISON has a short form that can accomodate OFFSET. */
963
964bool
965arc_short_comparison_p (rtx comparison, int offset)
966{
967 gcc_assert (ARC_CC_NC == ARC_CC_HS);
968 gcc_assert (ARC_CC_C == ARC_CC_LO);
969 switch (get_arc_condition_code (comparison))
970 {
971 case ARC_CC_EQ: case ARC_CC_NE:
972 return offset >= -512 && offset <= 506;
973 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
974 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
975 return offset >= -64 && offset <= 58;
976 default:
977 return false;
978 }
979}
980
981/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
982 return the mode to be used for the comparison. */
983
ef4bddc2 984machine_mode
526b7aee
SV
985arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
986{
ef4bddc2 987 machine_mode mode = GET_MODE (x);
526b7aee
SV
988 rtx x1;
989
990 /* For an operation that sets the condition codes as a side-effect, the
991 C and V flags is not set as for cmp, so we can only use comparisons where
992 this doesn't matter. (For LT and GE we can use "mi" and "pl"
993 instead.) */
994 /* ??? We could use "pnz" for greater than zero, however, we could then
995 get into trouble because the comparison could not be reversed. */
996 if (GET_MODE_CLASS (mode) == MODE_INT
997 && y == const0_rtx
998 && (op == EQ || op == NE
486c559b 999 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
526b7aee
SV
1000 return CC_ZNmode;
1001
1002 /* add.f for if (a+b) */
1003 if (mode == SImode
1004 && GET_CODE (y) == NEG
1005 && (op == EQ || op == NE))
1006 return CC_ZNmode;
1007
1008 /* Check if this is a test suitable for bxor.f . */
1009 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1010 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1011 && INTVAL (y))
1012 return CC_Zmode;
1013
1014 /* Check if this is a test suitable for add / bmsk.f . */
1015 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1016 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1017 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1018 && (~INTVAL (x1) | INTVAL (y)) < 0
1019 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1020 return CC_Zmode;
1021
1022 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1023 && GET_CODE (x) == PLUS
1024 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1025 return CC_Cmode;
1026
1027 if (TARGET_ARGONAUT_SET
1028 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1029 switch (op)
1030 {
1031 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1032 return CC_FPXmode;
1033 case LT: case UNGE: case GT: case UNLE:
1034 return CC_FP_GTmode;
1035 case LE: case UNGT: case GE: case UNLT:
1036 return CC_FP_GEmode;
1037 default: gcc_unreachable ();
1038 }
1039 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1040 switch (op)
1041 {
1042 case EQ: case NE: return CC_Zmode;
1043 case LT: case UNGE:
1044 case GT: case UNLE: return CC_FP_GTmode;
1045 case LE: case UNGT:
1046 case GE: case UNLT: return CC_FP_GEmode;
1047 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1048 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1049 default: gcc_unreachable ();
1050 }
1051
1052 return CCmode;
1053}
1054
1055/* Vectors to keep interesting information about registers where it can easily
1056 be got. We use to use the actual mode value as the bit number, but there
1057 is (or may be) more than 32 modes now. Instead we use two tables: one
1058 indexed by hard register number, and one indexed by mode. */
1059
1060/* The purpose of arc_mode_class is to shrink the range of modes so that
1061 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1062 mapped into one arc_mode_class mode. */
1063
1064enum arc_mode_class {
1065 C_MODE,
1066 S_MODE, D_MODE, T_MODE, O_MODE,
1067 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1068 V_MODE
1069};
1070
1071/* Modes for condition codes. */
1072#define C_MODES (1 << (int) C_MODE)
1073
1074/* Modes for single-word and smaller quantities. */
1075#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1076
1077/* Modes for double-word and smaller quantities. */
1078#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1079
1080/* Mode for 8-byte DF values only. */
1081#define DF_MODES (1 << DF_MODE)
1082
1083/* Modes for quad-word and smaller quantities. */
1084#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1085
1086/* Modes for 128-bit vectors. */
1087#define V_MODES (1 << (int) V_MODE)
1088
1089/* Value is 1 if register/mode pair is acceptable on arc. */
1090
1091unsigned int arc_hard_regno_mode_ok[] = {
1092 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1093 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1094 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1095 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1096
1097 /* ??? Leave these as S_MODES for now. */
1098 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1099 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1100 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1101 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1102
1103 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1104 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1105 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1106 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1107
1108 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1109 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1110 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1111 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1112
1113 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1114 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES
1115};
1116
1117unsigned int arc_mode_class [NUM_MACHINE_MODES];
1118
1119enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1120
1121enum reg_class
1122arc_preferred_reload_class (rtx, enum reg_class cl)
1123{
1124 if ((cl) == CHEAP_CORE_REGS || (cl) == WRITABLE_CORE_REGS)
1125 return GENERAL_REGS;
1126 return cl;
1127}
1128
1129/* Initialize the arc_mode_class array. */
1130
1131static void
1132arc_init_reg_tables (void)
1133{
1134 int i;
1135
1136 for (i = 0; i < NUM_MACHINE_MODES; i++)
1137 {
ef4bddc2 1138 machine_mode m = (machine_mode) i;
f8d91e80
NC
1139
1140 switch (GET_MODE_CLASS (m))
526b7aee
SV
1141 {
1142 case MODE_INT:
1143 case MODE_PARTIAL_INT:
1144 case MODE_COMPLEX_INT:
f8d91e80 1145 if (GET_MODE_SIZE (m) <= 4)
526b7aee 1146 arc_mode_class[i] = 1 << (int) S_MODE;
f8d91e80 1147 else if (GET_MODE_SIZE (m) == 8)
526b7aee 1148 arc_mode_class[i] = 1 << (int) D_MODE;
f8d91e80 1149 else if (GET_MODE_SIZE (m) == 16)
526b7aee 1150 arc_mode_class[i] = 1 << (int) T_MODE;
f8d91e80 1151 else if (GET_MODE_SIZE (m) == 32)
526b7aee
SV
1152 arc_mode_class[i] = 1 << (int) O_MODE;
1153 else
1154 arc_mode_class[i] = 0;
1155 break;
1156 case MODE_FLOAT:
1157 case MODE_COMPLEX_FLOAT:
f8d91e80 1158 if (GET_MODE_SIZE (m) <= 4)
526b7aee 1159 arc_mode_class[i] = 1 << (int) SF_MODE;
f8d91e80 1160 else if (GET_MODE_SIZE (m) == 8)
526b7aee 1161 arc_mode_class[i] = 1 << (int) DF_MODE;
f8d91e80 1162 else if (GET_MODE_SIZE (m) == 16)
526b7aee 1163 arc_mode_class[i] = 1 << (int) TF_MODE;
f8d91e80 1164 else if (GET_MODE_SIZE (m) == 32)
526b7aee
SV
1165 arc_mode_class[i] = 1 << (int) OF_MODE;
1166 else
1167 arc_mode_class[i] = 0;
1168 break;
1169 case MODE_VECTOR_INT:
1170 arc_mode_class [i] = (1<< (int) V_MODE);
1171 break;
1172 case MODE_CC:
1173 default:
1174 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1175 we must explicitly check for them here. */
1176 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1177 || i == (int) CC_Cmode
1178 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode)
1179 arc_mode_class[i] = 1 << (int) C_MODE;
1180 else
1181 arc_mode_class[i] = 0;
1182 break;
1183 }
1184 }
1185}
1186
1187/* Core registers 56..59 are used for multiply extension options.
1188 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1189 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1190 number depends on endianness.
1191 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1192 Because mlo / mhi form a 64 bit value, we use different gcc internal
1193 register numbers to make them form a register pair as the gcc internals
1194 know it. mmid gets number 57, if still available, and mlo / mhi get
1195 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1196 to map this back. */
1197 char rname56[5] = "r56";
1198 char rname57[5] = "r57";
1199 char rname58[5] = "r58";
1200 char rname59[5] = "r59";
1201
1202static void
1203arc_conditional_register_usage (void)
1204{
1205 int regno;
1206 int i;
1207 int fix_start = 60, fix_end = 55;
1208
1209 if (TARGET_MUL64_SET)
1210 {
1211 fix_start = 57;
1212 fix_end = 59;
1213
1214 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1215 you are supposed to refer to it as mlo & mhi, e.g
1216 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1217 In an actual asm instruction, you are of course use mmed.
1218 The point of avoiding having a separate register for mmed is that
1219 this way, we don't have to carry clobbers of that reg around in every
1220 isntruction that modifies mlo and/or mhi. */
1221 strcpy (rname57, "");
1222 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo");
1223 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi");
1224 }
1225 if (TARGET_MULMAC_32BY16_SET)
1226 {
1227 fix_start = 56;
1228 fix_end = fix_end > 57 ? fix_end : 57;
1229 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1230 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1231 }
1232 for (regno = fix_start; regno <= fix_end; regno++)
1233 {
1234 if (!fixed_regs[regno])
1235 warning (0, "multiply option implies r%d is fixed", regno);
1236 fixed_regs [regno] = call_used_regs[regno] = 1;
1237 }
1238 if (TARGET_Q_CLASS)
1239 {
1240 reg_alloc_order[2] = 12;
1241 reg_alloc_order[3] = 13;
1242 reg_alloc_order[4] = 14;
1243 reg_alloc_order[5] = 15;
1244 reg_alloc_order[6] = 1;
1245 reg_alloc_order[7] = 0;
1246 reg_alloc_order[8] = 4;
1247 reg_alloc_order[9] = 5;
1248 reg_alloc_order[10] = 6;
1249 reg_alloc_order[11] = 7;
1250 reg_alloc_order[12] = 8;
1251 reg_alloc_order[13] = 9;
1252 reg_alloc_order[14] = 10;
1253 reg_alloc_order[15] = 11;
1254 }
1255 if (TARGET_SIMD_SET)
1256 {
1257 int i;
6462fab0
JR
1258 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1259 reg_alloc_order [i] = i;
1260 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1261 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
526b7aee
SV
1262 reg_alloc_order [i] = i;
1263 }
fb155425 1264 /* For ARC600, lp_count may not be read in an instruction
526b7aee
SV
1265 following immediately after another one setting it to a new value.
1266 There was some discussion on how to enforce scheduling constraints for
1267 processors with missing interlocks on the gcc mailing list:
1268 http://gcc.gnu.org/ml/gcc/2008-05/msg00021.html .
1269 However, we can't actually use this approach, because for ARC the
1270 delay slot scheduling pass is active, which runs after
1271 machine_dependent_reorg. */
1272 if (TARGET_ARC600)
1273 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1274 else if (!TARGET_ARC700)
1275 fixed_regs[LP_COUNT] = 1;
1276 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1277 if (!call_used_regs[regno])
1278 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
1279 for (regno = 32; regno < 60; regno++)
1280 if (!fixed_regs[regno])
1281 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], regno);
1282 if (TARGET_ARC700)
1283 {
1284 for (regno = 32; regno <= 60; regno++)
1285 CLEAR_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], regno);
1286
1287 /* If they have used -ffixed-lp_count, make sure it takes
1288 effect. */
1289 if (fixed_regs[LP_COUNT])
1290 {
1291 CLEAR_HARD_REG_BIT (reg_class_contents[LPCOUNT_REG], LP_COUNT);
1292 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1293 CLEAR_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], LP_COUNT);
1294
1295 /* Instead of taking out SF_MODE like below, forbid it outright. */
1296 arc_hard_regno_mode_ok[60] = 0;
1297 }
1298 else
1299 arc_hard_regno_mode_ok[60] = 1 << (int) S_MODE;
1300 }
1301
1302 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1303 {
1304 if (i < 29)
1305 {
1306 if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15))))
1307 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1308 else
1309 arc_regno_reg_class[i] = GENERAL_REGS;
1310 }
1311 else if (i < 60)
1312 arc_regno_reg_class[i]
1313 = (fixed_regs[i]
1314 ? (TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i)
1315 ? CHEAP_CORE_REGS : ALL_CORE_REGS)
1316 : ((TARGET_ARC700
1317 && TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i))
1318 ? CHEAP_CORE_REGS : WRITABLE_CORE_REGS));
1319 else
1320 arc_regno_reg_class[i] = NO_REGS;
1321 }
1322
1323 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated. */
1324 if (!TARGET_Q_CLASS)
1325 {
1326 CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
1327 CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
1328 }
1329
1330 gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
1331
1332 /* Handle Special Registers. */
1333 arc_regno_reg_class[29] = LINK_REGS; /* ilink1 register. */
1334 arc_regno_reg_class[30] = LINK_REGS; /* ilink2 register. */
1335 arc_regno_reg_class[31] = LINK_REGS; /* blink register. */
1336 arc_regno_reg_class[60] = LPCOUNT_REG;
1337 arc_regno_reg_class[61] = NO_REGS; /* CC_REG: must be NO_REGS. */
1338 arc_regno_reg_class[62] = GENERAL_REGS;
1339
1340 if (TARGET_DPFP)
1341 {
1342 for (i = 40; i < 44; ++i)
1343 {
1344 arc_regno_reg_class[i] = DOUBLE_REGS;
1345
1346 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1347 no attempt is made to use such a register as a destination
1348 operand in *movdf_insn. */
1349 if (!TARGET_ARGONAUT_SET)
1350 {
1351 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1352 interpreted to mean they can use D1 or D2 in their insn. */
1353 CLEAR_HARD_REG_BIT(reg_class_contents[CHEAP_CORE_REGS ], i);
1354 CLEAR_HARD_REG_BIT(reg_class_contents[ALL_CORE_REGS ], i);
1355 CLEAR_HARD_REG_BIT(reg_class_contents[WRITABLE_CORE_REGS ], i);
1356 CLEAR_HARD_REG_BIT(reg_class_contents[MPY_WRITABLE_CORE_REGS], i);
1357 }
1358 }
1359 }
1360 else
1361 {
1362 /* Disable all DOUBLE_REGISTER settings,
1363 if not generating DPFP code. */
1364 arc_regno_reg_class[40] = ALL_REGS;
1365 arc_regno_reg_class[41] = ALL_REGS;
1366 arc_regno_reg_class[42] = ALL_REGS;
1367 arc_regno_reg_class[43] = ALL_REGS;
1368
1369 arc_hard_regno_mode_ok[40] = 0;
1370 arc_hard_regno_mode_ok[42] = 0;
1371
1372 CLEAR_HARD_REG_SET(reg_class_contents [DOUBLE_REGS]);
1373 }
1374
1375 if (TARGET_SIMD_SET)
1376 {
1377 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1378 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
1379
1380 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1381 arc_regno_reg_class [i] = SIMD_VR_REGS;
1382
1383 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
1384 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
1385 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
1386 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
1387
1388 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1389 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1390 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
1391 }
1392
1393 /* pc : r63 */
1394 arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
1395}
1396
1397/* Handle an "interrupt" attribute; arguments as in
1398 struct attribute_spec.handler. */
1399
1400static tree
1401arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
1402 bool *no_add_attrs)
1403{
1404 gcc_assert (args);
1405
1406 tree value = TREE_VALUE (args);
1407
1408 if (TREE_CODE (value) != STRING_CST)
1409 {
1410 warning (OPT_Wattributes,
1411 "argument of %qE attribute is not a string constant",
1412 name);
1413 *no_add_attrs = true;
1414 }
1415 else if (strcmp (TREE_STRING_POINTER (value), "ilink1")
1416 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
1417 {
1418 warning (OPT_Wattributes,
1419 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1420 name);
1421 *no_add_attrs = true;
1422 }
1423 return NULL_TREE;
1424}
1425
1426/* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1427 and two if they are nearly compatible (which causes a warning to be
1428 generated). */
1429
1430static int
1431arc_comp_type_attributes (const_tree type1,
1432 const_tree type2)
1433{
1434 int l1, l2, m1, m2, s1, s2;
1435
1436 /* Check for mismatch of non-default calling convention. */
1437 if (TREE_CODE (type1) != FUNCTION_TYPE)
1438 return 1;
1439
1440 /* Check for mismatched call attributes. */
1441 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
1442 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
1443 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
1444 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
1445 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
1446 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
1447
1448 /* Only bother to check if an attribute is defined. */
1449 if (l1 | l2 | m1 | m2 | s1 | s2)
1450 {
1451 /* If one type has an attribute, the other must have the same attribute. */
1452 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
1453 return 0;
1454
1455 /* Disallow mixed attributes. */
1456 if (l1 + m1 + s1 > 1)
1457 return 0;
1458 }
1459
1460
1461 return 1;
1462}
1463
1464/* Set the default attributes for TYPE. */
1465
1466void
1467arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED)
1468{
1469 gcc_unreachable();
1470}
1471
1472/* Misc. utilities. */
1473
1474/* X and Y are two things to compare using CODE. Emit the compare insn and
1475 return the rtx for the cc reg in the proper mode. */
1476
1477rtx
ef4bddc2 1478gen_compare_reg (rtx comparison, machine_mode omode)
526b7aee
SV
1479{
1480 enum rtx_code code = GET_CODE (comparison);
1481 rtx x = XEXP (comparison, 0);
1482 rtx y = XEXP (comparison, 1);
1483 rtx tmp, cc_reg;
ef4bddc2 1484 machine_mode mode, cmode;
526b7aee
SV
1485
1486
1487 cmode = GET_MODE (x);
1488 if (cmode == VOIDmode)
1489 cmode = GET_MODE (y);
1490 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode);
1491 if (cmode == SImode)
1492 {
1493 if (!register_operand (x, SImode))
1494 {
1495 if (register_operand (y, SImode))
1496 {
1497 tmp = x;
1498 x = y;
1499 y = tmp;
1500 code = swap_condition (code);
1501 }
1502 else
1503 x = copy_to_mode_reg (SImode, x);
1504 }
1505 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
1506 y = copy_to_mode_reg (SImode, y);
1507 }
1508 else
1509 {
1510 x = force_reg (cmode, x);
1511 y = force_reg (cmode, y);
1512 }
1513 mode = SELECT_CC_MODE (code, x, y);
1514
1515 cc_reg = gen_rtx_REG (mode, CC_REG);
1516
1517 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
1518 cmpdfpx_raw, is not a correct comparison for floats:
1519 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1520 */
1521 if (TARGET_ARGONAUT_SET
1522 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
1523 {
1524 switch (code)
1525 {
1526 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
1527 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1528 break;
1529 case GT: case UNLE: case GE: case UNLT:
1530 code = swap_condition (code);
1531 tmp = x;
1532 x = y;
1533 y = tmp;
1534 break;
1535 default:
1536 gcc_unreachable ();
1537 }
1538 if (cmode == SFmode)
1539 {
1540 emit_insn (gen_cmpsfpx_raw (x, y));
1541 }
1542 else /* DFmode */
1543 {
1544 /* Accepts Dx regs directly by insns. */
1545 emit_insn (gen_cmpdfpx_raw (x, y));
1546 }
1547
1548 if (mode != CC_FPXmode)
f7df4a84 1549 emit_insn (gen_rtx_SET (cc_reg,
526b7aee
SV
1550 gen_rtx_COMPARE (mode,
1551 gen_rtx_REG (CC_FPXmode, 61),
1552 const0_rtx)));
1553 }
1554 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
1555 {
1556 rtx op0 = gen_rtx_REG (cmode, 0);
1557 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
1558
1559 switch (code)
1560 {
1561 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
1562 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1563 break;
1564 case LT: case UNGE: case LE: case UNGT:
1565 code = swap_condition (code);
1566 tmp = x;
1567 x = y;
1568 y = tmp;
1569 break;
1570 default:
1571 gcc_unreachable ();
1572 }
1573 if (currently_expanding_to_rtl)
1574 {
1575 emit_move_insn (op0, x);
1576 emit_move_insn (op1, y);
1577 }
1578 else
1579 {
1580 gcc_assert (rtx_equal_p (op0, x));
1581 gcc_assert (rtx_equal_p (op1, y));
1582 }
1583 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
1584 }
1585 else
f7df4a84 1586 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
526b7aee
SV
1587 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
1588}
1589
1590/* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
1591 We assume the value can be either signed or unsigned. */
1592
1593bool
1594arc_double_limm_p (rtx value)
1595{
1596 HOST_WIDE_INT low, high;
1597
1598 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
1599
1600 if (TARGET_DPFP)
1601 return true;
1602
1603 low = CONST_DOUBLE_LOW (value);
1604 high = CONST_DOUBLE_HIGH (value);
1605
1606 if (low & 0x80000000)
1607 {
1608 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
1609 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
1610 == - (unsigned HOST_WIDE_INT) 0x80000000)
1611 && high == -1));
1612 }
1613 else
1614 {
1615 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
1616 }
1617}
1618
1619/* Do any needed setup for a variadic function. For the ARC, we must
1620 create a register parameter block, and then copy any anonymous arguments
1621 in registers to memory.
1622
1623 CUM has not been updated for the last named argument which has type TYPE
1624 and mode MODE, and we rely on this fact. */
1625
1626static void
1627arc_setup_incoming_varargs (cumulative_args_t args_so_far,
ef4bddc2 1628 machine_mode mode, tree type,
526b7aee
SV
1629 int *pretend_size, int no_rtl)
1630{
1631 int first_anon_arg;
1632 CUMULATIVE_ARGS next_cum;
1633
1634 /* We must treat `__builtin_va_alist' as an anonymous arg. */
1635
1636 next_cum = *get_cumulative_args (args_so_far);
1637 arc_function_arg_advance (pack_cumulative_args (&next_cum), mode, type, 1);
1638 first_anon_arg = next_cum;
1639
1640 if (first_anon_arg < MAX_ARC_PARM_REGS)
1641 {
1642 /* First anonymous (unnamed) argument is in a reg. */
1643
1644 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
1645 int first_reg_offset = first_anon_arg;
1646
1647 if (!no_rtl)
1648 {
1649 rtx regblock
1650 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
1651 FIRST_PARM_OFFSET (0)));
1652 move_block_from_reg (first_reg_offset, regblock,
1653 MAX_ARC_PARM_REGS - first_reg_offset);
1654 }
1655
1656 *pretend_size
1657 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
1658 }
1659}
1660
1661/* Cost functions. */
1662
1663/* Provide the costs of an addressing mode that contains ADDR.
1664 If ADDR is not a valid address, its cost is irrelevant. */
1665
1666int
ef4bddc2 1667arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
526b7aee
SV
1668{
1669 switch (GET_CODE (addr))
1670 {
1671 case REG :
1672 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1;
1673 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
1674 case PRE_MODIFY: case POST_MODIFY:
1675 return !speed;
1676
1677 case LABEL_REF :
1678 case SYMBOL_REF :
1679 case CONST :
1680 /* Most likely needs a LIMM. */
1681 return COSTS_N_INSNS (1);
1682
1683 case PLUS :
1684 {
1685 register rtx plus0 = XEXP (addr, 0);
1686 register rtx plus1 = XEXP (addr, 1);
1687
1688 if (GET_CODE (plus0) != REG
1689 && (GET_CODE (plus0) != MULT
1690 || !CONST_INT_P (XEXP (plus0, 1))
1691 || (INTVAL (XEXP (plus0, 1)) != 2
1692 && INTVAL (XEXP (plus0, 1)) != 4)))
1693 break;
1694
1695 switch (GET_CODE (plus1))
1696 {
1697 case CONST_INT :
1698 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
1699 ? COSTS_N_INSNS (1)
1700 : speed
1701 ? 0
1702 : (satisfies_constraint_Rcq (plus0)
1703 && satisfies_constraint_O (plus1))
1704 ? 0
1705 : 1);
1706 case REG:
1707 return (speed < 1 ? 0
1708 : (satisfies_constraint_Rcq (plus0)
1709 && satisfies_constraint_Rcq (plus1))
1710 ? 0 : 1);
1711 case CONST :
1712 case SYMBOL_REF :
1713 case LABEL_REF :
1714 return COSTS_N_INSNS (1);
1715 default:
1716 break;
1717 }
1718 break;
1719 }
1720 default:
1721 break;
1722 }
1723
1724 return 4;
1725}
1726
1727/* Emit instruction X with the frame related bit set. */
1728
1729static rtx
1730frame_insn (rtx x)
1731{
1732 x = emit_insn (x);
1733 RTX_FRAME_RELATED_P (x) = 1;
1734 return x;
1735}
1736
1737/* Emit a frame insn to move SRC to DST. */
1738
1739static rtx
1740frame_move (rtx dst, rtx src)
1741{
f7df4a84 1742 return frame_insn (gen_rtx_SET (dst, src));
526b7aee
SV
1743}
1744
1745/* Like frame_move, but add a REG_INC note for REG if ADDR contains an
1746 auto increment address, or is zero. */
1747
1748static rtx
1749frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
1750{
1751 rtx insn = frame_move (dst, src);
1752
1753 if (!addr
1754 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
1755 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
1756 add_reg_note (insn, REG_INC, reg);
1757 return insn;
1758}
1759
1760/* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
1761
1762static rtx
1763frame_add (rtx reg, HOST_WIDE_INT offset)
1764{
1765 gcc_assert ((offset & 0x3) == 0);
1766 if (!offset)
1767 return NULL_RTX;
1768 return frame_move (reg, plus_constant (Pmode, reg, offset));
1769}
1770
1771/* Emit a frame insn which adjusts stack pointer by OFFSET. */
1772
1773static rtx
1774frame_stack_add (HOST_WIDE_INT offset)
1775{
1776 return frame_add (stack_pointer_rtx, offset);
1777}
1778
1779/* Traditionally, we push saved registers first in the prologue,
1780 then we allocate the rest of the frame - and reverse in the epilogue.
1781 This has still its merits for ease of debugging, or saving code size
1782 or even execution time if the stack frame is so large that some accesses
1783 can't be encoded anymore with offsets in the instruction code when using
1784 a different scheme.
1785 Also, it would be a good starting point if we got instructions to help
1786 with register save/restore.
1787
1788 However, often stack frames are small, and the pushing / popping has
1789 some costs:
1790 - the stack modification prevents a lot of scheduling.
1791 - frame allocation / deallocation needs extra instructions.
1792 - unless we know that we compile ARC700 user code, we need to put
1793 a memory barrier after frame allocation / before deallocation to
1794 prevent interrupts clobbering our data in the frame.
1795 In particular, we don't have any such guarantees for library functions,
1796 which tend to, on the other hand, to have small frames.
1797
1798 Thus, for small frames, we'd like to use a different scheme:
1799 - The frame is allocated in full with the first prologue instruction,
1800 and deallocated in full with the last epilogue instruction.
1801 Thus, the instructions in-betwen can be freely scheduled.
1802 - If the function has no outgoing arguments on the stack, we can allocate
1803 one register save slot at the top of the stack. This register can then
1804 be saved simultanously with frame allocation, and restored with
1805 frame deallocation.
1806 This register can be picked depending on scheduling considerations,
1807 although same though should go into having some set of registers
1808 to be potentially lingering after a call, and others to be available
1809 immediately - i.e. in the absence of interprocedual optimization, we
1810 can use an ABI-like convention for register allocation to reduce
1811 stalls after function return. */
1812/* Function prologue/epilogue handlers. */
1813
1814/* ARCompact stack frames look like:
1815
1816 Before call After call
1817 high +-----------------------+ +-----------------------+
1818 mem | reg parm save area | | reg parm save area |
1819 | only created for | | only created for |
1820 | variable arg fns | | variable arg fns |
1821 AP +-----------------------+ +-----------------------+
1822 | return addr register | | return addr register |
1823 | (if required) | | (if required) |
1824 +-----------------------+ +-----------------------+
1825 | | | |
1826 | reg save area | | reg save area |
1827 | | | |
1828 +-----------------------+ +-----------------------+
1829 | frame pointer | | frame pointer |
1830 | (if required) | | (if required) |
1831 FP +-----------------------+ +-----------------------+
1832 | | | |
1833 | local/temp variables | | local/temp variables |
1834 | | | |
1835 +-----------------------+ +-----------------------+
1836 | | | |
1837 | arguments on stack | | arguments on stack |
1838 | | | |
1839 SP +-----------------------+ +-----------------------+
1840 | reg parm save area |
1841 | only created for |
1842 | variable arg fns |
1843 AP +-----------------------+
1844 | return addr register |
1845 | (if required) |
1846 +-----------------------+
1847 | |
1848 | reg save area |
1849 | |
1850 +-----------------------+
1851 | frame pointer |
1852 | (if required) |
1853 FP +-----------------------+
1854 | |
1855 | local/temp variables |
1856 | |
1857 +-----------------------+
1858 | |
1859 | arguments on stack |
1860 low | |
1861 mem SP +-----------------------+
1862
1863Notes:
18641) The "reg parm save area" does not exist for non variable argument fns.
1865 The "reg parm save area" can be eliminated completely if we created our
1866 own va-arc.h, but that has tradeoffs as well (so it's not done). */
1867
1868/* Structure to be filled in by arc_compute_frame_size with register
1869 save masks, and offsets for the current function. */
6cdfeeb4 1870struct GTY (()) arc_frame_info
526b7aee
SV
1871{
1872 unsigned int total_size; /* # bytes that the entire frame takes up. */
1873 unsigned int extra_size; /* # bytes of extra stuff. */
1874 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
1875 unsigned int args_size; /* # bytes that outgoing arguments take up. */
1876 unsigned int reg_size; /* # bytes needed to store regs. */
1877 unsigned int var_size; /* # bytes that variables take up. */
1878 unsigned int reg_offset; /* Offset from new sp to store regs. */
1879 unsigned int gmask; /* Mask of saved gp registers. */
1880 int initialized; /* Nonzero if frame size already calculated. */
1881 short millicode_start_reg;
1882 short millicode_end_reg;
1883 bool save_return_addr;
1884};
1885
1886/* Defining data structures for per-function information. */
1887
1888typedef struct GTY (()) machine_function
1889{
1890 enum arc_function_type fn_type;
1891 struct arc_frame_info frame_info;
1892 /* To keep track of unalignment caused by short insns. */
1893 int unalign;
1894 int force_short_suffix; /* Used when disgorging return delay slot insns. */
1895 const char *size_reason;
1896 struct arc_ccfsm ccfsm_current;
1897 /* Map from uid to ccfsm state during branch shortening. */
1898 rtx ccfsm_current_insn;
1899 char arc_reorg_started;
1900 char prescan_initialized;
1901} machine_function;
1902
1903/* Type of function DECL.
1904
1905 The result is cached. To reset the cache at the end of a function,
1906 call with DECL = NULL_TREE. */
1907
1908enum arc_function_type
1909arc_compute_function_type (struct function *fun)
1910{
1911 tree decl = fun->decl;
1912 tree a;
1913 enum arc_function_type fn_type = fun->machine->fn_type;
1914
1915 if (fn_type != ARC_FUNCTION_UNKNOWN)
1916 return fn_type;
1917
1918 /* Assume we have a normal function (not an interrupt handler). */
1919 fn_type = ARC_FUNCTION_NORMAL;
1920
1921 /* Now see if this is an interrupt handler. */
1922 for (a = DECL_ATTRIBUTES (decl);
1923 a;
1924 a = TREE_CHAIN (a))
1925 {
1926 tree name = TREE_PURPOSE (a), args = TREE_VALUE (a);
1927
1928 if (name == get_identifier ("interrupt")
1929 && list_length (args) == 1
1930 && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1931 {
1932 tree value = TREE_VALUE (args);
1933
1934 if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
1935 fn_type = ARC_FUNCTION_ILINK1;
1936 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
1937 fn_type = ARC_FUNCTION_ILINK2;
1938 else
1939 gcc_unreachable ();
1940 break;
1941 }
1942 }
1943
1944 return fun->machine->fn_type = fn_type;
1945}
1946
1947#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
1948#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
1949
1950/* Tell prologue and epilogue if register REGNO should be saved / restored.
1951 The return address and frame pointer are treated separately.
1952 Don't consider them here.
1953 Addition for pic: The gp register needs to be saved if the current
1954 function changes it to access gotoff variables.
1955 FIXME: This will not be needed if we used some arbitrary register
1956 instead of r26.
1957*/
1958#define MUST_SAVE_REGISTER(regno, interrupt_p) \
1959(((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
1960 && (df_regs_ever_live_p (regno) && (!call_used_regs[regno] || interrupt_p))) \
1961 || (flag_pic && crtl->uses_pic_offset_table \
1962 && regno == PIC_OFFSET_TABLE_REGNUM) )
1963
1964#define MUST_SAVE_RETURN_ADDR \
1965 (cfun->machine->frame_info.save_return_addr)
1966
1967/* Return non-zero if there are registers to be saved or loaded using
1968 millicode thunks. We can only use consecutive sequences starting
1969 with r13, and not going beyond r25.
1970 GMASK is a bitmask of registers to save. This function sets
1971 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
1972 of registers to be saved / restored with a millicode call. */
1973
1974static int
1975arc_compute_millicode_save_restore_regs (unsigned int gmask,
1976 struct arc_frame_info *frame)
1977{
1978 int regno;
1979
1980 int start_reg = 13, end_reg = 25;
1981
1982 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
1983 regno++;
1984 end_reg = regno - 1;
1985 /* There is no point in using millicode thunks if we don't save/restore
1986 at least three registers. For non-leaf functions we also have the
1987 blink restore. */
1988 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
1989 {
1990 frame->millicode_start_reg = 13;
1991 frame->millicode_end_reg = regno - 1;
1992 return 1;
1993 }
1994 return 0;
1995}
1996
1997/* Return the bytes needed to compute the frame pointer from the current
1998 stack pointer.
1999
2000 SIZE is the size needed for local variables. */
2001
2002unsigned int
2003arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */
2004{
2005 int regno;
2006 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2007 unsigned int reg_size, reg_offset;
2008 unsigned int gmask;
2009 enum arc_function_type fn_type;
2010 int interrupt_p;
2011 struct arc_frame_info *frame_info = &cfun->machine->frame_info;
2012
2013 size = ARC_STACK_ALIGN (size);
2014
2015 /* 1) Size of locals and temporaries */
2016 var_size = size;
2017
2018 /* 2) Size of outgoing arguments */
2019 args_size = crtl->outgoing_args_size;
2020
2021 /* 3) Calculate space needed for saved registers.
2022 ??? We ignore the extension registers for now. */
2023
2024 /* See if this is an interrupt handler. Call used registers must be saved
2025 for them too. */
2026
2027 reg_size = 0;
2028 gmask = 0;
2029 fn_type = arc_compute_function_type (cfun);
2030 interrupt_p = ARC_INTERRUPT_P (fn_type);
2031
2032 for (regno = 0; regno <= 31; regno++)
2033 {
2034 if (MUST_SAVE_REGISTER (regno, interrupt_p))
2035 {
2036 reg_size += UNITS_PER_WORD;
2037 gmask |= 1 << regno;
2038 }
2039 }
2040
2041 /* 4) Space for back trace data structure.
2042 <return addr reg size> (if required) + <fp size> (if required). */
2043 frame_info->save_return_addr
2044 = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM));
2045 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2046 if (optimize_size && !TARGET_NO_MILLICODE_THUNK_SET)
2047 {
2048 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2049 frame_info->save_return_addr = true;
2050 }
2051
2052 extra_size = 0;
2053 if (MUST_SAVE_RETURN_ADDR)
2054 extra_size = 4;
2055 if (frame_pointer_needed)
2056 extra_size += 4;
2057
2058 /* 5) Space for variable arguments passed in registers */
2059 pretend_size = crtl->args.pretend_args_size;
2060
2061 /* Ensure everything before the locals is aligned appropriately. */
2062 {
2063 unsigned int extra_plus_reg_size;
2064 unsigned int extra_plus_reg_size_aligned;
2065
2066 extra_plus_reg_size = extra_size + reg_size;
2067 extra_plus_reg_size_aligned = ARC_STACK_ALIGN(extra_plus_reg_size);
2068 reg_size = extra_plus_reg_size_aligned - extra_size;
2069 }
2070
2071 /* Compute total frame size. */
2072 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2073
2074 total_size = ARC_STACK_ALIGN (total_size);
2075
2076 /* Compute offset of register save area from stack pointer:
fb155425 2077 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
526b7aee
SV
2078 */
2079 reg_offset = (total_size - (pretend_size + reg_size + extra_size)
2080 + (frame_pointer_needed ? 4 : 0));
2081
2082 /* Save computed information. */
2083 frame_info->total_size = total_size;
2084 frame_info->extra_size = extra_size;
2085 frame_info->pretend_size = pretend_size;
2086 frame_info->var_size = var_size;
2087 frame_info->args_size = args_size;
2088 frame_info->reg_size = reg_size;
2089 frame_info->reg_offset = reg_offset;
2090 frame_info->gmask = gmask;
2091 frame_info->initialized = reload_completed;
2092
2093 /* Ok, we're done. */
2094 return total_size;
2095}
2096
2097/* Common code to save/restore registers. */
2098/* BASE_REG is the base register to use for addressing and to adjust.
2099 GMASK is a bitmask of general purpose registers to save/restore.
2100 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2101 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2102 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2103 zeroed. */
2104
2105static void
2106arc_save_restore (rtx base_reg,
2107 unsigned int gmask, int epilogue_p, int *first_offset)
2108{
2109 unsigned int offset = 0;
2110 int regno;
2111 struct arc_frame_info *frame = &cfun->machine->frame_info;
2112 rtx sibthunk_insn = NULL_RTX;
2113
2114 if (gmask)
2115 {
2116 /* Millicode thunks implementation:
2117 Generates calls to millicodes for registers starting from r13 to r25
2118 Present Limitations:
2119 - Only one range supported. The remaining regs will have the ordinary
2120 st and ld instructions for store and loads. Hence a gmask asking
2121 to store r13-14, r16-r25 will only generate calls to store and
2122 load r13 to r14 while store and load insns will be generated for
2123 r16 to r25 in the prologue and epilogue respectively.
2124
2125 - Presently library only supports register ranges starting from r13.
2126 */
2127 if (epilogue_p == 2 || frame->millicode_end_reg > 14)
2128 {
2129 int start_call = frame->millicode_start_reg;
2130 int end_call = frame->millicode_end_reg;
2131 int n_regs = end_call - start_call + 1;
2132 int i = 0, r, off = 0;
2133 rtx insn;
2134 rtx ret_addr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
2135
2136 if (*first_offset)
2137 {
2138 /* "reg_size" won't be more than 127 . */
6ace1161 2139 gcc_assert (epilogue_p || abs (*first_offset) <= 127);
526b7aee
SV
2140 frame_add (base_reg, *first_offset);
2141 *first_offset = 0;
2142 }
2143 insn = gen_rtx_PARALLEL
2144 (VOIDmode, rtvec_alloc ((epilogue_p == 2) + n_regs + 1));
2145 if (epilogue_p == 2)
2146 i += 2;
2147 else
2148 XVECEXP (insn, 0, n_regs) = gen_rtx_CLOBBER (VOIDmode, ret_addr);
2149 for (r = start_call; r <= end_call; r++, off += UNITS_PER_WORD, i++)
2150 {
2151 rtx reg = gen_rtx_REG (SImode, r);
2152 rtx mem
2153 = gen_frame_mem (SImode, plus_constant (Pmode, base_reg, off));
2154
2155 if (epilogue_p)
f7df4a84 2156 XVECEXP (insn, 0, i) = gen_rtx_SET (reg, mem);
526b7aee 2157 else
f7df4a84 2158 XVECEXP (insn, 0, i) = gen_rtx_SET (mem, reg);
526b7aee
SV
2159 gmask = gmask & ~(1L << r);
2160 }
2161 if (epilogue_p == 2)
2162 sibthunk_insn = insn;
2163 else
2164 frame_insn (insn);
2165 offset += off;
2166 }
2167
2168 for (regno = 0; regno <= 31; regno++)
2169 {
2170 if ((gmask & (1L << regno)) != 0)
2171 {
2172 rtx reg = gen_rtx_REG (SImode, regno);
2173 rtx addr, mem;
2174
2175 if (*first_offset)
2176 {
2177 gcc_assert (!offset);
2178 addr = plus_constant (Pmode, base_reg, *first_offset);
2179 addr = gen_rtx_PRE_MODIFY (Pmode, base_reg, addr);
2180 *first_offset = 0;
2181 }
2182 else
2183 {
2184 gcc_assert (SMALL_INT (offset));
2185 addr = plus_constant (Pmode, base_reg, offset);
2186 }
2187 mem = gen_frame_mem (SImode, addr);
2188 if (epilogue_p)
2189 frame_move_inc (reg, mem, base_reg, addr);
2190 else
2191 frame_move_inc (mem, reg, base_reg, addr);
2192 offset += UNITS_PER_WORD;
2193 } /* if */
2194 } /* for */
2195 }/* if */
2196 if (sibthunk_insn)
2197 {
2198 rtx r12 = gen_rtx_REG (Pmode, 12);
2199
f7df4a84 2200 frame_insn (gen_rtx_SET (r12, GEN_INT (offset)));
526b7aee
SV
2201 XVECEXP (sibthunk_insn, 0, 0) = ret_rtx;
2202 XVECEXP (sibthunk_insn, 0, 1)
f7df4a84 2203 = gen_rtx_SET (stack_pointer_rtx,
526b7aee
SV
2204 gen_rtx_PLUS (Pmode, stack_pointer_rtx, r12));
2205 sibthunk_insn = emit_jump_insn (sibthunk_insn);
2206 RTX_FRAME_RELATED_P (sibthunk_insn) = 1;
2207 }
2208} /* arc_save_restore */
2209
2210
2211int arc_return_address_regs[4]
2212 = {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM};
2213
2214/* Set up the stack and frame pointer (if desired) for the function. */
2215
2216void
2217arc_expand_prologue (void)
2218{
2219 int size = get_frame_size ();
2220 unsigned int gmask = cfun->machine->frame_info.gmask;
2221 /* unsigned int frame_pointer_offset;*/
2222 unsigned int frame_size_to_allocate;
2223 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2224 Change the stack layout so that we rather store a high register with the
2225 PRE_MODIFY, thus enabling more short insn generation.) */
2226 int first_offset = 0;
2227
2228 size = ARC_STACK_ALIGN (size);
2229
2230 /* Compute/get total frame size. */
2231 size = (!cfun->machine->frame_info.initialized
2232 ? arc_compute_frame_size (size)
2233 : cfun->machine->frame_info.total_size);
2234
2235 if (flag_stack_usage_info)
2236 current_function_static_stack_size = size;
2237
2238 /* Keep track of frame size to be allocated. */
2239 frame_size_to_allocate = size;
2240
2241 /* These cases shouldn't happen. Catch them now. */
2242 gcc_assert (!(size == 0 && gmask));
2243
2244 /* Allocate space for register arguments if this is a variadic function. */
2245 if (cfun->machine->frame_info.pretend_size != 0)
2246 {
2247 /* Ensure pretend_size is maximum of 8 * word_size. */
2248 gcc_assert (cfun->machine->frame_info.pretend_size <= 32);
2249
2250 frame_stack_add (-(HOST_WIDE_INT)cfun->machine->frame_info.pretend_size);
2251 frame_size_to_allocate -= cfun->machine->frame_info.pretend_size;
2252 }
2253
2254 /* The home-grown ABI says link register is saved first. */
2255 if (MUST_SAVE_RETURN_ADDR)
2256 {
2257 rtx ra = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
2258 rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2259
2260 frame_move_inc (mem, ra, stack_pointer_rtx, 0);
2261 frame_size_to_allocate -= UNITS_PER_WORD;
2262
2263 } /* MUST_SAVE_RETURN_ADDR */
2264
2265 /* Save any needed call-saved regs (and call-used if this is an
2266 interrupt handler) for ARCompact ISA. */
2267 if (cfun->machine->frame_info.reg_size)
2268 {
2269 first_offset = -cfun->machine->frame_info.reg_size;
2270 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
2271 arc_save_restore (stack_pointer_rtx, gmask, 0, &first_offset);
2272 frame_size_to_allocate -= cfun->machine->frame_info.reg_size;
2273 }
2274
2275
2276 /* Save frame pointer if needed. */
2277 if (frame_pointer_needed)
2278 {
2279 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2280 GEN_INT (-UNITS_PER_WORD + first_offset));
2281 rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_MODIFY (Pmode,
2282 stack_pointer_rtx,
2283 addr));
2284 frame_move_inc (mem, frame_pointer_rtx, stack_pointer_rtx, 0);
2285 frame_size_to_allocate -= UNITS_PER_WORD;
2286 first_offset = 0;
2287 frame_move (frame_pointer_rtx, stack_pointer_rtx);
2288 }
2289
2290 /* ??? We don't handle the case where the saved regs are more than 252
2291 bytes away from sp. This can be handled by decrementing sp once, saving
2292 the regs, and then decrementing it again. The epilogue doesn't have this
2293 problem as the `ld' insn takes reg+limm values (though it would be more
2294 efficient to avoid reg+limm). */
2295
2296 frame_size_to_allocate -= first_offset;
2297 /* Allocate the stack frame. */
2298 if (frame_size_to_allocate > 0)
2299 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
2300
2301 /* Setup the gp register, if needed. */
2302 if (crtl->uses_pic_offset_table)
2303 arc_finalize_pic ();
2304}
2305
2306/* Do any necessary cleanup after a function to restore stack, frame,
2307 and regs. */
2308
2309void
2310arc_expand_epilogue (int sibcall_p)
2311{
2312 int size = get_frame_size ();
2313 enum arc_function_type fn_type = arc_compute_function_type (cfun);
2314
2315 size = ARC_STACK_ALIGN (size);
2316 size = (!cfun->machine->frame_info.initialized
2317 ? arc_compute_frame_size (size)
2318 : cfun->machine->frame_info.total_size);
2319
5719867d
JR
2320 unsigned int pretend_size = cfun->machine->frame_info.pretend_size;
2321 unsigned int frame_size;
2322 unsigned int size_to_deallocate;
2323 int restored;
2324 int can_trust_sp_p = !cfun->calls_alloca;
2325 int first_offset = 0;
2326 int millicode_p = cfun->machine->frame_info.millicode_end_reg > 0;
526b7aee 2327
5719867d 2328 size_to_deallocate = size;
526b7aee 2329
5719867d
JR
2330 frame_size = size - (pretend_size +
2331 cfun->machine->frame_info.reg_size +
2332 cfun->machine->frame_info.extra_size);
526b7aee 2333
5719867d
JR
2334 /* ??? There are lots of optimizations that can be done here.
2335 EG: Use fp to restore regs if it's closer.
2336 Maybe in time we'll do them all. For now, always restore regs from
2337 sp, but don't restore sp if we don't have to. */
526b7aee 2338
5719867d
JR
2339 if (!can_trust_sp_p)
2340 gcc_assert (frame_pointer_needed);
526b7aee 2341
5719867d
JR
2342 /* Restore stack pointer to the beginning of saved register area for
2343 ARCompact ISA. */
2344 if (frame_size)
2345 {
526b7aee 2346 if (frame_pointer_needed)
5719867d
JR
2347 frame_move (stack_pointer_rtx, frame_pointer_rtx);
2348 else
2349 first_offset = frame_size;
2350 size_to_deallocate -= frame_size;
2351 }
2352 else if (!can_trust_sp_p)
2353 frame_stack_add (-frame_size);
526b7aee 2354
526b7aee 2355
5719867d
JR
2356 /* Restore any saved registers. */
2357 if (frame_pointer_needed)
2358 {
2359 rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
2360
2361 frame_move_inc (frame_pointer_rtx, gen_frame_mem (Pmode, addr),
2362 stack_pointer_rtx, 0);
2363 size_to_deallocate -= UNITS_PER_WORD;
2364 }
2365
2366 /* Load blink after the calls to thunk calls in case of optimize size. */
2367 if (millicode_p)
2368 {
2369 int sibthunk_p = (!sibcall_p
2370 && fn_type == ARC_FUNCTION_NORMAL
2371 && !cfun->machine->frame_info.pretend_size);
2372
2373 gcc_assert (!(cfun->machine->frame_info.gmask
2374 & (FRAME_POINTER_MASK | RETURN_ADDR_MASK)));
2375 arc_save_restore (stack_pointer_rtx,
2376 cfun->machine->frame_info.gmask,
2377 1 + sibthunk_p, &first_offset);
2378 if (sibthunk_p)
2379 goto epilogue_done;
2380 }
2381 /* If we are to restore registers, and first_offset would require
2382 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
2383 fast add to the stack pointer, do this now. */
2384 if ((!SMALL_INT (first_offset)
2385 && cfun->machine->frame_info.gmask
2386 && ((TARGET_ARC700 && !optimize_size)
2387 ? first_offset <= 0x800
2388 : satisfies_constraint_C2a (GEN_INT (first_offset))))
2389 /* Also do this if we have both gprs and return
2390 address to restore, and they both would need a LIMM. */
2391 || (MUST_SAVE_RETURN_ADDR
2392 && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2)
2393 && cfun->machine->frame_info.gmask))
2394 {
2395 frame_stack_add (first_offset);
2396 first_offset = 0;
2397 }
2398 if (MUST_SAVE_RETURN_ADDR)
2399 {
2400 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
2401 int ra_offs = cfun->machine->frame_info.reg_size + first_offset;
2402 rtx addr = plus_constant (Pmode, stack_pointer_rtx, ra_offs);
2403
2404 /* If the load of blink would need a LIMM, but we can add
2405 the offset quickly to sp, do the latter. */
2406 if (!SMALL_INT (ra_offs >> 2)
2407 && !cfun->machine->frame_info.gmask
2408 && ((TARGET_ARC700 && !optimize_size)
2409 ? ra_offs <= 0x800
2410 : satisfies_constraint_C2a (GEN_INT (ra_offs))))
526b7aee 2411 {
5719867d
JR
2412 size_to_deallocate -= ra_offs - first_offset;
2413 first_offset = 0;
2414 frame_stack_add (ra_offs);
2415 ra_offs = 0;
2416 addr = stack_pointer_rtx;
526b7aee 2417 }
5719867d
JR
2418 /* See if we can combine the load of the return address with the
2419 final stack adjustment.
2420 We need a separate load if there are still registers to
2421 restore. We also want a separate load if the combined insn
2422 would need a limm, but a separate load doesn't. */
2423 if (ra_offs
2424 && !cfun->machine->frame_info.gmask
2425 && (SMALL_INT (ra_offs) || !SMALL_INT (ra_offs >> 2)))
526b7aee 2426 {
5719867d 2427 addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, addr);
526b7aee 2428 first_offset = 0;
5719867d 2429 size_to_deallocate -= cfun->machine->frame_info.reg_size;
526b7aee 2430 }
5719867d 2431 else if (!ra_offs && size_to_deallocate == UNITS_PER_WORD)
526b7aee 2432 {
5719867d
JR
2433 addr = gen_rtx_POST_INC (Pmode, addr);
2434 size_to_deallocate = 0;
526b7aee 2435 }
5719867d
JR
2436 frame_move_inc (ra, gen_frame_mem (Pmode, addr), stack_pointer_rtx, addr);
2437 }
526b7aee 2438
5719867d
JR
2439 if (!millicode_p)
2440 {
2441 if (cfun->machine->frame_info.reg_size)
2442 arc_save_restore (stack_pointer_rtx,
2443 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
2444 cfun->machine->frame_info.gmask
2445 & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 1, &first_offset);
2446 }
526b7aee
SV
2447
2448
5719867d
JR
2449 /* The rest of this function does the following:
2450 ARCompact : handle epilogue_delay, restore sp (phase-2), return
2451 */
526b7aee 2452
5719867d
JR
2453 /* Keep track of how much of the stack pointer we've restored.
2454 It makes the following a lot more readable. */
2455 size_to_deallocate += first_offset;
2456 restored = size - size_to_deallocate;
526b7aee 2457
5719867d
JR
2458 if (size > restored)
2459 frame_stack_add (size - restored);
2460 /* Emit the return instruction. */
2461 if (sibcall_p == FALSE)
2462 emit_jump_insn (gen_simple_return ());
526b7aee
SV
2463 epilogue_done:
2464 if (!TARGET_EPILOGUE_CFI)
2465 {
b32d5189 2466 rtx_insn *insn;
526b7aee
SV
2467
2468 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2469 RTX_FRAME_RELATED_P (insn) = 0;
2470 }
2471}
2472
2473/* Return the offset relative to the stack pointer where the return address
2474 is stored, or -1 if it is not stored. */
2475
2476int
2477arc_return_slot_offset ()
2478{
2479 struct arc_frame_info *afi = &cfun->machine->frame_info;
2480
2481 return (afi->save_return_addr
2482 ? afi->total_size - afi->pretend_size - afi->extra_size : -1);
2483}
2484
2485/* PIC */
2486
2487/* Emit special PIC prologues and epilogues. */
2488/* If the function has any GOTOFF relocations, then the GOTBASE
2489 register has to be setup in the prologue
2490 The instruction needed at the function start for setting up the
2491 GOTBASE register is
2492 add rdest, pc,
2493 ----------------------------------------------------------
2494 The rtl to be emitted for this should be:
2495 set (reg basereg)
2496 (plus (reg pc)
2497 (const (unspec (symref _DYNAMIC) 3)))
2498 ---------------------------------------------------------- */
2499
2500static void
2501arc_finalize_pic (void)
2502{
2503 rtx pat;
2504 rtx baseptr_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
2505
2506 if (crtl->uses_pic_offset_table == 0)
2507 return;
2508
2509 gcc_assert (flag_pic != 0);
2510
2511 pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC");
2512 pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, pat), ARC_UNSPEC_GOT);
2513 pat = gen_rtx_CONST (Pmode, pat);
2514
f7df4a84 2515 pat = gen_rtx_SET (baseptr_rtx, pat);
526b7aee
SV
2516
2517 emit_insn (pat);
2518}
2519\f
2520/* !TARGET_BARREL_SHIFTER support. */
2521/* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
2522 kind of shift. */
2523
2524void
2525emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
2526{
2527 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
2528 rtx pat
2529 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop)
2530 (op0, op1, op2, shift));
2531 emit_insn (pat);
2532}
2533
2534/* Output the assembler code for doing a shift.
2535 We go to a bit of trouble to generate efficient code as the ARC601 only has
2536 single bit shifts. This is taken from the h8300 port. We only have one
2537 mode of shifting and can't access individual bytes like the h8300 can, so
2538 this is greatly simplified (at the expense of not generating hyper-
2539 efficient code).
2540
2541 This function is not used if the variable shift insns are present. */
2542
2543/* FIXME: This probably can be done using a define_split in arc.md.
2544 Alternately, generate rtx rather than output instructions. */
2545
2546const char *
2547output_shift (rtx *operands)
2548{
2549 /* static int loopend_lab;*/
2550 rtx shift = operands[3];
ef4bddc2 2551 machine_mode mode = GET_MODE (shift);
526b7aee
SV
2552 enum rtx_code code = GET_CODE (shift);
2553 const char *shift_one;
2554
2555 gcc_assert (mode == SImode);
2556
2557 switch (code)
2558 {
2559 case ASHIFT: shift_one = "add %0,%1,%1"; break;
2560 case ASHIFTRT: shift_one = "asr %0,%1"; break;
2561 case LSHIFTRT: shift_one = "lsr %0,%1"; break;
2562 default: gcc_unreachable ();
2563 }
2564
2565 if (GET_CODE (operands[2]) != CONST_INT)
2566 {
2567 output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
2568 goto shiftloop;
2569 }
2570 else
2571 {
2572 int n;
2573
2574 n = INTVAL (operands[2]);
2575
2576 /* Only consider the lower 5 bits of the shift count. */
2577 n = n & 0x1f;
2578
2579 /* First see if we can do them inline. */
2580 /* ??? We could get better scheduling & shorter code (using short insns)
2581 by using splitters. Alas, that'd be even more verbose. */
2582 if (code == ASHIFT && n <= 9 && n > 2
2583 && dest_reg_operand (operands[4], SImode))
2584 {
2585 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
2586 for (n -=3 ; n >= 3; n -= 3)
2587 output_asm_insn ("add3 %0,%4,%0", operands);
2588 if (n == 2)
2589 output_asm_insn ("add2 %0,%4,%0", operands);
2590 else if (n)
2591 output_asm_insn ("add %0,%0,%0", operands);
2592 }
2593 else if (n <= 4)
2594 {
2595 while (--n >= 0)
2596 {
2597 output_asm_insn (shift_one, operands);
2598 operands[1] = operands[0];
2599 }
2600 }
2601 /* See if we can use a rotate/and. */
2602 else if (n == BITS_PER_WORD - 1)
2603 {
2604 switch (code)
2605 {
2606 case ASHIFT :
2607 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
2608 break;
2609 case ASHIFTRT :
2610 /* The ARC doesn't have a rol insn. Use something else. */
2611 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
2612 break;
2613 case LSHIFTRT :
2614 /* The ARC doesn't have a rol insn. Use something else. */
2615 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
2616 break;
2617 default:
2618 break;
2619 }
2620 }
2621 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
2622 {
2623 switch (code)
2624 {
2625 case ASHIFT :
2626 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
2627 break;
2628 case ASHIFTRT :
2629#if 1 /* Need some scheduling comparisons. */
2630 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
2631 "add.f 0,%4,%4\n\trlc %0,%0", operands);
2632#else
2633 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
2634 "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
2635#endif
2636 break;
2637 case LSHIFTRT :
2638#if 1
2639 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
2640 "add.f 0,%4,%4\n\trlc %0,%0", operands);
2641#else
2642 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
2643 "and %0,%0,1\n\trlc %0,%0", operands);
2644#endif
2645 break;
2646 default:
2647 break;
2648 }
2649 }
2650 else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
2651 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
2652 operands);
2653 /* Must loop. */
2654 else
2655 {
2656 operands[2] = GEN_INT (n);
2657 output_asm_insn ("mov.f lp_count, %2", operands);
2658
2659 shiftloop:
2660 {
2661 output_asm_insn ("lpnz\t2f", operands);
2662 output_asm_insn (shift_one, operands);
2663 output_asm_insn ("nop", operands);
2664 fprintf (asm_out_file, "2:\t%s end single insn loop\n",
2665 ASM_COMMENT_START);
2666 }
2667 }
2668 }
2669
2670 return "";
2671}
2672\f
2673/* Nested function support. */
2674
2675/* Directly store VALUE into memory object BLOCK at OFFSET. */
2676
2677static void
2678emit_store_direct (rtx block, int offset, int value)
2679{
2680 emit_insn (gen_store_direct (adjust_address (block, SImode, offset),
2681 force_reg (SImode,
2682 gen_int_mode (value, SImode))));
2683}
2684
2685/* Emit RTL insns to initialize the variable parts of a trampoline.
2686 FNADDR is an RTX for the address of the function's pure code.
2687 CXT is an RTX for the static chain value for the function. */
2688/* With potentially multiple shared objects loaded, and multiple stacks
2689 present for multiple thereds where trampolines might reside, a simple
2690 range check will likely not suffice for the profiler to tell if a callee
2691 is a trampoline. We a speedier check by making the trampoline start at
2692 an address that is not 4-byte aligned.
2693 A trampoline looks like this:
2694
2695 nop_s 0x78e0
2696entry:
2697 ld_s r12,[pcl,12] 0xd403
2698 ld r11,[pcl,12] 0x170c 700b
2699 j_s [r12] 0x7c00
2700 nop_s 0x78e0
2701
2702 The fastest trampoline to execute for trampolines within +-8KB of CTX
2703 would be:
2704 add2 r11,pcl,s12
2705 j [limm] 0x20200f80 limm
2706 and that would also be faster to write to the stack by computing the offset
2707 from CTX to TRAMP at compile time. However, it would really be better to
2708 get rid of the high cost of cache invalidation when generating trampolines,
2709 which requires that the code part of trampolines stays constant, and
2710 additionally either
2711 - making sure that no executable code but trampolines is on the stack,
2712 no icache entries linger for the area of the stack from when before the
2713 stack was allocated, and allocating trampolines in trampoline-only
2714 cache lines
2715 or
2716 - allocate trampolines fram a special pool of pre-allocated trampolines. */
2717
2718static void
2719arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
2720{
2721 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2722
2723 emit_store_direct (tramp, 0, TARGET_BIG_ENDIAN ? 0x78e0d403 : 0xd40378e0);
2724 emit_store_direct (tramp, 4, TARGET_BIG_ENDIAN ? 0x170c700b : 0x700b170c);
2725 emit_store_direct (tramp, 8, TARGET_BIG_ENDIAN ? 0x7c0078e0 : 0x78e07c00);
2726 emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
2727 emit_move_insn (adjust_address (tramp, SImode, 16), cxt);
2728 emit_insn (gen_flush_icache (adjust_address (tramp, SImode, 0)));
2729}
2730
2731/* Allow the profiler to easily distinguish trampolines from normal
2732 functions. */
2733
2734static rtx
2735arc_trampoline_adjust_address (rtx addr)
2736{
2737 return plus_constant (Pmode, addr, 2);
2738}
2739
2740/* This is set briefly to 1 when we output a ".as" address modifer, and then
2741 reset when we output the scaled address. */
2742static int output_scaled = 0;
2743
2744/* Print operand X (an rtx) in assembler syntax to file FILE.
2745 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2746 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2747/* In final.c:output_asm_insn:
2748 'l' : label
2749 'a' : address
2750 'c' : constant address if CONSTANT_ADDRESS_P
2751 'n' : negative
2752 Here:
2753 'Z': log2(x+1)-1
2754 'z': log2
2755 'M': log2(~x)
2756 '#': condbranch delay slot suffix
2757 '*': jump delay slot suffix
2758 '?' : nonjump-insn suffix for conditional execution or short instruction
2759 '!' : jump / call suffix for conditional execution or short instruction
2760 '`': fold constant inside unary o-perator, re-recognize, and emit.
2761 'd'
2762 'D'
2763 'R': Second word
2764 'S'
2765 'B': Branch comparison operand - suppress sda reference
2766 'H': Most significant word
2767 'L': Least significant word
2768 'A': ASCII decimal representation of floating point value
2769 'U': Load/store update or scaling indicator
2770 'V': cache bypass indicator for volatile
2771 'P'
2772 'F'
2773 '^'
2774 'O': Operator
2775 'o': original symbol - no @ prepending. */
2776
2777void
2778arc_print_operand (FILE *file, rtx x, int code)
2779{
2780 switch (code)
2781 {
2782 case 'Z':
2783 if (GET_CODE (x) == CONST_INT)
2784 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
2785 else
2786 output_operand_lossage ("invalid operand to %%Z code");
2787
2788 return;
2789
2790 case 'z':
2791 if (GET_CODE (x) == CONST_INT)
2792 fprintf (file, "%d",exact_log2(INTVAL (x)) );
2793 else
2794 output_operand_lossage ("invalid operand to %%z code");
2795
2796 return;
2797
2798 case 'M':
2799 if (GET_CODE (x) == CONST_INT)
2800 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
2801 else
2802 output_operand_lossage ("invalid operand to %%M code");
2803
2804 return;
2805
2806 case '#' :
2807 /* Conditional branches depending on condition codes.
2808 Note that this is only for branches that were known to depend on
2809 condition codes before delay slot scheduling;
2810 out-of-range brcc / bbit expansions should use '*'.
2811 This distinction is important because of the different
2812 allowable delay slot insns and the output of the delay suffix
2813 for TARGET_AT_DBR_COND_EXEC. */
2814 case '*' :
2815 /* Unconditional branches / branches not depending on condition codes.
2816 This could also be a CALL_INSN.
2817 Output the appropriate delay slot suffix. */
84034c69 2818 if (final_sequence && final_sequence->len () != 1)
526b7aee 2819 {
84034c69
DM
2820 rtx_insn *jump = final_sequence->insn (0);
2821 rtx_insn *delay = final_sequence->insn (1);
526b7aee
SV
2822
2823 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
4654c0cf 2824 if (delay->deleted ())
526b7aee
SV
2825 return;
2826 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
2827 fputs (INSN_FROM_TARGET_P (delay) ? ".d"
2828 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d"
2829 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? ""
2830 : ".nd",
2831 file);
2832 else
2833 fputs (".d", file);
2834 }
2835 return;
2836 case '?' : /* with leading "." */
2837 case '!' : /* without leading "." */
2838 /* This insn can be conditionally executed. See if the ccfsm machinery
2839 says it should be conditionalized.
2840 If it shouldn't, we'll check the compact attribute if this insn
2841 has a short variant, which may be used depending on code size and
2842 alignment considerations. */
2843 if (current_insn_predicate)
2844 arc_ccfsm_current.cc
2845 = get_arc_condition_code (current_insn_predicate);
2846 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current))
2847 {
2848 /* Is this insn in a delay slot sequence? */
2849 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
2850 || current_insn_predicate
68a1a6c0
DM
2851 || CALL_P (final_sequence->insn (0))
2852 || simplejump_p (final_sequence->insn (0)))
526b7aee
SV
2853 {
2854 /* This insn isn't in a delay slot sequence, or conditionalized
2855 independently of its position in a delay slot. */
2856 fprintf (file, "%s%s",
2857 code == '?' ? "." : "",
2858 arc_condition_codes[arc_ccfsm_current.cc]);
2859 /* If this is a jump, there are still short variants. However,
2860 only beq_s / bne_s have the same offset range as b_s,
2861 and the only short conditional returns are jeq_s and jne_s. */
2862 if (code == '!'
2863 && (arc_ccfsm_current.cc == ARC_CC_EQ
2864 || arc_ccfsm_current.cc == ARC_CC_NE
2865 || 0 /* FIXME: check if branch in 7 bit range. */))
2866 output_short_suffix (file);
2867 }
2868 else if (code == '!') /* Jump with delay slot. */
2869 fputs (arc_condition_codes[arc_ccfsm_current.cc], file);
2870 else /* An Instruction in a delay slot of a jump or call. */
2871 {
2872 rtx jump = XVECEXP (final_sequence, 0, 0);
2873 rtx insn = XVECEXP (final_sequence, 0, 1);
2874
2875 /* If the insn is annulled and is from the target path, we need
2876 to inverse the condition test. */
2877 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
2878 {
2879 if (INSN_FROM_TARGET_P (insn))
2880 fprintf (file, "%s%s",
2881 code == '?' ? "." : "",
2882 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]);
2883 else
2884 fprintf (file, "%s%s",
2885 code == '?' ? "." : "",
2886 arc_condition_codes[arc_ccfsm_current.cc]);
2887 if (arc_ccfsm_current.state == 5)
2888 arc_ccfsm_current.state = 0;
2889 }
2890 else
2891 /* This insn is executed for either path, so don't
2892 conditionalize it at all. */
2893 output_short_suffix (file);
2894
2895 }
2896 }
2897 else
2898 output_short_suffix (file);
2899 return;
2900 case'`':
2901 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
2902 gcc_unreachable ();
2903 case 'd' :
2904 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
2905 return;
2906 case 'D' :
2907 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
2908 (get_arc_condition_code (x))],
2909 file);
2910 return;
2911 case 'R' :
2912 /* Write second word of DImode or DFmode reference,
2913 register or memory. */
2914 if (GET_CODE (x) == REG)
2915 fputs (reg_names[REGNO (x)+1], file);
2916 else if (GET_CODE (x) == MEM)
2917 {
2918 fputc ('[', file);
2919
2920 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
2921 PRE_MODIFY, we will have handled the first word already;
2922 For POST_INC / POST_DEC / POST_MODIFY, the access to the
2923 first word will be done later. In either case, the access
2924 to the first word will do the modify, and we only have
2925 to add an offset of four here. */
2926 if (GET_CODE (XEXP (x, 0)) == PRE_INC
2927 || GET_CODE (XEXP (x, 0)) == PRE_DEC
2928 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
2929 || GET_CODE (XEXP (x, 0)) == POST_INC
2930 || GET_CODE (XEXP (x, 0)) == POST_DEC
2931 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
cc8ca59e
JB
2932 output_address (VOIDmode,
2933 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
526b7aee
SV
2934 else if (output_scaled)
2935 {
2936 rtx addr = XEXP (x, 0);
2937 int size = GET_MODE_SIZE (GET_MODE (x));
2938
cc8ca59e
JB
2939 output_address (VOIDmode,
2940 plus_constant (Pmode, XEXP (addr, 0),
526b7aee
SV
2941 ((INTVAL (XEXP (addr, 1)) + 4)
2942 >> (size == 2 ? 1 : 2))));
2943 output_scaled = 0;
2944 }
2945 else
cc8ca59e
JB
2946 output_address (VOIDmode,
2947 plus_constant (Pmode, XEXP (x, 0), 4));
526b7aee
SV
2948 fputc (']', file);
2949 }
2950 else
2951 output_operand_lossage ("invalid operand to %%R code");
2952 return;
2953 case 'S' :
2954 /* FIXME: remove %S option. */
2955 break;
2956 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
2957 if (CONSTANT_P (x))
2958 {
2959 output_addr_const (file, x);
2960 return;
2961 }
2962 break;
2963 case 'H' :
2964 case 'L' :
2965 if (GET_CODE (x) == REG)
2966 {
2967 /* L = least significant word, H = most significant word. */
2968 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
2969 fputs (reg_names[REGNO (x)], file);
2970 else
2971 fputs (reg_names[REGNO (x)+1], file);
2972 }
2973 else if (GET_CODE (x) == CONST_INT
2974 || GET_CODE (x) == CONST_DOUBLE)
2975 {
2976 rtx first, second;
2977
2978 split_double (x, &first, &second);
2979
2980 if((WORDS_BIG_ENDIAN) == 0)
dfca07ea 2981 fprintf (file, "0x%08" PRIx64,
526b7aee
SV
2982 code == 'L' ? INTVAL (first) : INTVAL (second));
2983 else
dfca07ea 2984 fprintf (file, "0x%08" PRIx64,
526b7aee
SV
2985 code == 'L' ? INTVAL (second) : INTVAL (first));
2986
2987
2988 }
2989 else
2990 output_operand_lossage ("invalid operand to %%H/%%L code");
2991 return;
2992 case 'A' :
2993 {
2994 char str[30];
2995
2996 gcc_assert (GET_CODE (x) == CONST_DOUBLE
2997 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
2998
2999 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
3000 fprintf (file, "%s", str);
3001 return;
3002 }
3003 case 'U' :
3004 /* Output a load/store with update indicator if appropriate. */
3005 if (GET_CODE (x) == MEM)
3006 {
3007 rtx addr = XEXP (x, 0);
3008 switch (GET_CODE (addr))
3009 {
3010 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
3011 fputs (".a", file); break;
3012 case POST_INC: case POST_DEC: case POST_MODIFY:
3013 fputs (".ab", file); break;
3014 case PLUS:
3015 /* Are we using a scaled index? */
3016 if (GET_CODE (XEXP (addr, 0)) == MULT)
3017 fputs (".as", file);
3018 /* Can we use a scaled offset? */
3019 else if (CONST_INT_P (XEXP (addr, 1))
3020 && GET_MODE_SIZE (GET_MODE (x)) > 1
3021 && (!(INTVAL (XEXP (addr, 1))
3022 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
3023 /* Does it make a difference? */
3024 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
3025 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
3026 {
3027 fputs (".as", file);
3028 output_scaled = 1;
3029 }
3030 break;
3031 case REG:
3032 break;
3033 default:
3034 gcc_assert (CONSTANT_P (addr)); break;
3035 }
3036 }
3037 else
3038 output_operand_lossage ("invalid operand to %%U code");
3039 return;
3040 case 'V' :
3041 /* Output cache bypass indicator for a load/store insn. Volatile memory
3042 refs are defined to use the cache bypass mechanism. */
3043 if (GET_CODE (x) == MEM)
3044 {
3045 if (MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET )
3046 fputs (".di", file);
3047 }
3048 else
3049 output_operand_lossage ("invalid operand to %%V code");
3050 return;
3051 /* plt code. */
3052 case 'P':
3053 case 0 :
3054 /* Do nothing special. */
3055 break;
3056 case 'F':
3057 fputs (reg_names[REGNO (x)]+1, file);
3058 return;
3059 case '^':
3060 /* This punctuation character is needed because label references are
3061 printed in the output template using %l. This is a front end
3062 character, and when we want to emit a '@' before it, we have to use
3063 this '^'. */
3064
3065 fputc('@',file);
3066 return;
3067 case 'O':
3068 /* Output an operator. */
3069 switch (GET_CODE (x))
3070 {
3071 case PLUS: fputs ("add", file); return;
3072 case SS_PLUS: fputs ("adds", file); return;
3073 case AND: fputs ("and", file); return;
3074 case IOR: fputs ("or", file); return;
3075 case XOR: fputs ("xor", file); return;
3076 case MINUS: fputs ("sub", file); return;
3077 case SS_MINUS: fputs ("subs", file); return;
3078 case ASHIFT: fputs ("asl", file); return;
3079 case ASHIFTRT: fputs ("asr", file); return;
3080 case LSHIFTRT: fputs ("lsr", file); return;
3081 case ROTATERT: fputs ("ror", file); return;
3082 case MULT: fputs ("mpy", file); return;
3083 case ABS: fputs ("abs", file); return; /* Unconditional. */
3084 case NEG: fputs ("neg", file); return;
3085 case SS_NEG: fputs ("negs", file); return;
3086 case NOT: fputs ("not", file); return; /* Unconditional. */
3087 case ZERO_EXTEND:
3088 fputs ("ext", file); /* bmsk allows predication. */
3089 goto size_suffix;
3090 case SIGN_EXTEND: /* Unconditional. */
3091 fputs ("sex", file);
3092 size_suffix:
3093 switch (GET_MODE (XEXP (x, 0)))
3094 {
3095 case QImode: fputs ("b", file); return;
3096 case HImode: fputs ("w", file); return;
3097 default: break;
3098 }
3099 break;
3100 case SS_TRUNCATE:
3101 if (GET_MODE (x) != HImode)
3102 break;
3103 fputs ("sat16", file);
3104 default: break;
3105 }
3106 output_operand_lossage ("invalid operand to %%O code"); return;
3107 case 'o':
3108 if (GET_CODE (x) == SYMBOL_REF)
3109 {
3110 assemble_name (file, XSTR (x, 0));
3111 return;
3112 }
3113 break;
3114 case '&':
3115 if (TARGET_ANNOTATE_ALIGN && cfun->machine->size_reason)
3116 fprintf (file, "; unalign: %d", cfun->machine->unalign);
3117 return;
3118 default :
3119 /* Unknown flag. */
3120 output_operand_lossage ("invalid operand output code");
3121 }
3122
3123 switch (GET_CODE (x))
3124 {
3125 case REG :
3126 fputs (reg_names[REGNO (x)], file);
3127 break;
3128 case MEM :
3129 {
3130 rtx addr = XEXP (x, 0);
3131 int size = GET_MODE_SIZE (GET_MODE (x));
3132
3133 fputc ('[', file);
3134
3135 switch (GET_CODE (addr))
3136 {
3137 case PRE_INC: case POST_INC:
cc8ca59e
JB
3138 output_address (VOIDmode,
3139 plus_constant (Pmode, XEXP (addr, 0), size)); break;
526b7aee 3140 case PRE_DEC: case POST_DEC:
cc8ca59e
JB
3141 output_address (VOIDmode,
3142 plus_constant (Pmode, XEXP (addr, 0), -size));
526b7aee
SV
3143 break;
3144 case PRE_MODIFY: case POST_MODIFY:
cc8ca59e 3145 output_address (VOIDmode, XEXP (addr, 1)); break;
526b7aee
SV
3146 case PLUS:
3147 if (output_scaled)
3148 {
cc8ca59e
JB
3149 output_address (VOIDmode,
3150 plus_constant (Pmode, XEXP (addr, 0),
526b7aee
SV
3151 (INTVAL (XEXP (addr, 1))
3152 >> (size == 2 ? 1 : 2))));
3153 output_scaled = 0;
3154 }
3155 else
cc8ca59e 3156 output_address (VOIDmode, addr);
526b7aee
SV
3157 break;
3158 default:
3159 if (flag_pic && CONSTANT_ADDRESS_P (addr))
3160 arc_output_pic_addr_const (file, addr, code);
3161 else
cc8ca59e 3162 output_address (VOIDmode, addr);
526b7aee
SV
3163 break;
3164 }
3165 fputc (']', file);
3166 break;
3167 }
3168 case CONST_DOUBLE :
3169 /* We handle SFmode constants here as output_addr_const doesn't. */
3170 if (GET_MODE (x) == SFmode)
3171 {
526b7aee
SV
3172 long l;
3173
34a72c33 3174 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
526b7aee
SV
3175 fprintf (file, "0x%08lx", l);
3176 break;
3177 }
3178 /* Fall through. Let output_addr_const deal with it. */
3179 default :
3180 if (flag_pic)
3181 arc_output_pic_addr_const (file, x, code);
3182 else
3183 {
3184 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3185 with asm_output_symbol_ref */
3186 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
3187 {
3188 x = XEXP (x, 0);
3189 output_addr_const (file, XEXP (x, 0));
3190 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && SYMBOL_REF_SMALL_P (XEXP (x, 0)))
3191 fprintf (file, "@sda");
3192
3193 if (GET_CODE (XEXP (x, 1)) != CONST_INT
3194 || INTVAL (XEXP (x, 1)) >= 0)
3195 fprintf (file, "+");
3196 output_addr_const (file, XEXP (x, 1));
3197 }
3198 else
3199 output_addr_const (file, x);
3200 }
3201 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
3202 fprintf (file, "@sda");
3203 break;
3204 }
3205}
3206
3207/* Print a memory address as an operand to reference that memory location. */
3208
3209void
3210arc_print_operand_address (FILE *file , rtx addr)
3211{
3212 register rtx base, index = 0;
3213
3214 switch (GET_CODE (addr))
3215 {
3216 case REG :
3217 fputs (reg_names[REGNO (addr)], file);
3218 break;
3219 case SYMBOL_REF :
3220 output_addr_const (file, addr);
3221 if (SYMBOL_REF_SMALL_P (addr))
3222 fprintf (file, "@sda");
3223 break;
3224 case PLUS :
3225 if (GET_CODE (XEXP (addr, 0)) == MULT)
3226 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
3227 else if (CONST_INT_P (XEXP (addr, 0)))
3228 index = XEXP (addr, 0), base = XEXP (addr, 1);
3229 else
3230 base = XEXP (addr, 0), index = XEXP (addr, 1);
3231
3232 gcc_assert (OBJECT_P (base));
3233 arc_print_operand_address (file, base);
3234 if (CONSTANT_P (base) && CONST_INT_P (index))
3235 fputc ('+', file);
3236 else
3237 fputc (',', file);
3238 gcc_assert (OBJECT_P (index));
3239 arc_print_operand_address (file, index);
3240 break;
3241 case CONST:
3242 {
3243 rtx c = XEXP (addr, 0);
3244
3245 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
3246 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
3247
cc8ca59e 3248 output_address (VOIDmode, XEXP (addr, 0));
526b7aee
SV
3249
3250 break;
3251 }
3252 case PRE_INC :
3253 case PRE_DEC :
3254 /* We shouldn't get here as we've lost the mode of the memory object
3255 (which says how much to inc/dec by. */
3256 gcc_unreachable ();
3257 break;
3258 default :
3259 if (flag_pic)
3260 arc_output_pic_addr_const (file, addr, 0);
3261 else
3262 output_addr_const (file, addr);
3263 break;
3264 }
3265}
3266
3267/* Called via walk_stores. DATA points to a hash table we can use to
3268 establish a unique SYMBOL_REF for each counter, which corresponds to
3269 a caller-callee pair.
3270 X is a store which we want to examine for an UNSPEC_PROF, which
3271 would be an address loaded into a register, or directly used in a MEM.
3272 If we found an UNSPEC_PROF, if we encounter a new counter the first time,
3273 write out a description and a data allocation for a 32 bit counter.
3274 Also, fill in the appropriate symbol_ref into each UNSPEC_PROF instance. */
3275
3276static void
3277write_profile_sections (rtx dest ATTRIBUTE_UNUSED, rtx x, void *data)
3278{
3279 rtx *srcp, src;
3280 htab_t htab = (htab_t) data;
3281 rtx *slot;
3282
3283 if (GET_CODE (x) != SET)
3284 return;
3285 srcp = &SET_SRC (x);
3286 if (MEM_P (*srcp))
3287 srcp = &XEXP (*srcp, 0);
3288 else if (MEM_P (SET_DEST (x)))
3289 srcp = &XEXP (SET_DEST (x), 0);
3290 src = *srcp;
3291 if (GET_CODE (src) != CONST)
3292 return;
3293 src = XEXP (src, 0);
3294 if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_PROF)
3295 return;
3296
3297 gcc_assert (XVECLEN (src, 0) == 3);
3298 if (!htab_elements (htab))
3299 {
3300 output_asm_insn (".section .__arc_profile_desc, \"a\"\n"
3301 "\t.long %0 + 1\n",
3302 &XVECEXP (src, 0, 0));
3303 }
3304 slot = (rtx *) htab_find_slot (htab, src, INSERT);
3305 if (*slot == HTAB_EMPTY_ENTRY)
3306 {
3307 static int count_nr;
3308 char buf[24];
3309 rtx count;
3310
3311 *slot = src;
3312 sprintf (buf, "__prof_count%d", count_nr++);
3313 count = gen_rtx_SYMBOL_REF (Pmode, xstrdup (buf));
3314 XVECEXP (src, 0, 2) = count;
3315 output_asm_insn (".section\t.__arc_profile_desc, \"a\"\n"
3316 "\t.long\t%1\n"
3317 "\t.section\t.__arc_profile_counters, \"aw\"\n"
3318 "\t.type\t%o2, @object\n"
3319 "\t.size\t%o2, 4\n"
3320 "%o2:\t.zero 4",
3321 &XVECEXP (src, 0, 0));
3322 *srcp = count;
3323 }
3324 else
3325 *srcp = XVECEXP (*slot, 0, 2);
3326}
3327
3328/* Hash function for UNSPEC_PROF htab. Use both the caller's name and
3329 the callee's name (if known). */
3330
3331static hashval_t
3332unspec_prof_hash (const void *x)
3333{
3334 const_rtx u = (const_rtx) x;
3335 const_rtx s1 = XVECEXP (u, 0, 1);
3336
3337 return (htab_hash_string (XSTR (XVECEXP (u, 0, 0), 0))
3338 ^ (s1->code == SYMBOL_REF ? htab_hash_string (XSTR (s1, 0)) : 0));
3339}
3340
3341/* Equality function for UNSPEC_PROF htab. Two pieces of UNSPEC_PROF rtl
3342 shall refer to the same counter if both caller name and callee rtl
3343 are identical. */
3344
3345static int
3346unspec_prof_htab_eq (const void *x, const void *y)
3347{
3348 const_rtx u0 = (const_rtx) x;
3349 const_rtx u1 = (const_rtx) y;
3350 const_rtx s01 = XVECEXP (u0, 0, 1);
3351 const_rtx s11 = XVECEXP (u1, 0, 1);
3352
3353 return (!strcmp (XSTR (XVECEXP (u0, 0, 0), 0),
3354 XSTR (XVECEXP (u1, 0, 0), 0))
3355 && rtx_equal_p (s01, s11));
3356}
3357
3358/* Conditional execution support.
3359
3360 This is based on the ARM port but for now is much simpler.
3361
3362 A finite state machine takes care of noticing whether or not instructions
3363 can be conditionally executed, and thus decrease execution time and code
3364 size by deleting branch instructions. The fsm is controlled by
3365 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
3366 actions of PRINT_OPERAND. The patterns in the .md file for the branch
3367 insns also have a hand in this. */
3368/* The way we leave dealing with non-anulled or annull-false delay slot
3369 insns to the consumer is awkward. */
3370
3371/* The state of the fsm controlling condition codes are:
3372 0: normal, do nothing special
3373 1: don't output this insn
3374 2: don't output this insn
3375 3: make insns conditional
3376 4: make insns conditional
3377 5: make insn conditional (only for outputting anulled delay slot insns)
3378
3379 special value for cfun->machine->uid_ccfsm_state:
3380 6: return with but one insn before it since function start / call
3381
3382 State transitions (state->state by whom, under what condition):
3383 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
3384 some instructions.
3385 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
3386 by zero or more non-jump insns and an unconditional branch with
3387 the same target label as the condbranch.
3388 1 -> 3 branch patterns, after having not output the conditional branch
3389 2 -> 4 branch patterns, after having not output the conditional branch
3390 0 -> 5 branch patterns, for anulled delay slot insn.
3391 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
3392 (the target label has CODE_LABEL_NUMBER equal to
3393 arc_ccfsm_target_label).
3394 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
3395 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
3396 5 -> 0 when outputting the delay slot insn
3397
3398 If the jump clobbers the conditions then we use states 2 and 4.
3399
3400 A similar thing can be done with conditional return insns.
3401
3402 We also handle separating branches from sets of the condition code.
3403 This is done here because knowledge of the ccfsm state is required,
3404 we may not be outputting the branch. */
3405
3406/* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
3407 before letting final output INSN. */
3408
3409static void
b3458f61 3410arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
526b7aee
SV
3411{
3412 /* BODY will hold the body of INSN. */
3413 register rtx body;
3414
3415 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
3416 an if/then/else), and things need to be reversed. */
3417 int reverse = 0;
3418
3419 /* If we start with a return insn, we only succeed if we find another one. */
3420 int seeking_return = 0;
3421
3422 /* START_INSN will hold the insn from where we start looking. This is the
3423 first insn after the following code_label if REVERSE is true. */
b3458f61 3424 rtx_insn *start_insn = insn;
526b7aee
SV
3425
3426 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
3427 since they don't rely on a cmp preceding the. */
3428 enum attr_type jump_insn_type;
3429
3430 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
3431 We can't do this in macro FINAL_PRESCAN_INSN because its called from
3432 final_scan_insn which has `optimize' as a local. */
3433 if (optimize < 2 || TARGET_NO_COND_EXEC)
3434 return;
3435
3436 /* Ignore notes and labels. */
3437 if (!INSN_P (insn))
3438 return;
3439 body = PATTERN (insn);
3440 /* If in state 4, check if the target branch is reached, in order to
3441 change back to state 0. */
3442 if (state->state == 4)
3443 {
3444 if (insn == state->target_insn)
3445 {
3446 state->target_insn = NULL;
3447 state->state = 0;
3448 }
3449 return;
3450 }
3451
3452 /* If in state 3, it is possible to repeat the trick, if this insn is an
3453 unconditional branch to a label, and immediately following this branch
3454 is the previous target label which is only used once, and the label this
3455 branch jumps to is not too far off. Or in other words "we've done the
3456 `then' part, see if we can do the `else' part." */
3457 if (state->state == 3)
3458 {
3459 if (simplejump_p (insn))
3460 {
3461 start_insn = next_nonnote_insn (start_insn);
3462 if (GET_CODE (start_insn) == BARRIER)
3463 {
3464 /* ??? Isn't this always a barrier? */
3465 start_insn = next_nonnote_insn (start_insn);
3466 }
3467 if (GET_CODE (start_insn) == CODE_LABEL
3468 && CODE_LABEL_NUMBER (start_insn) == state->target_label
3469 && LABEL_NUSES (start_insn) == 1)
3470 reverse = TRUE;
3471 else
3472 return;
3473 }
3474 else if (GET_CODE (body) == SIMPLE_RETURN)
3475 {
3476 start_insn = next_nonnote_insn (start_insn);
3477 if (GET_CODE (start_insn) == BARRIER)
3478 start_insn = next_nonnote_insn (start_insn);
3479 if (GET_CODE (start_insn) == CODE_LABEL
3480 && CODE_LABEL_NUMBER (start_insn) == state->target_label
3481 && LABEL_NUSES (start_insn) == 1)
3482 {
3483 reverse = TRUE;
3484 seeking_return = 1;
3485 }
3486 else
3487 return;
3488 }
3489 else
3490 return;
3491 }
3492
3493 if (GET_CODE (insn) != JUMP_INSN
3494 || GET_CODE (PATTERN (insn)) == ADDR_VEC
3495 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
3496 return;
3497
3498 /* We can't predicate BRCC or loop ends.
3499 Also, when generating PIC code, and considering a medium range call,
3500 we can't predicate the call. */
3501 jump_insn_type = get_attr_type (insn);
3502 if (jump_insn_type == TYPE_BRCC
3503 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
3504 || jump_insn_type == TYPE_LOOP_END
3505 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
3506 return;
3507
3508 /* This jump might be paralleled with a clobber of the condition codes,
3509 the jump should always come first. */
3510 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
3511 body = XVECEXP (body, 0, 0);
3512
3513 if (reverse
3514 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
3515 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
3516 {
3517 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
3518 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
3519 int then_not_else = TRUE;
3520 /* Nonzero if next insn must be the target label. */
3521 int next_must_be_target_label_p;
b3458f61
DM
3522 rtx_insn *this_insn = start_insn;
3523 rtx label = 0;
526b7aee
SV
3524
3525 /* Register the insn jumped to. */
3526 if (reverse)
3527 {
3528 if (!seeking_return)
3529 label = XEXP (SET_SRC (body), 0);
3530 }
3531 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
3532 label = XEXP (XEXP (SET_SRC (body), 1), 0);
3533 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
3534 {
3535 label = XEXP (XEXP (SET_SRC (body), 2), 0);
3536 then_not_else = FALSE;
3537 }
3538 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
3539 seeking_return = 1;
3540 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
3541 {
3542 seeking_return = 1;
3543 then_not_else = FALSE;
3544 }
3545 else
3546 gcc_unreachable ();
3547
3548 /* If this is a non-annulled branch with a delay slot, there is
3549 no need to conditionalize the delay slot. */
3550 if (NEXT_INSN (PREV_INSN (insn)) != insn
3551 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
3552 {
3553 this_insn = NEXT_INSN (this_insn);
3554 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn)))
3555 == NEXT_INSN (this_insn));
3556 }
3557 /* See how many insns this branch skips, and what kind of insns. If all
3558 insns are okay, and the label or unconditional branch to the same
3559 label is not too far away, succeed. */
3560 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
3561 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
3562 insns_skipped++)
3563 {
3564 rtx scanbody;
3565
3566 this_insn = next_nonnote_insn (this_insn);
3567 if (!this_insn)
3568 break;
3569
3570 if (next_must_be_target_label_p)
3571 {
3572 if (GET_CODE (this_insn) == BARRIER)
3573 continue;
3574 if (GET_CODE (this_insn) == CODE_LABEL
3575 && this_insn == label)
3576 {
3577 state->state = 1;
3578 succeed = TRUE;
3579 }
3580 else
3581 fail = TRUE;
3582 break;
3583 }
3584
3585 scanbody = PATTERN (this_insn);
3586
3587 switch (GET_CODE (this_insn))
3588 {
3589 case CODE_LABEL:
3590 /* Succeed if it is the target label, otherwise fail since
3591 control falls in from somewhere else. */
3592 if (this_insn == label)
3593 {
3594 state->state = 1;
3595 succeed = TRUE;
3596 }
3597 else
3598 fail = TRUE;
3599 break;
3600
3601 case BARRIER:
3602 /* Succeed if the following insn is the target label.
3603 Otherwise fail.
3604 If return insns are used then the last insn in a function
3605 will be a barrier. */
3606 next_must_be_target_label_p = TRUE;
3607 break;
3608
3609 case CALL_INSN:
3610 /* Can handle a call insn if there are no insns after it.
3611 IE: The next "insn" is the target label. We don't have to
3612 worry about delay slots as such insns are SEQUENCE's inside
3613 INSN's. ??? It is possible to handle such insns though. */
3614 if (get_attr_cond (this_insn) == COND_CANUSE)
3615 next_must_be_target_label_p = TRUE;
3616 else
3617 fail = TRUE;
3618 break;
3619
3620 case JUMP_INSN:
3621 /* If this is an unconditional branch to the same label, succeed.
3622 If it is to another label, do nothing. If it is conditional,
3623 fail. */
3624 /* ??? Probably, the test for the SET and the PC are
3625 unnecessary. */
3626
3627 if (GET_CODE (scanbody) == SET
3628 && GET_CODE (SET_DEST (scanbody)) == PC)
3629 {
3630 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
3631 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
3632 {
3633 state->state = 2;
3634 succeed = TRUE;
3635 }
3636 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
3637 fail = TRUE;
3638 else if (get_attr_cond (this_insn) != COND_CANUSE)
3639 fail = TRUE;
3640 }
3641 else if (GET_CODE (scanbody) == SIMPLE_RETURN
3642 && seeking_return)
3643 {
3644 state->state = 2;
3645 succeed = TRUE;
3646 }
3647 else if (GET_CODE (scanbody) == PARALLEL)
3648 {
3649 if (get_attr_cond (this_insn) != COND_CANUSE)
3650 fail = TRUE;
3651 }
3652 break;
3653
3654 case INSN:
3655 /* We can only do this with insns that can use the condition
3656 codes (and don't set them). */
3657 if (GET_CODE (scanbody) == SET
3658 || GET_CODE (scanbody) == PARALLEL)
3659 {
3660 if (get_attr_cond (this_insn) != COND_CANUSE)
3661 fail = TRUE;
3662 }
3663 /* We can't handle other insns like sequences. */
3664 else
3665 fail = TRUE;
3666 break;
3667
3668 default:
3669 break;
3670 }
3671 }
3672
3673 if (succeed)
3674 {
3675 if ((!seeking_return) && (state->state == 1 || reverse))
3676 state->target_label = CODE_LABEL_NUMBER (label);
3677 else if (seeking_return || state->state == 2)
3678 {
3679 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
3680 {
3681 this_insn = next_nonnote_insn (this_insn);
3682
3683 gcc_assert (!this_insn ||
3684 (GET_CODE (this_insn) != BARRIER
3685 && GET_CODE (this_insn) != CODE_LABEL));
3686 }
3687 if (!this_insn)
3688 {
3689 /* Oh dear! we ran off the end, give up. */
3690 extract_insn_cached (insn);
3691 state->state = 0;
3692 state->target_insn = NULL;
3693 return;
3694 }
3695 state->target_insn = this_insn;
3696 }
3697 else
3698 gcc_unreachable ();
3699
3700 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
3701 what it was. */
3702 if (!reverse)
3703 {
3704 state->cond = XEXP (SET_SRC (body), 0);
3705 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
3706 }
3707
3708 if (reverse || then_not_else)
3709 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
3710 }
3711
3712 /* Restore recog_operand. Getting the attributes of other insns can
3713 destroy this array, but final.c assumes that it remains intact
3714 across this call; since the insn has been recognized already we
3715 call insn_extract direct. */
3716 extract_insn_cached (insn);
3717 }
3718}
3719
3720/* Record that we are currently outputting label NUM with prefix PREFIX.
3721 It it's the label we're looking for, reset the ccfsm machinery.
3722
3723 Called from ASM_OUTPUT_INTERNAL_LABEL. */
3724
3725static void
3726arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
3727{
3728 if (state->state == 3 && state->target_label == num
3729 && !strcmp (prefix, "L"))
3730 {
3731 state->state = 0;
b3458f61 3732 state->target_insn = NULL;
526b7aee
SV
3733 }
3734}
3735
3736/* We are considering a conditional branch with the condition COND.
3737 Check if we want to conditionalize a delay slot insn, and if so modify
3738 the ccfsm state accordingly.
3739 REVERSE says branch will branch when the condition is false. */
3740void
b32d5189 3741arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
526b7aee
SV
3742 struct arc_ccfsm *state)
3743{
b3458f61 3744 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
526b7aee
SV
3745 if (!state)
3746 state = &arc_ccfsm_current;
3747
3748 gcc_assert (state->state == 0);
3749 if (seq_insn != jump)
3750 {
3751 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
3752
4654c0cf 3753 if (!as_a<rtx_insn *> (insn)->deleted ()
526b7aee
SV
3754 && INSN_ANNULLED_BRANCH_P (jump)
3755 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
3756 {
3757 state->cond = cond;
3758 state->cc = get_arc_condition_code (cond);
3759 if (!reverse)
3760 arc_ccfsm_current.cc
3761 = ARC_INVERSE_CONDITION_CODE (state->cc);
3762 rtx pat = PATTERN (insn);
3763 if (GET_CODE (pat) == COND_EXEC)
3764 gcc_assert ((INSN_FROM_TARGET_P (insn)
3765 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
3766 == get_arc_condition_code (XEXP (pat, 0)));
3767 else
3768 state->state = 5;
3769 }
3770 }
3771}
3772
3773/* Update *STATE as we would when we emit INSN. */
3774
3775static void
b3458f61 3776arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
526b7aee 3777{
53ea364f
JR
3778 enum attr_type type;
3779
526b7aee
SV
3780 if (LABEL_P (insn))
3781 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
3782 else if (JUMP_P (insn)
3783 && GET_CODE (PATTERN (insn)) != ADDR_VEC
3784 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
53ea364f
JR
3785 && ((type = get_attr_type (insn)) == TYPE_BRANCH
3786 || (type == TYPE_UNCOND_BRANCH
1ea1e1b5
JR
3787 /* ??? Maybe should also handle TYPE_RETURN here,
3788 but we don't have a testcase for that. */
53ea364f 3789 && ARC_CCFSM_BRANCH_DELETED_P (state))))
526b7aee
SV
3790 {
3791 if (ARC_CCFSM_BRANCH_DELETED_P (state))
3792 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
3793 else
3794 {
3795 rtx src = SET_SRC (PATTERN (insn));
3796 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
3797 insn, state);
3798 }
3799 }
3800 else if (arc_ccfsm_current.state == 5)
3801 arc_ccfsm_current.state = 0;
3802}
3803
3804/* Return true if the current insn, which is a conditional branch, is to be
3805 deleted. */
3806
3807bool
3808arc_ccfsm_branch_deleted_p (void)
3809{
3810 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
3811}
3812
3813/* Record a branch isn't output because subsequent insns can be
3814 conditionalized. */
3815
3816void
3817arc_ccfsm_record_branch_deleted (void)
3818{
3819 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
3820}
3821
3822/* During insn output, indicate if the current insn is predicated. */
3823
3824bool
3825arc_ccfsm_cond_exec_p (void)
3826{
3827 return (cfun->machine->prescan_initialized
3828 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
3829}
3830
3831/* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
3832 and look inside SEQUENCEs. */
3833
b3458f61
DM
3834static rtx_insn *
3835arc_next_active_insn (rtx_insn *insn, struct arc_ccfsm *statep)
526b7aee
SV
3836{
3837 rtx pat;
3838
3839 do
3840 {
3841 if (statep)
3842 arc_ccfsm_post_advance (insn, statep);
3843 insn = NEXT_INSN (insn);
3844 if (!insn || BARRIER_P (insn))
b3458f61 3845 return NULL;
526b7aee
SV
3846 if (statep)
3847 arc_ccfsm_advance (insn, statep);
3848 }
3849 while (NOTE_P (insn)
3850 || (cfun->machine->arc_reorg_started
3851 && LABEL_P (insn) && !label_to_alignment (insn))
3852 || (NONJUMP_INSN_P (insn)
3853 && (GET_CODE (PATTERN (insn)) == USE
3854 || GET_CODE (PATTERN (insn)) == CLOBBER)));
3855 if (!LABEL_P (insn))
3856 {
3857 gcc_assert (INSN_P (insn));
3858 pat = PATTERN (insn);
3859 if (GET_CODE (pat) == ADDR_VEC || GET_CODE (pat) == ADDR_DIFF_VEC)
b3458f61 3860 return NULL;
526b7aee 3861 if (GET_CODE (pat) == SEQUENCE)
b3458f61 3862 return as_a <rtx_insn *> (XVECEXP (pat, 0, 0));
526b7aee
SV
3863 }
3864 return insn;
3865}
3866
3867/* When deciding if an insn should be output short, we want to know something
3868 about the following insns:
3869 - if another insn follows which we know we can output as a short insn
3870 before an alignment-sensitive point, we can output this insn short:
3871 the decision about the eventual alignment can be postponed.
3872 - if a to-be-aligned label comes next, we should output this insn such
3873 as to get / preserve 4-byte alignment.
3874 - if a likely branch without delay slot insn, or a call with an immediately
3875 following short insn comes next, we should out output this insn such as to
3876 get / preserve 2 mod 4 unalignment.
3877 - do the same for a not completely unlikely branch with a short insn
3878 following before any other branch / label.
3879 - in order to decide if we are actually looking at a branch, we need to
3880 call arc_ccfsm_advance.
3881 - in order to decide if we are looking at a short insn, we should know
3882 if it is conditionalized. To a first order of approximation this is
3883 the case if the state from arc_ccfsm_advance from before this insn
3884 indicates the insn is conditionalized. However, a further refinement
3885 could be to not conditionalize an insn if the destination register(s)
3886 is/are dead in the non-executed case. */
3887/* Return non-zero if INSN should be output as a short insn. UNALIGN is
3888 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
3889 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
3890
3891int
b3458f61 3892arc_verify_short (rtx_insn *insn, int, int check_attr)
526b7aee
SV
3893{
3894 enum attr_iscompact iscompact;
3895 struct machine_function *machine;
3896
3897 if (check_attr > 0)
3898 {
3899 iscompact = get_attr_iscompact (insn);
3900 if (iscompact == ISCOMPACT_FALSE)
3901 return 0;
3902 }
3903 machine = cfun->machine;
3904
3905 if (machine->force_short_suffix >= 0)
3906 return machine->force_short_suffix;
3907
3908 return (get_attr_length (insn) & 2) != 0;
3909}
3910
3911/* When outputting an instruction (alternative) that can potentially be short,
3912 output the short suffix if the insn is in fact short, and update
3913 cfun->machine->unalign accordingly. */
3914
3915static void
3916output_short_suffix (FILE *file)
3917{
b3458f61 3918 rtx_insn *insn = current_output_insn;
526b7aee
SV
3919
3920 if (arc_verify_short (insn, cfun->machine->unalign, 1))
3921 {
3922 fprintf (file, "_s");
3923 cfun->machine->unalign ^= 2;
3924 }
3925 /* Restore recog_operand. */
3926 extract_insn_cached (insn);
3927}
3928
3929/* Implement FINAL_PRESCAN_INSN. */
3930
3931void
b3458f61 3932arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
526b7aee
SV
3933 int noperands ATTRIBUTE_UNUSED)
3934{
3935 if (TARGET_DUMPISIZE)
3936 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
3937
3938 /* Output a nop if necessary to prevent a hazard.
3939 Don't do this for delay slots: inserting a nop would
3940 alter semantics, and the only time we would find a hazard is for a
3941 call function result - and in that case, the hazard is spurious to
3942 start with. */
3943 if (PREV_INSN (insn)
3944 && PREV_INSN (NEXT_INSN (insn)) == insn
3945 && arc_hazard (prev_real_insn (insn), insn))
3946 {
3947 current_output_insn =
3948 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn)));
3949 final_scan_insn (current_output_insn, asm_out_file, optimize, 1, NULL);
b3458f61 3950 current_output_insn = insn;
526b7aee
SV
3951 }
3952 /* Restore extraction data which might have been clobbered by arc_hazard. */
3953 extract_constrain_insn_cached (insn);
3954
3955 if (!cfun->machine->prescan_initialized)
3956 {
3957 /* Clear lingering state from branch shortening. */
3958 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
3959 cfun->machine->prescan_initialized = 1;
3960 }
3961 arc_ccfsm_advance (insn, &arc_ccfsm_current);
3962
3963 cfun->machine->size_reason = 0;
3964}
3965
3966/* Given FROM and TO register numbers, say whether this elimination is allowed.
3967 Frame pointer elimination is automatically handled.
3968
3969 All eliminations are permissible. If we need a frame
3970 pointer, we must eliminate ARG_POINTER_REGNUM into
3971 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
3972
3973static bool
3974arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
3975{
3976 return to == FRAME_POINTER_REGNUM || !arc_frame_pointer_required ();
3977}
3978
3979/* Define the offset between two registers, one to be eliminated, and
3980 the other its replacement, at the start of a routine. */
3981
3982int
3983arc_initial_elimination_offset (int from, int to)
3984{
3985 if (! cfun->machine->frame_info.initialized)
3986 arc_compute_frame_size (get_frame_size ());
3987
3988 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
3989 {
3990 return (cfun->machine->frame_info.extra_size
3991 + cfun->machine->frame_info.reg_size);
3992 }
3993
3994 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
3995 {
3996 return (cfun->machine->frame_info.total_size
3997 - cfun->machine->frame_info.pretend_size);
3998 }
3999
4000 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
4001 {
4002 return (cfun->machine->frame_info.total_size
4003 - (cfun->machine->frame_info.pretend_size
4004 + cfun->machine->frame_info.extra_size
4005 + cfun->machine->frame_info.reg_size));
4006 }
4007
4008 gcc_unreachable ();
4009}
4010
4011static bool
4012arc_frame_pointer_required (void)
4013{
4014 return cfun->calls_alloca;
4015}
4016
4017
4018/* Return the destination address of a branch. */
4019
4020int
4021branch_dest (rtx branch)
4022{
4023 rtx pat = PATTERN (branch);
4024 rtx dest = (GET_CODE (pat) == PARALLEL
4025 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
4026 int dest_uid;
4027
4028 if (GET_CODE (dest) == IF_THEN_ELSE)
4029 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
4030
4031 dest = XEXP (dest, 0);
4032 dest_uid = INSN_UID (dest);
4033
4034 return INSN_ADDRESSES (dest_uid);
4035}
4036
4037
5719867d 4038/* Implement TARGET_ENCODE_SECTION_INFO hook. */
526b7aee
SV
4039
4040static void
4041arc_encode_section_info (tree decl, rtx rtl, int first)
4042{
4043 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4044 This clears machine specific flags, so has to come first. */
4045 default_encode_section_info (decl, rtl, first);
4046
4047 /* Check if it is a function, and whether it has the
4048 [long/medium/short]_call attribute specified. */
4049 if (TREE_CODE (decl) == FUNCTION_DECL)
4050 {
4051 rtx symbol = XEXP (rtl, 0);
4052 int flags = SYMBOL_REF_FLAGS (symbol);
4053
4054 tree attr = (TREE_TYPE (decl) != error_mark_node
4055 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
4056 tree long_call_attr = lookup_attribute ("long_call", attr);
4057 tree medium_call_attr = lookup_attribute ("medium_call", attr);
4058 tree short_call_attr = lookup_attribute ("short_call", attr);
4059
4060 if (long_call_attr != NULL_TREE)
4061 flags |= SYMBOL_FLAG_LONG_CALL;
4062 else if (medium_call_attr != NULL_TREE)
4063 flags |= SYMBOL_FLAG_MEDIUM_CALL;
4064 else if (short_call_attr != NULL_TREE)
4065 flags |= SYMBOL_FLAG_SHORT_CALL;
4066
4067 SYMBOL_REF_FLAGS (symbol) = flags;
4068 }
4069}
4070
4071/* This is how to output a definition of an internal numbered label where
4072 PREFIX is the class of label and NUM is the number within the class. */
4073
4074static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
4075{
4076 if (cfun)
4077 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
4078 default_internal_label (stream, prefix, labelno);
4079}
4080
4081/* Set the cpu type and print out other fancy things,
4082 at the top of the file. */
4083
4084static void arc_file_start (void)
4085{
4086 default_file_start ();
4087 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
4088}
4089
4090/* Cost functions. */
4091
4092/* Compute a (partial) cost for rtx X. Return true if the complete
4093 cost has been computed, and false if subexpressions should be
4094 scanned. In either case, *TOTAL contains the cost result. */
4095
4096static bool
e548c9df
AM
4097arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
4098 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
526b7aee 4099{
e548c9df
AM
4100 int code = GET_CODE (x);
4101
526b7aee
SV
4102 switch (code)
4103 {
4104 /* Small integers are as cheap as registers. */
4105 case CONST_INT:
4106 {
4107 bool nolimm = false; /* Can we do without long immediate? */
4108 bool fast = false; /* Is the result available immediately? */
4109 bool condexec = false; /* Does this allow conditiobnal execution? */
4110 bool compact = false; /* Is a 16 bit opcode available? */
4111 /* CONDEXEC also implies that we can have an unconditional
4112 3-address operation. */
4113
4114 nolimm = compact = condexec = false;
4115 if (UNSIGNED_INT6 (INTVAL (x)))
4116 nolimm = condexec = compact = true;
4117 else
4118 {
4119 if (SMALL_INT (INTVAL (x)))
4120 nolimm = fast = true;
4121 switch (outer_code)
4122 {
4123 case AND: /* bclr, bmsk, ext[bw] */
4124 if (satisfies_constraint_Ccp (x) /* bclr */
4125 || satisfies_constraint_C1p (x) /* bmsk */)
4126 nolimm = fast = condexec = compact = true;
4127 break;
4128 case IOR: /* bset */
4129 if (satisfies_constraint_C0p (x)) /* bset */
4130 nolimm = fast = condexec = compact = true;
4131 break;
4132 case XOR:
4133 if (satisfies_constraint_C0p (x)) /* bxor */
4134 nolimm = fast = condexec = true;
4135 break;
4136 case SET:
4137 if (satisfies_constraint_Crr (x)) /* ror b,u6 */
4138 nolimm = true;
4139 default:
4140 break;
4141 }
4142 }
4143 /* FIXME: Add target options to attach a small cost if
4144 condexec / compact is not true. */
4145 if (nolimm)
4146 {
4147 *total = 0;
4148 return true;
4149 }
4150 }
4151 /* FALLTHRU */
4152
4153 /* 4 byte values can be fetched as immediate constants -
4154 let's give that the cost of an extra insn. */
4155 case CONST:
4156 case LABEL_REF:
4157 case SYMBOL_REF:
4158 *total = COSTS_N_INSNS (1);
4159 return true;
4160
4161 case CONST_DOUBLE:
4162 {
4163 rtx high, low;
4164
4165 if (TARGET_DPFP)
4166 {
4167 *total = COSTS_N_INSNS (1);
4168 return true;
4169 }
4170 /* FIXME: correct the order of high,low */
4171 split_double (x, &high, &low);
4172 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high))
4173 + !SMALL_INT (INTVAL (low)));
4174 return true;
4175 }
4176
4177 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4178 If we need more than 12 insns to do a multiply, then go out-of-line,
4179 since the call overhead will be < 10% of the cost of the multiply. */
4180 case ASHIFT:
4181 case ASHIFTRT:
4182 case LSHIFTRT:
4183 if (TARGET_BARREL_SHIFTER)
4184 {
4185 /* If we want to shift a constant, we need a LIMM. */
4186 /* ??? when the optimizers want to know if a constant should be
4187 hoisted, they ask for the cost of the constant. OUTER_CODE is
4188 insufficient context for shifts since we don't know which operand
4189 we are looking at. */
4190 if (CONSTANT_P (XEXP (x, 0)))
4191 {
4192 *total += (COSTS_N_INSNS (2)
e548c9df
AM
4193 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
4194 0, speed));
526b7aee
SV
4195 return true;
4196 }
4197 *total = COSTS_N_INSNS (1);
4198 }
4199 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4200 *total = COSTS_N_INSNS (16);
4201 else
4202 {
4203 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
4204 /* ??? want_to_gcse_p can throw negative shift counts at us,
4205 and then panics when it gets a negative cost as result.
4206 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4207 if (*total < 0)
4208 *total = 0;
4209 }
4210 return false;
4211
4212 case DIV:
4213 case UDIV:
4214 if (speed)
4215 *total = COSTS_N_INSNS(30);
4216 else
4217 *total = COSTS_N_INSNS(1);
4218 return false;
4219
4220 case MULT:
4221 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
4222 *total = COSTS_N_INSNS (1);
4223 else if (speed)
4224 *total= arc_multcost;
4225 /* We do not want synth_mult sequences when optimizing
4226 for size. */
4227 else if (TARGET_MUL64_SET || (TARGET_ARC700 && !TARGET_NOMPY_SET))
4228 *total = COSTS_N_INSNS (1);
4229 else
4230 *total = COSTS_N_INSNS (2);
4231 return false;
4232 case PLUS:
4233 if (GET_CODE (XEXP (x, 0)) == MULT
4234 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
4235 {
e548c9df
AM
4236 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
4237 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
526b7aee
SV
4238 return true;
4239 }
4240 return false;
4241 case MINUS:
4242 if (GET_CODE (XEXP (x, 1)) == MULT
4243 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
4244 {
e548c9df
AM
4245 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
4246 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
526b7aee
SV
4247 return true;
4248 }
4249 return false;
4250 case COMPARE:
4251 {
4252 rtx op0 = XEXP (x, 0);
4253 rtx op1 = XEXP (x, 1);
4254
4255 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
4256 && XEXP (op0, 1) == const1_rtx)
4257 {
4258 /* btst / bbit0 / bbit1:
4259 Small integers and registers are free; everything else can
4260 be put in a register. */
e548c9df
AM
4261 mode = GET_MODE (XEXP (op0, 0));
4262 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
4263 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
526b7aee
SV
4264 return true;
4265 }
4266 if (GET_CODE (op0) == AND && op1 == const0_rtx
4267 && satisfies_constraint_C1p (XEXP (op0, 1)))
4268 {
4269 /* bmsk.f */
e548c9df 4270 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
526b7aee
SV
4271 return true;
4272 }
4273 /* add.f */
4274 if (GET_CODE (op1) == NEG)
4275 {
4276 /* op0 might be constant, the inside of op1 is rather
4277 unlikely to be so. So swapping the operands might lower
4278 the cost. */
e548c9df
AM
4279 mode = GET_MODE (op0);
4280 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
4281 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
526b7aee
SV
4282 }
4283 return false;
4284 }
4285 case EQ: case NE:
4286 if (outer_code == IF_THEN_ELSE
4287 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
4288 && XEXP (x, 1) == const0_rtx
4289 && XEXP (XEXP (x, 0), 1) == const1_rtx)
4290 {
4291 /* btst / bbit0 / bbit1:
4292 Small integers and registers are free; everything else can
4293 be put in a register. */
4294 rtx op0 = XEXP (x, 0);
4295
e548c9df
AM
4296 mode = GET_MODE (XEXP (op0, 0));
4297 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
4298 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
526b7aee
SV
4299 return true;
4300 }
4301 /* Fall through. */
4302 /* scc_insn expands into two insns. */
4303 case GTU: case GEU: case LEU:
e548c9df 4304 if (mode == SImode)
526b7aee
SV
4305 *total += COSTS_N_INSNS (1);
4306 return false;
4307 case LTU: /* might use adc. */
e548c9df 4308 if (mode == SImode)
526b7aee
SV
4309 *total += COSTS_N_INSNS (1) - 1;
4310 return false;
4311 default:
4312 return false;
4313 }
4314}
4315
4316/* Return true if ADDR is an address that needs to be expressed as an
4317 explicit sum of pcl + offset. */
4318
4319bool
4320arc_legitimate_pc_offset_p (rtx addr)
4321{
4322 if (GET_CODE (addr) != CONST)
4323 return false;
4324 addr = XEXP (addr, 0);
4325 if (GET_CODE (addr) == PLUS)
4326 {
4327 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
4328 return false;
4329 addr = XEXP (addr, 0);
4330 }
4331 return (GET_CODE (addr) == UNSPEC
4332 && XVECLEN (addr, 0) == 1
4333 && XINT (addr, 1) == ARC_UNSPEC_GOT
4334 && GET_CODE (XVECEXP (addr, 0, 0)) == SYMBOL_REF);
4335}
4336
4337/* Return true if ADDR is a valid pic address.
4338 A valid pic address on arc should look like
4339 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
4340
4341bool
4342arc_legitimate_pic_addr_p (rtx addr)
4343{
4344 if (GET_CODE (addr) == LABEL_REF)
4345 return true;
4346 if (GET_CODE (addr) != CONST)
4347 return false;
4348
4349 addr = XEXP (addr, 0);
4350
4351
4352 if (GET_CODE (addr) == PLUS)
4353 {
4354 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
4355 return false;
4356 addr = XEXP (addr, 0);
4357 }
4358
4359 if (GET_CODE (addr) != UNSPEC
4360 || XVECLEN (addr, 0) != 1)
4361 return false;
4362
4363 /* Must be @GOT or @GOTOFF. */
4364 if (XINT (addr, 1) != ARC_UNSPEC_GOT
4365 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF)
4366 return false;
4367
4368 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
4369 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
4370 return false;
4371
4372 return true;
4373}
4374
4375
4376
4377/* Return true if OP contains a symbol reference. */
4378
4379static bool
4380symbolic_reference_mentioned_p (rtx op)
4381{
4382 register const char *fmt;
4383 register int i;
4384
4385 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
4386 return true;
4387
4388 fmt = GET_RTX_FORMAT (GET_CODE (op));
4389 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
4390 {
4391 if (fmt[i] == 'E')
4392 {
4393 register int j;
4394
4395 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
4396 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
4397 return true;
4398 }
4399
4400 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
4401 return true;
4402 }
4403
4404 return false;
4405}
4406
4407/* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
4408 If SKIP_LOCAL is true, skip symbols that bind locally.
4409 This is used further down in this file, and, without SKIP_LOCAL,
4410 in the addsi3 / subsi3 expanders when generating PIC code. */
4411
4412bool
4413arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
4414{
4415 register const char *fmt;
4416 register int i;
4417
4418 if (GET_CODE(op) == UNSPEC)
4419 return false;
4420
4421 if (GET_CODE (op) == SYMBOL_REF)
4422 {
4423 tree decl = SYMBOL_REF_DECL (op);
4424 return !skip_local || !decl || !default_binds_local_p (decl);
4425 }
4426
4427 fmt = GET_RTX_FORMAT (GET_CODE (op));
4428 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
4429 {
4430 if (fmt[i] == 'E')
4431 {
4432 register int j;
4433
4434 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
4435 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
4436 skip_local))
4437 return true;
4438 }
4439
4440 else if (fmt[i] == 'e'
4441 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
4442 skip_local))
4443 return true;
4444 }
4445
4446 return false;
4447}
4448
4449/* Legitimize a pic address reference in ORIG.
4450 The return value is the legitimated address.
4451 If OLDX is non-zero, it is the target to assign the address to first. */
4452
4453rtx
4454arc_legitimize_pic_address (rtx orig, rtx oldx)
4455{
4456 rtx addr = orig;
4457 rtx pat = orig;
4458 rtx base;
4459
4460 if (oldx == orig)
4461 oldx = NULL;
4462
4463 if (GET_CODE (addr) == LABEL_REF)
4464 ; /* Do nothing. */
4465 else if (GET_CODE (addr) == SYMBOL_REF
4466 && (CONSTANT_POOL_ADDRESS_P (addr)
4467 || SYMBOL_REF_LOCAL_P (addr)))
4468 {
4469 /* This symbol may be referenced via a displacement from the PIC
4470 base address (@GOTOFF). */
4471
4472 /* FIXME: if we had a way to emit pc-relative adds that don't
4473 create a GOT entry, we could do without the use of the gp register. */
4474 crtl->uses_pic_offset_table = 1;
4475 pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOTOFF);
4476 pat = gen_rtx_CONST (Pmode, pat);
4477 pat = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pat);
4478
4479 if (oldx == NULL)
4480 oldx = gen_reg_rtx (Pmode);
4481
4482 if (oldx != 0)
4483 {
4484 emit_move_insn (oldx, pat);
4485 pat = oldx;
4486 }
4487
4488 }
4489 else if (GET_CODE (addr) == SYMBOL_REF)
4490 {
4491 /* This symbol must be referenced via a load from the
4492 Global Offset Table (@GOTPC). */
4493
4494 pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT);
4495 pat = gen_rtx_CONST (Pmode, pat);
4496 pat = gen_const_mem (Pmode, pat);
4497
4498 if (oldx == 0)
4499 oldx = gen_reg_rtx (Pmode);
4500
4501 emit_move_insn (oldx, pat);
4502 pat = oldx;
4503 }
4504 else
4505 {
4506 if (GET_CODE (addr) == CONST)
4507 {
4508 addr = XEXP (addr, 0);
4509 if (GET_CODE (addr) == UNSPEC)
4510 {
4511 /* Check that the unspec is one of the ones we generate? */
4512 }
4513 else
4514 gcc_assert (GET_CODE (addr) == PLUS);
4515 }
4516
4517 if (GET_CODE (addr) == PLUS)
4518 {
4519 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
4520
4521 /* Check first to see if this is a constant offset from a @GOTOFF
4522 symbol reference. */
4523 if ((GET_CODE (op0) == LABEL_REF
4524 || (GET_CODE (op0) == SYMBOL_REF
4525 && (CONSTANT_POOL_ADDRESS_P (op0)
4526 || SYMBOL_REF_LOCAL_P (op0))))
4527 && GET_CODE (op1) == CONST_INT)
4528 {
4529 /* FIXME: like above, could do without gp reference. */
4530 crtl->uses_pic_offset_table = 1;
4531 pat
4532 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), ARC_UNSPEC_GOTOFF);
4533 pat = gen_rtx_PLUS (Pmode, pat, op1);
4534 pat = gen_rtx_CONST (Pmode, pat);
4535 pat = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pat);
4536
4537 if (oldx != 0)
4538 {
4539 emit_move_insn (oldx, pat);
4540 pat = oldx;
4541 }
4542 }
4543 else
4544 {
4545 base = arc_legitimize_pic_address (XEXP (addr, 0), oldx);
4546 pat = arc_legitimize_pic_address (XEXP (addr, 1),
4547 base == oldx ? NULL_RTX : oldx);
4548
4549 if (GET_CODE (pat) == CONST_INT)
4550 pat = plus_constant (Pmode, base, INTVAL (pat));
4551 else
4552 {
4553 if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1)))
4554 {
4555 base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0));
4556 pat = XEXP (pat, 1);
4557 }
4558 pat = gen_rtx_PLUS (Pmode, base, pat);
4559 }
4560 }
4561 }
4562 }
4563
4564 return pat;
4565}
4566
4567/* Output address constant X to FILE, taking PIC into account. */
4568
4569void
4570arc_output_pic_addr_const (FILE * file, rtx x, int code)
4571{
4572 char buf[256];
4573
4574 restart:
4575 switch (GET_CODE (x))
4576 {
4577 case PC:
4578 if (flag_pic)
4579 putc ('.', file);
4580 else
4581 gcc_unreachable ();
4582 break;
4583
4584 case SYMBOL_REF:
4585 output_addr_const (file, x);
4586
4587 /* Local functions do not get references through the PLT. */
4588 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
4589 fputs ("@plt", file);
4590 break;
4591
4592 case LABEL_REF:
4593 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
4594 assemble_name (file, buf);
4595 break;
4596
4597 case CODE_LABEL:
4598 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
4599 assemble_name (file, buf);
4600 break;
4601
4602 case CONST_INT:
4603 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
4604 break;
4605
4606 case CONST:
4607 arc_output_pic_addr_const (file, XEXP (x, 0), code);
4608 break;
4609
4610 case CONST_DOUBLE:
4611 if (GET_MODE (x) == VOIDmode)
4612 {
4613 /* We can use %d if the number is one word and positive. */
4614 if (CONST_DOUBLE_HIGH (x))
4615 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
4616 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
4617 else if (CONST_DOUBLE_LOW (x) < 0)
4618 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
4619 else
4620 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
4621 }
4622 else
4623 /* We can't handle floating point constants;
4624 PRINT_OPERAND must handle them. */
4625 output_operand_lossage ("floating constant misused");
4626 break;
4627
4628 case PLUS:
4629 /* FIXME: Not needed here. */
4630 /* Some assemblers need integer constants to appear last (eg masm). */
4631 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
4632 {
4633 arc_output_pic_addr_const (file, XEXP (x, 1), code);
4634 fprintf (file, "+");
4635 arc_output_pic_addr_const (file, XEXP (x, 0), code);
4636 }
4637 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
4638 {
4639 arc_output_pic_addr_const (file, XEXP (x, 0), code);
4640 if (INTVAL (XEXP (x, 1)) >= 0)
4641 fprintf (file, "+");
4642 arc_output_pic_addr_const (file, XEXP (x, 1), code);
4643 }
4644 else
4645 gcc_unreachable();
4646 break;
4647
4648 case MINUS:
4649 /* Avoid outputting things like x-x or x+5-x,
4650 since some assemblers can't handle that. */
4651 x = simplify_subtraction (x);
4652 if (GET_CODE (x) != MINUS)
4653 goto restart;
4654
4655 arc_output_pic_addr_const (file, XEXP (x, 0), code);
4656 fprintf (file, "-");
4657 if (GET_CODE (XEXP (x, 1)) == CONST_INT
4658 && INTVAL (XEXP (x, 1)) < 0)
4659 {
4660 fprintf (file, "(");
4661 arc_output_pic_addr_const (file, XEXP (x, 1), code);
4662 fprintf (file, ")");
4663 }
4664 else
4665 arc_output_pic_addr_const (file, XEXP (x, 1), code);
4666 break;
4667
4668 case ZERO_EXTEND:
4669 case SIGN_EXTEND:
4670 arc_output_pic_addr_const (file, XEXP (x, 0), code);
4671 break;
4672
4673
4674 case UNSPEC:
4675 gcc_assert (XVECLEN (x, 0) == 1);
4676 if (XINT (x, 1) == ARC_UNSPEC_GOT)
4677 fputs ("pcl,", file);
4678 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
4679 switch (XINT (x, 1))
4680 {
4681 case ARC_UNSPEC_GOT:
4682 fputs ("@gotpc", file);
4683 break;
4684 case ARC_UNSPEC_GOTOFF:
4685 fputs ("@gotoff", file);
4686 break;
4687 case ARC_UNSPEC_PLT:
4688 fputs ("@plt", file);
4689 break;
4690 default:
4691 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
4692 break;
4693 }
4694 break;
4695
4696 default:
4697 output_operand_lossage ("invalid expression as operand");
4698 }
4699}
4700
4701#define SYMBOLIC_CONST(X) \
4702(GET_CODE (X) == SYMBOL_REF \
4703 || GET_CODE (X) == LABEL_REF \
4704 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
4705
4706/* Emit insns to move operands[1] into operands[0]. */
4707
4708void
ef4bddc2 4709emit_pic_move (rtx *operands, machine_mode)
526b7aee
SV
4710{
4711 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
4712
4713 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
4714 operands[1] = force_reg (Pmode, operands[1]);
4715 else
4716 operands[1] = arc_legitimize_pic_address (operands[1], temp);
4717}
4718
4719
4720/* The function returning the number of words, at the beginning of an
4721 argument, must be put in registers. The returned value must be
4722 zero for arguments that are passed entirely in registers or that
4723 are entirely pushed on the stack.
4724
4725 On some machines, certain arguments must be passed partially in
4726 registers and partially in memory. On these machines, typically
4727 the first N words of arguments are passed in registers, and the
4728 rest on the stack. If a multi-word argument (a `double' or a
4729 structure) crosses that boundary, its first few words must be
4730 passed in registers and the rest must be pushed. This function
4731 tells the compiler when this occurs, and how many of the words
4732 should go in registers.
4733
4734 `FUNCTION_ARG' for these arguments should return the first register
4735 to be used by the caller for this argument; likewise
4736 `FUNCTION_INCOMING_ARG', for the called function.
4737
4738 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
4739
4740/* If REGNO is the least arg reg available then what is the total number of arg
4741 regs available. */
4742#define GPR_REST_ARG_REGS(REGNO) \
4743 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
4744
4745/* Since arc parm regs are contiguous. */
4746#define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
4747
4748/* Implement TARGET_ARG_PARTIAL_BYTES. */
4749
4750static int
ef4bddc2 4751arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
526b7aee
SV
4752 tree type, bool named ATTRIBUTE_UNUSED)
4753{
4754 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4755 int bytes = (mode == BLKmode
4756 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
4757 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4758 int arg_num = *cum;
4759 int ret;
4760
4761 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
4762 ret = GPR_REST_ARG_REGS (arg_num);
4763
4764 /* ICEd at function.c:2361, and ret is copied to data->partial */
4765 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
4766
4767 return ret;
4768}
4769
4770
4771
4772/* This function is used to control a function argument is passed in a
4773 register, and which register.
4774
4775 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
4776 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
4777 all of the previous arguments so far passed in registers; MODE, the
4778 machine mode of the argument; TYPE, the data type of the argument
4779 as a tree node or 0 if that is not known (which happens for C
4780 support library functions); and NAMED, which is 1 for an ordinary
4781 argument and 0 for nameless arguments that correspond to `...' in
4782 the called function's prototype.
4783
4784 The returned value should either be a `reg' RTX for the hard
4785 register in which to pass the argument, or zero to pass the
4786 argument on the stack.
4787
4788 For machines like the Vax and 68000, where normally all arguments
4789 are pushed, zero suffices as a definition.
4790
4791 The usual way to make the ANSI library `stdarg.h' work on a machine
4792 where some arguments are usually passed in registers, is to cause
4793 nameless arguments to be passed on the stack instead. This is done
4794 by making the function return 0 whenever NAMED is 0.
4795
4796 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
4797 definition of this function to determine if this argument is of a
4798 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
4799 is not defined and the function returns non-zero for such an
4800 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
4801 defined, the argument will be computed in the stack and then loaded
4802 into a register.
4803
4804 The function is used to implement macro FUNCTION_ARG. */
4805/* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
4806 and the rest are pushed. */
4807
4808static rtx
ef4bddc2 4809arc_function_arg (cumulative_args_t cum_v, machine_mode mode,
526b7aee
SV
4810 const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
4811{
4812 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4813 int arg_num = *cum;
4814 rtx ret;
4815 const char *debstr ATTRIBUTE_UNUSED;
4816
4817 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
4818 /* Return a marker for use in the call instruction. */
4819 if (mode == VOIDmode)
4820 {
4821 ret = const0_rtx;
4822 debstr = "<0>";
4823 }
4824 else if (GPR_REST_ARG_REGS (arg_num) > 0)
4825 {
4826 ret = gen_rtx_REG (mode, arg_num);
4827 debstr = reg_names [arg_num];
4828 }
4829 else
4830 {
4831 ret = NULL_RTX;
4832 debstr = "memory";
4833 }
4834 return ret;
4835}
4836
4837/* The function to update the summarizer variable *CUM to advance past
4838 an argument in the argument list. The values MODE, TYPE and NAMED
4839 describe that argument. Once this is done, the variable *CUM is
4840 suitable for analyzing the *following* argument with
4841 `FUNCTION_ARG', etc.
4842
4843 This function need not do anything if the argument in question was
4844 passed on the stack. The compiler knows how to track the amount of
4845 stack space used for arguments without any special help.
4846
4847 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
4848/* For the ARC: the cum set here is passed on to function_arg where we
4849 look at its value and say which reg to use. Strategy: advance the
4850 regnumber here till we run out of arg regs, then set *cum to last
4851 reg. In function_arg, since *cum > last arg reg we would return 0
4852 and thus the arg will end up on the stack. For straddling args of
4853 course function_arg_partial_nregs will come into play. */
4854
4855static void
ef4bddc2 4856arc_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
526b7aee
SV
4857 const_tree type, bool named ATTRIBUTE_UNUSED)
4858{
4859 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4860 int bytes = (mode == BLKmode
4861 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
4862 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4863 int i;
4864
4865 if (words)
4866 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
4867 for (i = 0; i < words; i++)
4868 *cum = ARC_NEXT_ARG_REG (*cum);
4869
4870}
4871
4872/* Define how to find the value returned by a function.
4873 VALTYPE is the data type of the value (as a tree).
4874 If the precise function being called is known, FN_DECL_OR_TYPE is its
4875 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
4876
4877static rtx
4878arc_function_value (const_tree valtype,
4879 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
4880 bool outgoing ATTRIBUTE_UNUSED)
4881{
ef4bddc2 4882 machine_mode mode = TYPE_MODE (valtype);
526b7aee
SV
4883 int unsignedp ATTRIBUTE_UNUSED;
4884
4885 unsignedp = TYPE_UNSIGNED (valtype);
4886 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
4887 PROMOTE_MODE (mode, unsignedp, valtype);
4888 return gen_rtx_REG (mode, 0);
4889}
4890
4891/* Returns the return address that is used by builtin_return_address. */
4892
4893rtx
4894arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
4895{
4896 if (count != 0)
4897 return const0_rtx;
4898
4899 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
4900}
4901
4902/* Nonzero if the constant value X is a legitimate general operand
4903 when generating PIC code. It is given that flag_pic is on and
4904 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
4905
4906bool
4907arc_legitimate_pic_operand_p (rtx x)
4908{
4909 return !arc_raw_symbolic_reference_mentioned_p (x, true);
4910}
4911
4912/* Determine if a given RTX is a valid constant. We already know this
4913 satisfies CONSTANT_P. */
4914
4915bool
ef4bddc2 4916arc_legitimate_constant_p (machine_mode, rtx x)
526b7aee
SV
4917{
4918 if (!flag_pic)
4919 return true;
4920
4921 switch (GET_CODE (x))
4922 {
4923 case CONST:
4924 x = XEXP (x, 0);
4925
4926 if (GET_CODE (x) == PLUS)
4927 {
4928 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4929 return false;
4930 x = XEXP (x, 0);
4931 }
4932
4933 /* Only some unspecs are valid as "constants". */
4934 if (GET_CODE (x) == UNSPEC)
4935 switch (XINT (x, 1))
4936 {
4937 case ARC_UNSPEC_PLT:
4938 case ARC_UNSPEC_GOTOFF:
4939 case ARC_UNSPEC_GOT:
4940 case UNSPEC_PROF:
4941 return true;
4942
4943 default:
4944 gcc_unreachable ();
4945 }
4946
4947 /* We must have drilled down to a symbol. */
4948 if (arc_raw_symbolic_reference_mentioned_p (x, false))
4949 return false;
4950
4951 /* Return true. */
4952 break;
4953
4954 case LABEL_REF:
4955 case SYMBOL_REF:
4956 return false;
4957
4958 default:
4959 break;
4960 }
4961
4962 /* Otherwise we handle everything else in the move patterns. */
4963 return true;
4964}
4965
4966static bool
ef4bddc2 4967arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
526b7aee
SV
4968{
4969 if (RTX_OK_FOR_BASE_P (x, strict))
4970 return true;
4971 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, TARGET_INDEXED_LOADS, strict))
4972 return true;
4973 if (LEGITIMATE_SCALED_ADDRESS_P (mode, x, strict))
4974 return true;
4975 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
4976 return true;
4977 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
4978 return true;
4979 if ((GET_MODE_SIZE (mode) != 16)
4980 && (GET_CODE (x) == SYMBOL_REF
4981 || GET_CODE (x) == LABEL_REF
4982 || GET_CODE (x) == CONST))
4983 {
4984 if (!flag_pic || arc_legitimate_pic_addr_p (x))
4985 return true;
4986 }
4987 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
4988 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
4989 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
4990 return true;
4991 /* We're restricted here by the `st' insn. */
4992 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
4993 && GET_CODE (XEXP ((x), 1)) == PLUS
4994 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
4995 && LEGITIMATE_OFFSET_ADDRESS_P (QImode, XEXP (x, 1),
4996 TARGET_AUTO_MODIFY_REG, strict))
4997 return true;
4998 return false;
4999}
5000
5001/* Return true iff ADDR (a legitimate address expression)
5002 has an effect that depends on the machine mode it is used for. */
5003
5004static bool
5005arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
5006{
5007 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5008 which is valid for loads and stores, or a limm offset, which is valid for
5009 loads. */
5010 /* Scaled indices are scaled by the access mode; likewise for scaled
5011 offsets, which are needed for maximum offset stores. */
5012 if (GET_CODE (addr) == PLUS
5013 && (GET_CODE (XEXP ((addr), 0)) == MULT
5014 || (CONST_INT_P (XEXP ((addr), 1))
5015 && !SMALL_INT (INTVAL (XEXP ((addr), 1))))))
5016 return true;
5017 return false;
5018}
5019
5020/* Determine if it's legal to put X into the constant pool. */
5021
5022static bool
ef4bddc2 5023arc_cannot_force_const_mem (machine_mode mode, rtx x)
526b7aee
SV
5024{
5025 return !arc_legitimate_constant_p (mode, x);
5026}
5027
5028
5029/* Generic function to define a builtin. */
5030#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
5031 do \
5032 { \
5033 if (MASK) \
5034 add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE); \
5035 } \
5036 while (0)
5037
5038
5039static void
5040arc_init_builtins (void)
5041{
5042 tree endlink = void_list_node;
5043
5044 tree void_ftype_void
5045 = build_function_type (void_type_node,
5046 endlink);
5047
5048 tree int_ftype_int
5049 = build_function_type (integer_type_node,
5050 tree_cons (NULL_TREE, integer_type_node, endlink));
5051
5052 tree pcvoid_type_node
5053 = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
5054 tree int_ftype_pcvoid_int
5055 = build_function_type (integer_type_node,
5056 tree_cons (NULL_TREE, pcvoid_type_node,
5057 tree_cons (NULL_TREE, integer_type_node,
5058 endlink)));
5059
5060 tree int_ftype_short_int
5061 = build_function_type (integer_type_node,
5062 tree_cons (NULL_TREE, short_integer_type_node, endlink));
5063
5064 tree void_ftype_int_int
5065 = build_function_type (void_type_node,
5066 tree_cons (NULL_TREE, integer_type_node,
5067 tree_cons (NULL_TREE, integer_type_node, endlink)));
5068 tree void_ftype_usint_usint
5069 = build_function_type (void_type_node,
5070 tree_cons (NULL_TREE, long_unsigned_type_node,
5071 tree_cons (NULL_TREE, long_unsigned_type_node, endlink)));
5072
5073 tree int_ftype_int_int
5074 = build_function_type (integer_type_node,
5075 tree_cons (NULL_TREE, integer_type_node,
5076 tree_cons (NULL_TREE, integer_type_node, endlink)));
5077
5078 tree usint_ftype_usint
5079 = build_function_type (long_unsigned_type_node,
5080 tree_cons (NULL_TREE, long_unsigned_type_node, endlink));
5081
5082 tree void_ftype_usint
5083 = build_function_type (void_type_node,
5084 tree_cons (NULL_TREE, long_unsigned_type_node, endlink));
5085
5086 /* Add the builtins. */
5087 def_mbuiltin (1,"__builtin_arc_nop", void_ftype_void, ARC_BUILTIN_NOP);
5088 def_mbuiltin (TARGET_NORM, "__builtin_arc_norm", int_ftype_int, ARC_BUILTIN_NORM);
5089 def_mbuiltin (TARGET_NORM, "__builtin_arc_normw", int_ftype_short_int, ARC_BUILTIN_NORMW);
5090 def_mbuiltin (TARGET_SWAP, "__builtin_arc_swap", int_ftype_int, ARC_BUILTIN_SWAP);
5091 def_mbuiltin (TARGET_MUL64_SET,"__builtin_arc_mul64", void_ftype_int_int, ARC_BUILTIN_MUL64);
5092 def_mbuiltin (TARGET_MUL64_SET,"__builtin_arc_mulu64", void_ftype_usint_usint, ARC_BUILTIN_MULU64);
5093 def_mbuiltin (1,"__builtin_arc_rtie", void_ftype_void, ARC_BUILTIN_RTIE);
5094 def_mbuiltin (TARGET_ARC700,"__builtin_arc_sync", void_ftype_void, ARC_BUILTIN_SYNC);
5095 def_mbuiltin ((TARGET_EA_SET),"__builtin_arc_divaw", int_ftype_int_int, ARC_BUILTIN_DIVAW);
5096 def_mbuiltin (1,"__builtin_arc_brk", void_ftype_void, ARC_BUILTIN_BRK);
5097 def_mbuiltin (1,"__builtin_arc_flag", void_ftype_usint, ARC_BUILTIN_FLAG);
5098 def_mbuiltin (1,"__builtin_arc_sleep", void_ftype_usint, ARC_BUILTIN_SLEEP);
5099 def_mbuiltin (1,"__builtin_arc_swi", void_ftype_void, ARC_BUILTIN_SWI);
5100 def_mbuiltin (1,"__builtin_arc_core_read", usint_ftype_usint, ARC_BUILTIN_CORE_READ);
5101 def_mbuiltin (1,"__builtin_arc_core_write", void_ftype_usint_usint, ARC_BUILTIN_CORE_WRITE);
5102 def_mbuiltin (1,"__builtin_arc_lr", usint_ftype_usint, ARC_BUILTIN_LR);
5103 def_mbuiltin (1,"__builtin_arc_sr", void_ftype_usint_usint, ARC_BUILTIN_SR);
5104 def_mbuiltin (TARGET_ARC700,"__builtin_arc_trap_s", void_ftype_usint, ARC_BUILTIN_TRAP_S);
5105 def_mbuiltin (TARGET_ARC700,"__builtin_arc_unimp_s", void_ftype_void, ARC_BUILTIN_UNIMP_S);
5106 def_mbuiltin (1,"__builtin_arc_aligned", int_ftype_pcvoid_int, ARC_BUILTIN_ALIGNED);
5107
5108 if (TARGET_SIMD_SET)
5109 arc_init_simd_builtins ();
5110}
5111
ef4bddc2 5112static rtx arc_expand_simd_builtin (tree, rtx, rtx, machine_mode, int);
526b7aee
SV
5113
5114/* Expand an expression EXP that calls a built-in function,
5115 with result going to TARGET if that's convenient
5116 (and in mode MODE if that's convenient).
5117 SUBTARGET may be used as the target for computing one of EXP's operands.
5118 IGNORE is nonzero if the value is to be ignored. */
5119
5120static rtx
5121arc_expand_builtin (tree exp,
5122 rtx target,
5123 rtx subtarget,
ef4bddc2 5124 machine_mode mode,
526b7aee
SV
5125 int ignore)
5126{
5127 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
5128 tree arg0;
5129 tree arg1;
5130 rtx op0;
5131 rtx op1;
5132 int fcode = DECL_FUNCTION_CODE (fndecl);
5133 int icode;
ef4bddc2
RS
5134 machine_mode mode0;
5135 machine_mode mode1;
526b7aee
SV
5136
5137 if (fcode > ARC_SIMD_BUILTIN_BEGIN && fcode < ARC_SIMD_BUILTIN_END)
5138 return arc_expand_simd_builtin (exp, target, subtarget, mode, ignore);
5139
5140 switch (fcode)
5141 {
5142 case ARC_BUILTIN_NOP:
5143 emit_insn (gen_nop ());
5144 return NULL_RTX;
5145
5146 case ARC_BUILTIN_NORM:
5147 icode = CODE_FOR_clrsbsi2;
5148 arg0 = CALL_EXPR_ARG (exp, 0);
5149 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5150 mode0 = insn_data[icode].operand[1].mode;
5151 target = gen_reg_rtx (SImode);
5152
5153 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5154 op0 = copy_to_mode_reg (mode0, op0);
5155
5156 emit_insn (gen_clrsbsi2 (target, op0));
5157 return target;
5158
5159 case ARC_BUILTIN_NORMW:
5160
5161 /* FIXME : This should all be HImode, not SImode. */
5162 icode = CODE_FOR_normw;
5163 arg0 = CALL_EXPR_ARG (exp, 0);
5164 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5165 mode0 = insn_data[icode].operand[1].mode;
5166 target = gen_reg_rtx (SImode);
5167
5168 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5169 op0 = copy_to_mode_reg (mode0, convert_to_mode (mode0, op0,0));
5170
5171 emit_insn (gen_normw (target, op0));
5172 return target;
5173
5174 case ARC_BUILTIN_MUL64:
5175 icode = CODE_FOR_mul64;
5176 arg0 = CALL_EXPR_ARG (exp, 0);
5177 arg1 = CALL_EXPR_ARG (exp, 1);
5178 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5179 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5180
5181 mode0 = insn_data[icode].operand[0].mode;
5182 mode1 = insn_data[icode].operand[1].mode;
5183
5184 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
5185 op0 = copy_to_mode_reg (mode0, op0);
5186
5187 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5188 op1 = copy_to_mode_reg (mode1, op1);
5189
5190 emit_insn (gen_mul64 (op0,op1));
5191 return NULL_RTX;
5192
5193 case ARC_BUILTIN_MULU64:
5194 icode = CODE_FOR_mulu64;
5195 arg0 = CALL_EXPR_ARG (exp, 0);
5196 arg1 = CALL_EXPR_ARG (exp, 1);
5197 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5198 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5199
5200 mode0 = insn_data[icode].operand[0].mode;
5201 mode1 = insn_data[icode].operand[1].mode;
5202
5203 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
5204 op0 = copy_to_mode_reg (mode0, op0);
5205
5206 if (! (*insn_data[icode].operand[0].predicate) (op1, mode1))
5207 op1 = copy_to_mode_reg (mode1, op1);
5208
5209 emit_insn (gen_mulu64 (op0,op1));
5210 return NULL_RTX;
5211
5212 case ARC_BUILTIN_RTIE:
5213 icode = CODE_FOR_rtie;
5214 emit_insn (gen_rtie (const1_rtx));
5215 return NULL_RTX;
5216
5217 case ARC_BUILTIN_SYNC:
5218 icode = CODE_FOR_sync;
5219 emit_insn (gen_sync (const1_rtx));
5220 return NULL_RTX;
5221
5222 case ARC_BUILTIN_SWAP:
5223 icode = CODE_FOR_swap;
5224 arg0 = CALL_EXPR_ARG (exp, 0);
5225 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5226 mode0 = insn_data[icode].operand[1].mode;
5227 target = gen_reg_rtx (SImode);
5228
5229 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5230 op0 = copy_to_mode_reg (mode0, op0);
5231
5232 emit_insn (gen_swap (target, op0));
5233 return target;
5234
5235 case ARC_BUILTIN_DIVAW:
5236 icode = CODE_FOR_divaw;
5237 arg0 = CALL_EXPR_ARG (exp, 0);
5238 arg1 = CALL_EXPR_ARG (exp, 1);
5239
5240 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5241 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5242 target = gen_reg_rtx (SImode);
5243
5244 mode0 = insn_data[icode].operand[0].mode;
5245 mode1 = insn_data[icode].operand[1].mode;
5246
5247 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
5248 op0 = copy_to_mode_reg (mode0, op0);
5249
5250 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5251 op1 = copy_to_mode_reg (mode1, op1);
5252
5253 emit_insn (gen_divaw (target, op0, op1));
5254 return target;
5255
5256 case ARC_BUILTIN_BRK:
5257 icode = CODE_FOR_brk;
5258 emit_insn (gen_brk (const1_rtx));
5259 return NULL_RTX;
5260
5261 case ARC_BUILTIN_SLEEP:
5262 icode = CODE_FOR_sleep;
5263 arg0 = CALL_EXPR_ARG (exp, 0);
5264
5265 fold (arg0);
5266
5267 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5268 mode0 = insn_data[icode].operand[1].mode;
5269
5270 emit_insn (gen_sleep (op0));
5271 return NULL_RTX;
5272
5273 case ARC_BUILTIN_SWI:
5274 icode = CODE_FOR_swi;
5275 emit_insn (gen_swi (const1_rtx));
5276 return NULL_RTX;
5277
5278 case ARC_BUILTIN_FLAG:
5279 icode = CODE_FOR_flag;
5280 arg0 = CALL_EXPR_ARG (exp, 0);
5281 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5282 mode0 = insn_data[icode].operand[0].mode;
5283
5284 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
5285 op0 = copy_to_mode_reg (mode0, op0);
5286
5287 emit_insn (gen_flag (op0));
5288 return NULL_RTX;
5289
5290 case ARC_BUILTIN_CORE_READ:
5291 icode = CODE_FOR_core_read;
5292 arg0 = CALL_EXPR_ARG (exp, 0);
5293 target = gen_reg_rtx (SImode);
5294
5295 fold (arg0);
5296
5297 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5298 mode0 = insn_data[icode].operand[1].mode;
5299
5300 emit_insn (gen_core_read (target, op0));
5301 return target;
5302
5303 case ARC_BUILTIN_CORE_WRITE:
5304 icode = CODE_FOR_core_write;
5305 arg0 = CALL_EXPR_ARG (exp, 0);
5306 arg1 = CALL_EXPR_ARG (exp, 1);
5307
5308 fold (arg1);
5309
5310 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5311 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5312
5313 mode0 = insn_data[icode].operand[0].mode;
5314 mode1 = insn_data[icode].operand[1].mode;
5315
5316 emit_insn (gen_core_write (op0, op1));
5317 return NULL_RTX;
5318
5319 case ARC_BUILTIN_LR:
5320 icode = CODE_FOR_lr;
5321 arg0 = CALL_EXPR_ARG (exp, 0);
5322 target = gen_reg_rtx (SImode);
5323
5324 fold (arg0);
5325
5326 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5327 mode0 = insn_data[icode].operand[1].mode;
5328
5329 emit_insn (gen_lr (target, op0));
5330 return target;
5331
5332 case ARC_BUILTIN_SR:
5333 icode = CODE_FOR_sr;
5334 arg0 = CALL_EXPR_ARG (exp, 0);
5335 arg1 = CALL_EXPR_ARG (exp, 1);
5336
5337 fold (arg1);
5338
5339 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5340 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5341
5342 mode0 = insn_data[icode].operand[0].mode;
5343 mode1 = insn_data[icode].operand[1].mode;
5344
5345 emit_insn (gen_sr (op0, op1));
5346 return NULL_RTX;
5347
5348 case ARC_BUILTIN_TRAP_S:
5349 icode = CODE_FOR_trap_s;
5350 arg0 = CALL_EXPR_ARG (exp, 0);
5351
5352 fold (arg0);
5353
5354 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5355 mode0 = insn_data[icode].operand[1].mode;
5356
5357 /* We don't give an error for non-cost values here because
5358 we still want to allow things to be fixed up by later inlining /
5359 constant folding / dead code elimination. */
5360 if (CONST_INT_P (op0) && !satisfies_constraint_L (op0))
5361 {
5362 /* Keep this message in sync with the one in arc.md:trap_s,
5363 because *.md files don't get scanned by exgettext. */
5364 error ("operand to trap_s should be an unsigned 6-bit value");
5365 }
5366 emit_insn (gen_trap_s (op0));
5367 return NULL_RTX;
5368
5369 case ARC_BUILTIN_UNIMP_S:
5370 icode = CODE_FOR_unimp_s;
5371 emit_insn (gen_unimp_s (const1_rtx));
5372 return NULL_RTX;
5373
5374 case ARC_BUILTIN_ALIGNED:
5375 /* __builtin_arc_aligned (void* val, int alignval) */
5376 arg0 = CALL_EXPR_ARG (exp, 0);
5377 arg1 = CALL_EXPR_ARG (exp, 1);
5378 fold (arg1);
5379 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5380 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
5381 target = gen_reg_rtx (SImode);
5382
5383 if (!CONST_INT_P (op1))
5384 {
5385 /* If we can't fold the alignment to a constant integer
5386 whilst optimizing, this is probably a user error. */
5387 if (optimize)
5388 warning (0, "__builtin_arc_aligned with non-constant alignment");
5389 }
5390 else
5391 {
5392 HOST_WIDE_INT alignTest = INTVAL (op1);
5393 /* Check alignTest is positive, and a power of two. */
5394 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
5395 {
5396 error ("invalid alignment value for __builtin_arc_aligned");
5397 return NULL_RTX;
5398 }
5399
5400 if (CONST_INT_P (op0))
5401 {
5402 HOST_WIDE_INT pnt = INTVAL (op0);
5403
5404 if ((pnt & (alignTest - 1)) == 0)
5405 return const1_rtx;
5406 }
5407 else
5408 {
5409 unsigned align = get_pointer_alignment (arg0);
5410 unsigned numBits = alignTest * BITS_PER_UNIT;
5411
5412 if (align && align >= numBits)
5413 return const1_rtx;
5414 /* Another attempt to ascertain alignment. Check the type
5415 we are pointing to. */
5416 if (POINTER_TYPE_P (TREE_TYPE (arg0))
5417 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
5418 return const1_rtx;
5419 }
5420 }
5421
5422 /* Default to false. */
5423 return const0_rtx;
5424
5425 default:
5426 break;
5427 }
5428
5429 /* @@@ Should really do something sensible here. */
5430 return NULL_RTX;
5431}
5432
5433/* Returns true if the operands[opno] is a valid compile-time constant to be
5434 used as register number in the code for builtins. Else it flags an error
5435 and returns false. */
5436
5437bool
5438check_if_valid_regno_const (rtx *operands, int opno)
5439{
5440
5441 switch (GET_CODE (operands[opno]))
5442 {
5443 case SYMBOL_REF :
5444 case CONST :
5445 case CONST_INT :
5446 return true;
5447 default:
5448 error ("register number must be a compile-time constant. Try giving higher optimization levels");
5449 break;
5450 }
5451 return false;
5452}
5453
5454/* Check that after all the constant folding, whether the operand to
5455 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
5456
5457bool
5458check_if_valid_sleep_operand (rtx *operands, int opno)
5459{
5460 switch (GET_CODE (operands[opno]))
5461 {
5462 case CONST :
5463 case CONST_INT :
5464 if( UNSIGNED_INT6 (INTVAL (operands[opno])))
5465 return true;
5466 default:
40fecdd6
JM
5467 fatal_error (input_location,
5468 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
526b7aee
SV
5469 break;
5470 }
5471 return false;
5472}
5473
5474/* Return true if it is ok to make a tail-call to DECL. */
5475
5476static bool
5477arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
5478 tree exp ATTRIBUTE_UNUSED)
5479{
5480 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
5481 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
5482 return false;
5483
5484 /* Everything else is ok. */
5485 return true;
5486}
5487
5488/* Output code to add DELTA to the first argument, and then jump
5489 to FUNCTION. Used for C++ multiple inheritance. */
5490
5491static void
5492arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
5493 HOST_WIDE_INT delta,
5494 HOST_WIDE_INT vcall_offset,
5495 tree function)
5496{
5497 int mi_delta = delta;
5498 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
5499 int shift = 0;
5500 int this_regno
5501 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
5502 rtx fnaddr;
5503
5504 if (mi_delta < 0)
5505 mi_delta = - mi_delta;
5506
5507 /* Add DELTA. When possible use a plain add, otherwise load it into
5508 a register first. */
5509
5510 while (mi_delta != 0)
5511 {
5512 if ((mi_delta & (3 << shift)) == 0)
5513 shift += 2;
5514 else
5515 {
5516 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
5517 mi_op, reg_names[this_regno], reg_names[this_regno],
5518 mi_delta & (0xff << shift));
5519 mi_delta &= ~(0xff << shift);
5520 shift += 8;
5521 }
5522 }
5523
5524 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
5525 if (vcall_offset != 0)
5526 {
5527 /* ld r12,[this] --> temp = *this
5528 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
5529 ld r12,[r12]
5530 add this,this,r12 --> this+ = *(*this + vcall_offset) */
5531 asm_fprintf (file, "\tld\t%s, [%s]\n",
5532 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
dfca07ea 5533 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
526b7aee
SV
5534 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
5535 asm_fprintf (file, "\tld\t%s, [%s]\n",
5536 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
5537 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
5538 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
5539 }
5540
5541 fnaddr = XEXP (DECL_RTL (function), 0);
5542
5543 if (arc_is_longcall_p (fnaddr))
5544 fputs ("\tj\t", file);
5545 else
5546 fputs ("\tb\t", file);
5547 assemble_name (file, XSTR (fnaddr, 0));
5548 fputc ('\n', file);
5549}
5550
5551/* Return true if a 32 bit "long_call" should be generated for
5552 this calling SYM_REF. We generate a long_call if the function:
5553
5554 a. has an __attribute__((long call))
5555 or b. the -mlong-calls command line switch has been specified
5556
5557 However we do not generate a long call if the function has an
5558 __attribute__ ((short_call)) or __attribute__ ((medium_call))
5559
5560 This function will be called by C fragments contained in the machine
5561 description file. */
5562
5563bool
5564arc_is_longcall_p (rtx sym_ref)
5565{
5566 if (GET_CODE (sym_ref) != SYMBOL_REF)
5567 return false;
5568
5569 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
5570 || (TARGET_LONG_CALLS_SET
5571 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
5572 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
5573
5574}
5575
5576/* Likewise for short calls. */
5577
5578bool
5579arc_is_shortcall_p (rtx sym_ref)
5580{
5581 if (GET_CODE (sym_ref) != SYMBOL_REF)
5582 return false;
5583
5584 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
5585 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
5586 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
5587 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
5588
5589}
5590
5591/* Emit profiling code for calling CALLEE. Return true if a special
5592 call pattern needs to be generated. */
5593
5594bool
5595arc_profile_call (rtx callee)
5596{
5597 rtx from = XEXP (DECL_RTL (current_function_decl), 0);
5598
5599 if (TARGET_UCB_MCOUNT)
5600 /* Profiling is done by instrumenting the callee. */
5601 return false;
5602
5603 if (CONSTANT_P (callee))
5604 {
5605 rtx count_ptr
5606 = gen_rtx_CONST (Pmode,
5607 gen_rtx_UNSPEC (Pmode,
5608 gen_rtvec (3, from, callee,
5609 CONST0_RTX (Pmode)),
5610 UNSPEC_PROF));
5611 rtx counter = gen_rtx_MEM (SImode, count_ptr);
5612 /* ??? The increment would better be done atomically, but as there is
5613 no proper hardware support, that would be too expensive. */
5614 emit_move_insn (counter,
5615 force_reg (SImode, plus_constant (SImode, counter, 1)));
5616 return false;
5617 }
5618 else
5619 {
5620 rtx count_list_ptr
5621 = gen_rtx_CONST (Pmode,
5622 gen_rtx_UNSPEC (Pmode,
5623 gen_rtvec (3, from, CONST0_RTX (Pmode),
5624 CONST0_RTX (Pmode)),
5625 UNSPEC_PROF));
5626 emit_move_insn (gen_rtx_REG (Pmode, 8), count_list_ptr);
5627 emit_move_insn (gen_rtx_REG (Pmode, 9), callee);
5628 return true;
5629 }
5630}
5631
5632/* Worker function for TARGET_RETURN_IN_MEMORY. */
5633
5634static bool
5635arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
5636{
5637 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
5638 return true;
5639 else
5640 {
5641 HOST_WIDE_INT size = int_size_in_bytes (type);
5642 return (size == -1 || size > 8);
5643 }
5644}
5645
5646
5647/* This was in rtlanal.c, and can go in there when we decide we want
5648 to submit the change for inclusion in the GCC tree. */
5649/* Like note_stores, but allow the callback to have side effects on the rtl
5650 (like the note_stores of yore):
5651 Call FUN on each register or MEM that is stored into or clobbered by X.
5652 (X would be the pattern of an insn). DATA is an arbitrary pointer,
5653 ignored by note_stores, but passed to FUN.
5654 FUN may alter parts of the RTL.
5655
5656 FUN receives three arguments:
5657 1. the REG, MEM, CC0 or PC being stored in or clobbered,
5658 2. the SET or CLOBBER rtx that does the store,
5659 3. the pointer DATA provided to note_stores.
5660
5661 If the item being stored in or clobbered is a SUBREG of a hard register,
5662 the SUBREG will be passed. */
5663
5664/* For now. */ static
5665void
5666walk_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
5667{
5668 int i;
5669
5670 if (GET_CODE (x) == COND_EXEC)
5671 x = COND_EXEC_CODE (x);
5672
5673 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
5674 {
5675 rtx dest = SET_DEST (x);
5676
5677 while ((GET_CODE (dest) == SUBREG
5678 && (!REG_P (SUBREG_REG (dest))
5679 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
5680 || GET_CODE (dest) == ZERO_EXTRACT
5681 || GET_CODE (dest) == STRICT_LOW_PART)
5682 dest = XEXP (dest, 0);
5683
5684 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
5685 each of whose first operand is a register. */
5686 if (GET_CODE (dest) == PARALLEL)
5687 {
5688 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
5689 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
5690 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
5691 }
5692 else
5693 (*fun) (dest, x, data);
5694 }
5695
5696 else if (GET_CODE (x) == PARALLEL)
5697 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
5698 walk_stores (XVECEXP (x, 0, i), fun, data);
5699}
5700
5701static bool
5702arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
ef4bddc2 5703 machine_mode mode ATTRIBUTE_UNUSED,
526b7aee
SV
5704 const_tree type,
5705 bool named ATTRIBUTE_UNUSED)
5706{
5707 return (type != 0
5708 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
5709 || TREE_ADDRESSABLE (type)));
5710}
5711
1d0216c8
RS
5712/* Implement TARGET_CAN_USE_DOLOOP_P. */
5713
5714static bool
807e902e 5715arc_can_use_doloop_p (const widest_int &iterations, const widest_int &,
1d0216c8
RS
5716 unsigned int loop_depth, bool entered_at_top)
5717{
5718 if (loop_depth > 1)
5719 return false;
5720 /* Setting up the loop with two sr instructions costs 6 cycles. */
5721 if (TARGET_ARC700
5722 && !entered_at_top
807e902e
KZ
5723 && wi::gtu_p (iterations, 0)
5724 && wi::leu_p (iterations, flag_pic ? 6 : 3))
1d0216c8
RS
5725 return false;
5726 return true;
5727}
526b7aee
SV
5728
5729/* NULL if INSN insn is valid within a low-overhead loop.
5730 Otherwise return why doloop cannot be applied. */
5731
5732static const char *
ac44248e 5733arc_invalid_within_doloop (const rtx_insn *insn)
526b7aee
SV
5734{
5735 if (CALL_P (insn))
5736 return "Function call in the loop.";
5737 return NULL;
5738}
5739
5740static int arc_reorg_in_progress = 0;
5741
5742/* ARC's machince specific reorg function. */
5743
5744static void
5745arc_reorg (void)
5746{
b3458f61
DM
5747 rtx_insn *insn;
5748 rtx pattern;
526b7aee
SV
5749 rtx pc_target;
5750 long offset;
5751 int changed;
5752
5753 cfun->machine->arc_reorg_started = 1;
5754 arc_reorg_in_progress = 1;
5755
5756 /* Emit special sections for profiling. */
5757 if (crtl->profile)
5758 {
5759 section *save_text_section;
b3458f61 5760 rtx_insn *insn;
526b7aee
SV
5761 int size = get_max_uid () >> 4;
5762 htab_t htab = htab_create (size, unspec_prof_hash, unspec_prof_htab_eq,
5763 NULL);
5764
5765 save_text_section = in_section;
5766 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5767 if (NONJUMP_INSN_P (insn))
5768 walk_stores (PATTERN (insn), write_profile_sections, htab);
5769 if (htab_elements (htab))
5770 in_section = 0;
5771 switch_to_section (save_text_section);
5772 htab_delete (htab);
5773 }
5774
5775 /* Link up loop ends with their loop start. */
5776 {
5777 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5778 if (GET_CODE (insn) == JUMP_INSN
5779 && recog_memoized (insn) == CODE_FOR_doloop_end_i)
5780 {
b3458f61
DM
5781 rtx_insn *top_label
5782 = as_a <rtx_insn *> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0));
526b7aee 5783 rtx num = GEN_INT (CODE_LABEL_NUMBER (top_label));
b3458f61
DM
5784 rtx_insn *lp, *prev = prev_nonnote_insn (top_label);
5785 rtx_insn *lp_simple = NULL;
5786 rtx_insn *next = NULL;
526b7aee
SV
5787 rtx op0 = XEXP (XVECEXP (PATTERN (insn), 0, 1), 0);
5788 HOST_WIDE_INT loop_end_id
5789 = -INTVAL (XEXP (XVECEXP (PATTERN (insn), 0, 4), 0));
5790 int seen_label = 0;
5791
5792 for (lp = prev;
5793 (lp && NONJUMP_INSN_P (lp)
5794 && recog_memoized (lp) != CODE_FOR_doloop_begin_i);
5795 lp = prev_nonnote_insn (lp))
5796 ;
5797 if (!lp || !NONJUMP_INSN_P (lp)
5798 || dead_or_set_regno_p (lp, LP_COUNT))
5799 {
b3458f61 5800 for (prev = next = insn, lp = NULL ; prev || next;)
526b7aee
SV
5801 {
5802 if (prev)
5803 {
5804 if (NONJUMP_INSN_P (prev)
5805 && recog_memoized (prev) == CODE_FOR_doloop_begin_i
5806 && (INTVAL (XEXP (XVECEXP (PATTERN (prev), 0, 5), 0))
5807 == loop_end_id))
5808 {
5809 lp = prev;
5810 break;
5811 }
5812 else if (LABEL_P (prev))
5813 seen_label = 1;
5814 prev = prev_nonnote_insn (prev);
5815 }
5816 if (next)
5817 {
5818 if (NONJUMP_INSN_P (next)
5819 && recog_memoized (next) == CODE_FOR_doloop_begin_i
5820 && (INTVAL (XEXP (XVECEXP (PATTERN (next), 0, 5), 0))
5821 == loop_end_id))
5822 {
5823 lp = next;
5824 break;
5825 }
5826 next = next_nonnote_insn (next);
5827 }
5828 }
b3458f61 5829 prev = NULL;
526b7aee
SV
5830 }
5831 else
5832 lp_simple = lp;
5833 if (lp && !dead_or_set_regno_p (lp, LP_COUNT))
5834 {
5835 rtx begin_cnt = XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0);
5836 if (INTVAL (XEXP (XVECEXP (PATTERN (lp), 0, 4), 0)))
5837 /* The loop end insn has been duplicated. That can happen
5838 when there is a conditional block at the very end of
5839 the loop. */
5840 goto failure;
5841 /* If Register allocation failed to allocate to the right
5842 register, There is no point into teaching reload to
5843 fix this up with reloads, as that would cost more
5844 than using an ordinary core register with the
5845 doloop_fallback pattern. */
5846 if ((true_regnum (op0) != LP_COUNT || !REG_P (begin_cnt))
5847 /* Likewise, if the loop setup is evidently inside the loop,
5848 we loose. */
5849 || (!lp_simple && lp != next && !seen_label))
5850 {
5851 remove_insn (lp);
5852 goto failure;
5853 }
5854 /* It is common that the optimizers copy the loop count from
5855 another register, and doloop_begin_i is stuck with the
5856 source of the move. Making doloop_begin_i only accept "l"
5857 is nonsentical, as this then makes reload evict the pseudo
5858 used for the loop end. The underlying cause is that the
5859 optimizers don't understand that the register allocation for
5860 doloop_begin_i should be treated as part of the loop.
5861 Try to work around this problem by verifying the previous
5862 move exists. */
5863 if (true_regnum (begin_cnt) != LP_COUNT)
5864 {
b3458f61
DM
5865 rtx_insn *mov;
5866 rtx set, note;
526b7aee
SV
5867
5868 for (mov = prev_nonnote_insn (lp); mov;
5869 mov = prev_nonnote_insn (mov))
5870 {
5871 if (!NONJUMP_INSN_P (mov))
5872 mov = 0;
5873 else if ((set = single_set (mov))
5874 && rtx_equal_p (SET_SRC (set), begin_cnt)
5875 && rtx_equal_p (SET_DEST (set), op0))
5876 break;
5877 }
5878 if (mov)
5879 {
5880 XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0) = op0;
5881 note = find_regno_note (lp, REG_DEAD, REGNO (begin_cnt));
5882 if (note)
5883 remove_note (lp, note);
5884 }
5885 else
5886 {
5887 remove_insn (lp);
5888 goto failure;
5889 }
5890 }
5891 XEXP (XVECEXP (PATTERN (insn), 0, 4), 0) = num;
5892 XEXP (XVECEXP (PATTERN (lp), 0, 4), 0) = num;
5893 if (next == lp)
5894 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const2_rtx;
5895 else if (!lp_simple)
5896 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const1_rtx;
5897 else if (prev != lp)
5898 {
5899 remove_insn (lp);
5900 add_insn_after (lp, prev, NULL);
5901 }
5902 if (!lp_simple)
5903 {
5904 XEXP (XVECEXP (PATTERN (lp), 0, 7), 0)
5905 = gen_rtx_LABEL_REF (Pmode, top_label);
5906 add_reg_note (lp, REG_LABEL_OPERAND, top_label);
5907 LABEL_NUSES (top_label)++;
5908 }
5909 /* We can avoid tedious loop start / end setting for empty loops
5910 be merely setting the loop count to its final value. */
5911 if (next_active_insn (top_label) == insn)
5912 {
5913 rtx lc_set
f7df4a84 5914 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp), 0, 3), 0),
526b7aee
SV
5915 const0_rtx);
5916
b3458f61 5917 rtx_insn *lc_set_insn = emit_insn_before (lc_set, insn);
526b7aee
SV
5918 delete_insn (lp);
5919 delete_insn (insn);
b3458f61 5920 insn = lc_set_insn;
526b7aee
SV
5921 }
5922 /* If the loop is non-empty with zero length, we can't make it
5923 a zero-overhead loop. That can happen for empty asms. */
5924 else
5925 {
b3458f61 5926 rtx_insn *scan;
526b7aee
SV
5927
5928 for (scan = top_label;
5929 (scan && scan != insn
5930 && (!NONJUMP_INSN_P (scan) || !get_attr_length (scan)));
5931 scan = NEXT_INSN (scan));
5932 if (scan == insn)
5933 {
5934 remove_insn (lp);
5935 goto failure;
5936 }
5937 }
5938 }
5939 else
5940 {
5941 /* Sometimes the loop optimizer makes a complete hash of the
5942 loop. If it were only that the loop is not entered at the
5943 top, we could fix this up by setting LP_START with SR .
5944 However, if we can't find the loop begin were it should be,
5945 chances are that it does not even dominate the loop, but is
5946 inside the loop instead. Using SR there would kill
5947 performance.
5948 We use the doloop_fallback pattern here, which executes
5949 in two cycles on the ARC700 when predicted correctly. */
5950 failure:
5951 if (!REG_P (op0))
5952 {
5953 rtx op3 = XEXP (XVECEXP (PATTERN (insn), 0, 5), 0);
5954
5955 emit_insn_before (gen_move_insn (op3, op0), insn);
5956 PATTERN (insn)
5957 = gen_doloop_fallback_m (op3, JUMP_LABEL (insn), op0);
5958 }
5959 else
5960 XVEC (PATTERN (insn), 0)
5961 = gen_rtvec (2, XVECEXP (PATTERN (insn), 0, 0),
5962 XVECEXP (PATTERN (insn), 0, 1));
5963 INSN_CODE (insn) = -1;
5964 }
5965 }
5966 }
5967
5968/* FIXME: should anticipate ccfsm action, generate special patterns for
5969 to-be-deleted branches that have no delay slot and have at least the
5970 length of the size increase forced on other insns that are conditionalized.
5971 This can also have an insn_list inside that enumerates insns which are
5972 not actually conditionalized because the destinations are dead in the
5973 not-execute case.
5974 Could also tag branches that we want to be unaligned if they get no delay
5975 slot, or even ones that we don't want to do delay slot sheduling for
5976 because we can unalign them.
5977
5978 However, there are cases when conditional execution is only possible after
5979 delay slot scheduling:
5980
5981 - If a delay slot is filled with a nocond/set insn from above, the previous
5982 basic block can become elegible for conditional execution.
5983 - If a delay slot is filled with a nocond insn from the fall-through path,
5984 the branch with that delay slot can become eligble for conditional
5985 execution (however, with the same sort of data flow analysis that dbr
5986 does, we could have figured out before that we don't need to
5987 conditionalize this insn.)
5988 - If a delay slot insn is filled with an insn from the target, the
5989 target label gets its uses decremented (even deleted if falling to zero),
5990 thus possibly creating more condexec opportunities there.
5991 Therefore, we should still be prepared to apply condexec optimization on
5992 non-prepared branches if the size increase of conditionalized insns is no
5993 more than the size saved from eliminating the branch. An invocation option
5994 could also be used to reserve a bit of extra size for condbranches so that
5995 this'll work more often (could also test in arc_reorg if the block is
5996 'close enough' to be eligible for condexec to make this likely, and
5997 estimate required size increase). */
5998 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
5999 if (TARGET_NO_BRCC_SET)
6000 return;
6001
6002 do
6003 {
6004 init_insn_lengths();
6005 changed = 0;
6006
6007 if (optimize > 1 && !TARGET_NO_COND_EXEC)
6008 {
6009 arc_ifcvt ();
6010 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
6011 df_finish_pass ((flags & TODO_df_verify) != 0);
6012 }
6013
6014 /* Call shorten_branches to calculate the insn lengths. */
6015 shorten_branches (get_insns());
6016 cfun->machine->ccfsm_current_insn = NULL_RTX;
6017
6018 if (!INSN_ADDRESSES_SET_P())
40fecdd6 6019 fatal_error (input_location, "Insn addresses not set after shorten_branches");
526b7aee
SV
6020
6021 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6022 {
6023 rtx label;
6024 enum attr_type insn_type;
6025
6026 /* If a non-jump insn (or a casesi jump table), continue. */
6027 if (GET_CODE (insn) != JUMP_INSN ||
6028 GET_CODE (PATTERN (insn)) == ADDR_VEC
6029 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
6030 continue;
6031
6032 /* If we already have a brcc, note if it is suitable for brcc_s.
6033 Be a bit generous with the brcc_s range so that we can take
6034 advantage of any code shortening from delay slot scheduling. */
6035 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
6036 {
6037 rtx pat = PATTERN (insn);
6038 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
6039 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
6040
6041 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6042 if ((offset >= -140 && offset < 140)
6043 && rtx_equal_p (XEXP (op, 1), const0_rtx)
6044 && compact_register_operand (XEXP (op, 0), VOIDmode)
6045 && equality_comparison_operator (op, VOIDmode))
6046 PUT_MODE (*ccp, CC_Zmode);
6047 else if (GET_MODE (*ccp) == CC_Zmode)
6048 PUT_MODE (*ccp, CC_ZNmode);
6049 continue;
6050 }
6051 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
6052 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
6053 continue;
6054
6055 /* OK. so we have a jump insn. */
6056 /* We need to check that it is a bcc. */
6057 /* Bcc => set (pc) (if_then_else ) */
6058 pattern = PATTERN (insn);
6059 if (GET_CODE (pattern) != SET
6060 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
6061 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
6062 continue;
6063
6064 /* Now check if the jump is beyond the s9 range. */
339ba33b 6065 if (CROSSING_JUMP_P (insn))
526b7aee
SV
6066 continue;
6067 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
6068
6069 if(offset > 253 || offset < -254)
6070 continue;
6071
6072 pc_target = SET_SRC (pattern);
6073
6074 /* Now go back and search for the set cc insn. */
6075
6076 label = XEXP (pc_target, 1);
6077
6078 {
b3458f61
DM
6079 rtx pat;
6080 rtx_insn *scan, *link_insn = NULL;
526b7aee
SV
6081
6082 for (scan = PREV_INSN (insn);
6083 scan && GET_CODE (scan) != CODE_LABEL;
6084 scan = PREV_INSN (scan))
6085 {
6086 if (! INSN_P (scan))
6087 continue;
6088 pat = PATTERN (scan);
6089 if (GET_CODE (pat) == SET
6090 && cc_register (SET_DEST (pat), VOIDmode))
6091 {
6092 link_insn = scan;
6093 break;
6094 }
6095 }
6096 if (! link_insn)
6097 continue;
6098 else
6099 /* Check if this is a data dependency. */
6100 {
6101 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
6102 rtx cmp0, cmp1;
6103
6104 /* Ok this is the set cc. copy args here. */
6105 op = XEXP (pc_target, 0);
6106
6107 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
6108 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
6109 if (GET_CODE (op0) == ZERO_EXTRACT
6110 && XEXP (op0, 1) == const1_rtx
6111 && (GET_CODE (op) == EQ
6112 || GET_CODE (op) == NE))
6113 {
6114 /* btst / b{eq,ne} -> bbit{0,1} */
6115 op0 = XEXP (cmp0, 0);
6116 op1 = XEXP (cmp0, 2);
6117 }
6118 else if (!register_operand (op0, VOIDmode)
6119 || !general_operand (op1, VOIDmode))
6120 continue;
6121 /* Be careful not to break what cmpsfpx_raw is
6122 trying to create for checking equality of
6123 single-precision floats. */
6124 else if (TARGET_SPFP
6125 && GET_MODE (op0) == SFmode
6126 && GET_MODE (op1) == SFmode)
6127 continue;
6128
6129 /* None of the two cmp operands should be set between the
6130 cmp and the branch. */
6131 if (reg_set_between_p (op0, link_insn, insn))
6132 continue;
6133
6134 if (reg_set_between_p (op1, link_insn, insn))
6135 continue;
6136
6137 /* Since the MODE check does not work, check that this is
6138 CC reg's last set location before insn, and also no
6139 instruction between the cmp and branch uses the
6140 condition codes. */
6141 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
6142 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
6143 continue;
6144
6145 /* CC reg should be dead after insn. */
6146 if (!find_regno_note (insn, REG_DEAD, CC_REG))
6147 continue;
6148
6149 op = gen_rtx_fmt_ee (GET_CODE (op),
6150 GET_MODE (op), cmp0, cmp1);
6151 /* If we create a LIMM where there was none before,
6152 we only benefit if we can avoid a scheduling bubble
6153 for the ARC600. Otherwise, we'd only forgo chances
6154 at short insn generation, and risk out-of-range
6155 branches. */
6156 if (!brcc_nolimm_operator (op, VOIDmode)
6157 && !long_immediate_operand (op1, VOIDmode)
6158 && (TARGET_ARC700
6159 || next_active_insn (link_insn) != insn))
6160 continue;
6161
6162 /* Emit bbit / brcc (or brcc_s if possible).
6163 CC_Zmode indicates that brcc_s is possible. */
6164
6165 if (op0 != cmp0)
6166 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
6167 else if ((offset >= -140 && offset < 140)
6168 && rtx_equal_p (op1, const0_rtx)
6169 && compact_register_operand (op0, VOIDmode)
6170 && (GET_CODE (op) == EQ
6171 || GET_CODE (op) == NE))
6172 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
6173 else
6174 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
6175
6176 brcc_insn
6177 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
f7df4a84 6178 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
526b7aee
SV
6179 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
6180 brcc_insn
6181 = gen_rtx_PARALLEL
6182 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
6183 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
6184
6185 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
6186 note = find_reg_note (insn, REG_BR_PROB, 0);
6187 if (note)
6188 {
6189 XEXP (note, 1) = REG_NOTES (brcc_insn);
6190 REG_NOTES (brcc_insn) = note;
6191 }
6192 note = find_reg_note (link_insn, REG_DEAD, op0);
6193 if (note)
6194 {
6195 remove_note (link_insn, note);
6196 XEXP (note, 1) = REG_NOTES (brcc_insn);
6197 REG_NOTES (brcc_insn) = note;
6198 }
6199 note = find_reg_note (link_insn, REG_DEAD, op1);
6200 if (note)
6201 {
6202 XEXP (note, 1) = REG_NOTES (brcc_insn);
6203 REG_NOTES (brcc_insn) = note;
6204 }
6205
6206 changed = 1;
6207
6208 /* Delete the bcc insn. */
6209 set_insn_deleted (insn);
6210
6211 /* Delete the cmp insn. */
6212 set_insn_deleted (link_insn);
6213
6214 }
6215 }
6216 }
6217 /* Clear out insn_addresses. */
6218 INSN_ADDRESSES_FREE ();
6219
6220 } while (changed);
6221
6222 if (INSN_ADDRESSES_SET_P())
40fecdd6 6223 fatal_error (input_location, "insn addresses not freed");
526b7aee
SV
6224
6225 arc_reorg_in_progress = 0;
6226}
6227
6228 /* Check if the operands are valid for BRcc.d generation
6229 Valid Brcc.d patterns are
6230 Brcc.d b, c, s9
6231 Brcc.d b, u6, s9
6232
6233 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
6234 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
6235 does not have a delay slot
6236
6237 Assumed precondition: Second operand is either a register or a u6 value. */
6238
6239bool
6240valid_brcc_with_delay_p (rtx *operands)
6241{
6242 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
6243 return false;
6244 return brcc_nolimm_operator (operands[0], VOIDmode);
6245}
6246
6247/* ??? Hack. This should no really be here. See PR32143. */
6248static bool
6249arc_decl_anon_ns_mem_p (const_tree decl)
6250{
6251 while (1)
6252 {
6253 if (decl == NULL_TREE || decl == error_mark_node)
6254 return false;
6255 if (TREE_CODE (decl) == NAMESPACE_DECL
6256 && DECL_NAME (decl) == NULL_TREE)
6257 return true;
6258 /* Classes and namespaces inside anonymous namespaces have
6259 TREE_PUBLIC == 0, so we can shortcut the search. */
6260 else if (TYPE_P (decl))
6261 return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
6262 else if (TREE_CODE (decl) == NAMESPACE_DECL)
6263 return (TREE_PUBLIC (decl) == 0);
6264 else
6265 decl = DECL_CONTEXT (decl);
6266 }
6267}
6268
6269/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
6270 access DECL using %gp_rel(...)($gp). */
6271
6272static bool
6273arc_in_small_data_p (const_tree decl)
6274{
6275 HOST_WIDE_INT size;
6276
6277 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
6278 return false;
6279
6280
6281 /* We don't yet generate small-data references for -mabicalls. See related
6282 -G handling in override_options. */
6283 if (TARGET_NO_SDATA_SET)
6284 return false;
6285
6286 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
6287 {
6288 const char *name;
6289
6290 /* Reject anything that isn't in a known small-data section. */
f961457f 6291 name = DECL_SECTION_NAME (decl);
526b7aee
SV
6292 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
6293 return false;
6294
6295 /* If a symbol is defined externally, the assembler will use the
6296 usual -G rules when deciding how to implement macros. */
6297 if (!DECL_EXTERNAL (decl))
6298 return true;
6299 }
6300 /* Only global variables go into sdata section for now. */
6301 else if (1)
6302 {
6303 /* Don't put constants into the small data section: we want them
6304 to be in ROM rather than RAM. */
6305 if (TREE_CODE (decl) != VAR_DECL)
6306 return false;
6307
6308 if (TREE_READONLY (decl)
6309 && !TREE_SIDE_EFFECTS (decl)
6310 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
6311 return false;
6312
6313 /* TREE_PUBLIC might change after the first call, because of the patch
6314 for PR19238. */
6315 if (default_binds_local_p_1 (decl, 1)
6316 || arc_decl_anon_ns_mem_p (decl))
6317 return false;
6318
6319 /* To ensure -mvolatile-cache works
6320 ld.di does not have a gp-relative variant. */
6321 if (TREE_THIS_VOLATILE (decl))
6322 return false;
6323 }
6324
6325 /* Disable sdata references to weak variables. */
6326 if (DECL_WEAK (decl))
6327 return false;
6328
6329 size = int_size_in_bytes (TREE_TYPE (decl));
6330
6331/* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
6332/* return false; */
6333
6334 /* Allow only <=4B long data types into sdata. */
6335 return (size > 0 && size <= 4);
6336}
6337
6338/* Return true if X is a small data address that can be rewritten
6339 as a gp+symref. */
6340
6341static bool
752ae22f 6342arc_rewrite_small_data_p (const_rtx x)
526b7aee
SV
6343{
6344 if (GET_CODE (x) == CONST)
6345 x = XEXP (x, 0);
6346
6347 if (GET_CODE (x) == PLUS)
6348 {
6349 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
6350 x = XEXP (x, 0);
6351 }
6352
6353 return (GET_CODE (x) == SYMBOL_REF
6354 && SYMBOL_REF_SMALL_P(x));
6355}
6356
526b7aee
SV
6357/* If possible, rewrite OP so that it refers to small data using
6358 explicit relocations. */
6359
6360rtx
6361arc_rewrite_small_data (rtx op)
6362{
6363 op = copy_insn (op);
6733978e
RS
6364 subrtx_ptr_iterator::array_type array;
6365 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
6366 {
6367 rtx *loc = *iter;
6368 if (arc_rewrite_small_data_p (*loc))
6369 {
6370 gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
6371 *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
6372 if (loc != &op)
6373 {
6374 if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
6375 ; /* OK. */
6376 else if (GET_CODE (op) == MEM
6377 && GET_CODE (XEXP (op, 0)) == PLUS
6378 && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
6379 *loc = force_reg (Pmode, *loc);
6380 else
6381 gcc_unreachable ();
6382 }
6383 iter.skip_subrtxes ();
6384 }
6385 else if (GET_CODE (*loc) == PLUS
6386 && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
6387 iter.skip_subrtxes ();
6388 }
526b7aee
SV
6389 return op;
6390}
6391
526b7aee
SV
6392/* Return true if OP refers to small data symbols directly, not through
6393 a PLUS. */
6394
6395bool
ef4bddc2 6396small_data_pattern (rtx op, machine_mode)
526b7aee 6397{
752ae22f
RS
6398 if (GET_CODE (op) == SEQUENCE)
6399 return false;
6400 subrtx_iterator::array_type array;
6401 FOR_EACH_SUBRTX (iter, array, op, ALL)
6402 {
6403 const_rtx x = *iter;
6404 if (GET_CODE (x) == PLUS
6405 && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
6406 iter.skip_subrtxes ();
6407 else if (arc_rewrite_small_data_p (x))
6408 return true;
6409 }
6410 return false;
526b7aee
SV
6411}
6412
6413/* Return true if OP is an acceptable memory operand for ARCompact
6414 16-bit gp-relative load instructions.
6415 op shd look like : [r26, symref@sda]
6416 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
6417 */
6418/* volatile cache option still to be handled. */
6419
6420bool
ef4bddc2 6421compact_sda_memory_operand (rtx op, machine_mode mode)
526b7aee
SV
6422{
6423 rtx addr;
6424 int size;
6425
6426 /* Eliminate non-memory operations. */
6427 if (GET_CODE (op) != MEM)
6428 return false;
6429
6430 if (mode == VOIDmode)
6431 mode = GET_MODE (op);
6432
6433 size = GET_MODE_SIZE (mode);
6434
6435 /* dword operations really put out 2 instructions, so eliminate them. */
6436 if (size > UNITS_PER_WORD)
6437 return false;
6438
6439 /* Decode the address now. */
6440 addr = XEXP (op, 0);
6441
6442 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
6443}
6444
6445/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
6446
6447void
6448arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
6449 unsigned HOST_WIDE_INT size,
6450 unsigned HOST_WIDE_INT align,
6451 unsigned HOST_WIDE_INT globalize_p)
6452{
6453 int in_small_data = arc_in_small_data_p (decl);
6454
6455 if (in_small_data)
6456 switch_to_section (get_named_section (NULL, ".sbss", 0));
6457 /* named_section (0,".sbss",0); */
6458 else
6459 switch_to_section (bss_section);
6460
6461 if (globalize_p)
6462 (*targetm.asm_out.globalize_label) (stream, name);
6463
6464 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
6465 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
6466 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
6467 ASM_OUTPUT_LABEL (stream, name);
6468
6469 if (size != 0)
6470 ASM_OUTPUT_SKIP (stream, size);
6471}
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506/* SIMD builtins support. */
6507enum simd_insn_args_type {
6508 Va_Vb_Vc,
6509 Va_Vb_rlimm,
6510 Va_Vb_Ic,
6511 Va_Vb_u6,
6512 Va_Vb_u8,
6513 Va_rlimm_u8,
6514
6515 Va_Vb,
6516
6517 void_rlimm,
6518 void_u6,
6519
6520 Da_u3_rlimm,
6521 Da_rlimm_rlimm,
6522
6523 Va_Ib_u8,
6524 void_Va_Ib_u8,
6525
6526 Va_Vb_Ic_u8,
6527 void_Va_u3_Ib_u8
6528};
6529
6530struct builtin_description
6531{
6532 enum simd_insn_args_type args_type;
6533 const enum insn_code icode;
6534 const char * const name;
6535 const enum arc_builtins code;
6536};
6537
6538static const struct builtin_description arc_simd_builtin_desc_list[] =
6539{
6540 /* VVV builtins go first. */
6541#define SIMD_BUILTIN(type, code, string, builtin) \
6542 { type,CODE_FOR_##code, "__builtin_arc_" string, \
6543 ARC_SIMD_BUILTIN_##builtin },
6544
6545 SIMD_BUILTIN (Va_Vb_Vc, vaddaw_insn, "vaddaw", VADDAW)
6546 SIMD_BUILTIN (Va_Vb_Vc, vaddw_insn, "vaddw", VADDW)
6547 SIMD_BUILTIN (Va_Vb_Vc, vavb_insn, "vavb", VAVB)
6548 SIMD_BUILTIN (Va_Vb_Vc, vavrb_insn, "vavrb", VAVRB)
6549 SIMD_BUILTIN (Va_Vb_Vc, vdifaw_insn, "vdifaw", VDIFAW)
6550 SIMD_BUILTIN (Va_Vb_Vc, vdifw_insn, "vdifw", VDIFW)
6551 SIMD_BUILTIN (Va_Vb_Vc, vmaxaw_insn, "vmaxaw", VMAXAW)
6552 SIMD_BUILTIN (Va_Vb_Vc, vmaxw_insn, "vmaxw", VMAXW)
6553 SIMD_BUILTIN (Va_Vb_Vc, vminaw_insn, "vminaw", VMINAW)
6554 SIMD_BUILTIN (Va_Vb_Vc, vminw_insn, "vminw", VMINW)
6555 SIMD_BUILTIN (Va_Vb_Vc, vmulaw_insn, "vmulaw", VMULAW)
6556 SIMD_BUILTIN (Va_Vb_Vc, vmulfaw_insn, "vmulfaw", VMULFAW)
6557 SIMD_BUILTIN (Va_Vb_Vc, vmulfw_insn, "vmulfw", VMULFW)
6558 SIMD_BUILTIN (Va_Vb_Vc, vmulw_insn, "vmulw", VMULW)
6559 SIMD_BUILTIN (Va_Vb_Vc, vsubaw_insn, "vsubaw", VSUBAW)
6560 SIMD_BUILTIN (Va_Vb_Vc, vsubw_insn, "vsubw", VSUBW)
6561 SIMD_BUILTIN (Va_Vb_Vc, vsummw_insn, "vsummw", VSUMMW)
6562 SIMD_BUILTIN (Va_Vb_Vc, vand_insn, "vand", VAND)
6563 SIMD_BUILTIN (Va_Vb_Vc, vandaw_insn, "vandaw", VANDAW)
6564 SIMD_BUILTIN (Va_Vb_Vc, vbic_insn, "vbic", VBIC)
6565 SIMD_BUILTIN (Va_Vb_Vc, vbicaw_insn, "vbicaw", VBICAW)
6566 SIMD_BUILTIN (Va_Vb_Vc, vor_insn, "vor", VOR)
6567 SIMD_BUILTIN (Va_Vb_Vc, vxor_insn, "vxor", VXOR)
6568 SIMD_BUILTIN (Va_Vb_Vc, vxoraw_insn, "vxoraw", VXORAW)
6569 SIMD_BUILTIN (Va_Vb_Vc, veqw_insn, "veqw", VEQW)
6570 SIMD_BUILTIN (Va_Vb_Vc, vlew_insn, "vlew", VLEW)
6571 SIMD_BUILTIN (Va_Vb_Vc, vltw_insn, "vltw", VLTW)
6572 SIMD_BUILTIN (Va_Vb_Vc, vnew_insn, "vnew", VNEW)
6573 SIMD_BUILTIN (Va_Vb_Vc, vmr1aw_insn, "vmr1aw", VMR1AW)
6574 SIMD_BUILTIN (Va_Vb_Vc, vmr1w_insn, "vmr1w", VMR1W)
6575 SIMD_BUILTIN (Va_Vb_Vc, vmr2aw_insn, "vmr2aw", VMR2AW)
6576 SIMD_BUILTIN (Va_Vb_Vc, vmr2w_insn, "vmr2w", VMR2W)
6577 SIMD_BUILTIN (Va_Vb_Vc, vmr3aw_insn, "vmr3aw", VMR3AW)
6578 SIMD_BUILTIN (Va_Vb_Vc, vmr3w_insn, "vmr3w", VMR3W)
6579 SIMD_BUILTIN (Va_Vb_Vc, vmr4aw_insn, "vmr4aw", VMR4AW)
6580 SIMD_BUILTIN (Va_Vb_Vc, vmr4w_insn, "vmr4w", VMR4W)
6581 SIMD_BUILTIN (Va_Vb_Vc, vmr5aw_insn, "vmr5aw", VMR5AW)
6582 SIMD_BUILTIN (Va_Vb_Vc, vmr5w_insn, "vmr5w", VMR5W)
6583 SIMD_BUILTIN (Va_Vb_Vc, vmr6aw_insn, "vmr6aw", VMR6AW)
6584 SIMD_BUILTIN (Va_Vb_Vc, vmr6w_insn, "vmr6w", VMR6W)
6585 SIMD_BUILTIN (Va_Vb_Vc, vmr7aw_insn, "vmr7aw", VMR7AW)
6586 SIMD_BUILTIN (Va_Vb_Vc, vmr7w_insn, "vmr7w", VMR7W)
6587 SIMD_BUILTIN (Va_Vb_Vc, vmrb_insn, "vmrb", VMRB)
6588 SIMD_BUILTIN (Va_Vb_Vc, vh264f_insn, "vh264f", VH264F)
6589 SIMD_BUILTIN (Va_Vb_Vc, vh264ft_insn, "vh264ft", VH264FT)
6590 SIMD_BUILTIN (Va_Vb_Vc, vh264fw_insn, "vh264fw", VH264FW)
6591 SIMD_BUILTIN (Va_Vb_Vc, vvc1f_insn, "vvc1f", VVC1F)
6592 SIMD_BUILTIN (Va_Vb_Vc, vvc1ft_insn, "vvc1ft", VVC1FT)
6593
6594 SIMD_BUILTIN (Va_Vb_rlimm, vbaddw_insn, "vbaddw", VBADDW)
6595 SIMD_BUILTIN (Va_Vb_rlimm, vbmaxw_insn, "vbmaxw", VBMAXW)
6596 SIMD_BUILTIN (Va_Vb_rlimm, vbminw_insn, "vbminw", VBMINW)
6597 SIMD_BUILTIN (Va_Vb_rlimm, vbmulaw_insn, "vbmulaw", VBMULAW)
6598 SIMD_BUILTIN (Va_Vb_rlimm, vbmulfw_insn, "vbmulfw", VBMULFW)
6599 SIMD_BUILTIN (Va_Vb_rlimm, vbmulw_insn, "vbmulw", VBMULW)
6600 SIMD_BUILTIN (Va_Vb_rlimm, vbrsubw_insn, "vbrsubw", VBRSUBW)
6601 SIMD_BUILTIN (Va_Vb_rlimm, vbsubw_insn, "vbsubw", VBSUBW)
6602
6603 /* Va, Vb, Ic instructions. */
6604 SIMD_BUILTIN (Va_Vb_Ic, vasrw_insn, "vasrw", VASRW)
6605 SIMD_BUILTIN (Va_Vb_Ic, vsr8_insn, "vsr8", VSR8)
6606 SIMD_BUILTIN (Va_Vb_Ic, vsr8aw_insn, "vsr8aw", VSR8AW)
6607
6608 /* Va, Vb, u6 instructions. */
6609 SIMD_BUILTIN (Va_Vb_u6, vasrrwi_insn, "vasrrwi", VASRRWi)
6610 SIMD_BUILTIN (Va_Vb_u6, vasrsrwi_insn, "vasrsrwi", VASRSRWi)
6611 SIMD_BUILTIN (Va_Vb_u6, vasrwi_insn, "vasrwi", VASRWi)
6612 SIMD_BUILTIN (Va_Vb_u6, vasrpwbi_insn, "vasrpwbi", VASRPWBi)
6613 SIMD_BUILTIN (Va_Vb_u6, vasrrpwbi_insn,"vasrrpwbi", VASRRPWBi)
6614 SIMD_BUILTIN (Va_Vb_u6, vsr8awi_insn, "vsr8awi", VSR8AWi)
6615 SIMD_BUILTIN (Va_Vb_u6, vsr8i_insn, "vsr8i", VSR8i)
6616
6617 /* Va, Vb, u8 (simm) instructions. */
6618 SIMD_BUILTIN (Va_Vb_u8, vmvaw_insn, "vmvaw", VMVAW)
6619 SIMD_BUILTIN (Va_Vb_u8, vmvw_insn, "vmvw", VMVW)
6620 SIMD_BUILTIN (Va_Vb_u8, vmvzw_insn, "vmvzw", VMVZW)
6621 SIMD_BUILTIN (Va_Vb_u8, vd6tapf_insn, "vd6tapf", VD6TAPF)
6622
6623 /* Va, rlimm, u8 (simm) instructions. */
6624 SIMD_BUILTIN (Va_rlimm_u8, vmovaw_insn, "vmovaw", VMOVAW)
6625 SIMD_BUILTIN (Va_rlimm_u8, vmovw_insn, "vmovw", VMOVW)
6626 SIMD_BUILTIN (Va_rlimm_u8, vmovzw_insn, "vmovzw", VMOVZW)
6627
6628 /* Va, Vb instructions. */
6629 SIMD_BUILTIN (Va_Vb, vabsaw_insn, "vabsaw", VABSAW)
6630 SIMD_BUILTIN (Va_Vb, vabsw_insn, "vabsw", VABSW)
6631 SIMD_BUILTIN (Va_Vb, vaddsuw_insn, "vaddsuw", VADDSUW)
6632 SIMD_BUILTIN (Va_Vb, vsignw_insn, "vsignw", VSIGNW)
6633 SIMD_BUILTIN (Va_Vb, vexch1_insn, "vexch1", VEXCH1)
6634 SIMD_BUILTIN (Va_Vb, vexch2_insn, "vexch2", VEXCH2)
6635 SIMD_BUILTIN (Va_Vb, vexch4_insn, "vexch4", VEXCH4)
6636 SIMD_BUILTIN (Va_Vb, vupbaw_insn, "vupbaw", VUPBAW)
6637 SIMD_BUILTIN (Va_Vb, vupbw_insn, "vupbw", VUPBW)
6638 SIMD_BUILTIN (Va_Vb, vupsbaw_insn, "vupsbaw", VUPSBAW)
6639 SIMD_BUILTIN (Va_Vb, vupsbw_insn, "vupsbw", VUPSBW)
6640
6641 /* DIb, rlimm, rlimm instructions. */
6642 SIMD_BUILTIN (Da_rlimm_rlimm, vdirun_insn, "vdirun", VDIRUN)
6643 SIMD_BUILTIN (Da_rlimm_rlimm, vdorun_insn, "vdorun", VDORUN)
6644
6645 /* DIb, limm, rlimm instructions. */
6646 SIMD_BUILTIN (Da_u3_rlimm, vdiwr_insn, "vdiwr", VDIWR)
6647 SIMD_BUILTIN (Da_u3_rlimm, vdowr_insn, "vdowr", VDOWR)
6648
6649 /* rlimm instructions. */
6650 SIMD_BUILTIN (void_rlimm, vrec_insn, "vrec", VREC)
6651 SIMD_BUILTIN (void_rlimm, vrun_insn, "vrun", VRUN)
6652 SIMD_BUILTIN (void_rlimm, vrecrun_insn, "vrecrun", VRECRUN)
6653 SIMD_BUILTIN (void_rlimm, vendrec_insn, "vendrec", VENDREC)
6654
6655 /* Va, [Ib,u8] instructions. */
6656 SIMD_BUILTIN (Va_Vb_Ic_u8, vld32wh_insn, "vld32wh", VLD32WH)
6657 SIMD_BUILTIN (Va_Vb_Ic_u8, vld32wl_insn, "vld32wl", VLD32WL)
6658 SIMD_BUILTIN (Va_Vb_Ic_u8, vld64_insn, "vld64", VLD64)
6659 SIMD_BUILTIN (Va_Vb_Ic_u8, vld32_insn, "vld32", VLD32)
6660
6661 SIMD_BUILTIN (Va_Ib_u8, vld64w_insn, "vld64w", VLD64W)
6662 SIMD_BUILTIN (Va_Ib_u8, vld128_insn, "vld128", VLD128)
6663 SIMD_BUILTIN (void_Va_Ib_u8, vst128_insn, "vst128", VST128)
6664 SIMD_BUILTIN (void_Va_Ib_u8, vst64_insn, "vst64", VST64)
6665
6666 /* Va, [Ib, u8] instructions. */
6667 SIMD_BUILTIN (void_Va_u3_Ib_u8, vst16_n_insn, "vst16_n", VST16_N)
6668 SIMD_BUILTIN (void_Va_u3_Ib_u8, vst32_n_insn, "vst32_n", VST32_N)
6669
6670 SIMD_BUILTIN (void_u6, vinti_insn, "vinti", VINTI)
6671};
6672
6673static void
6674arc_init_simd_builtins (void)
6675{
6676 int i;
6677 tree endlink = void_list_node;
6678 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node, V8HImode);
6679
6680 tree v8hi_ftype_v8hi_v8hi
6681 = build_function_type (V8HI_type_node,
6682 tree_cons (NULL_TREE, V8HI_type_node,
6683 tree_cons (NULL_TREE, V8HI_type_node,
6684 endlink)));
6685 tree v8hi_ftype_v8hi_int
6686 = build_function_type (V8HI_type_node,
6687 tree_cons (NULL_TREE, V8HI_type_node,
6688 tree_cons (NULL_TREE, integer_type_node,
6689 endlink)));
6690
6691 tree v8hi_ftype_v8hi_int_int
6692 = build_function_type (V8HI_type_node,
6693 tree_cons (NULL_TREE, V8HI_type_node,
6694 tree_cons (NULL_TREE, integer_type_node,
6695 tree_cons (NULL_TREE,
6696 integer_type_node,
6697 endlink))));
6698
6699 tree void_ftype_v8hi_int_int
6700 = build_function_type (void_type_node,
6701 tree_cons (NULL_TREE, V8HI_type_node,
6702 tree_cons (NULL_TREE, integer_type_node,
6703 tree_cons (NULL_TREE,
6704 integer_type_node,
6705 endlink))));
6706
6707 tree void_ftype_v8hi_int_int_int
6708 = (build_function_type
6709 (void_type_node,
6710 tree_cons (NULL_TREE, V8HI_type_node,
6711 tree_cons (NULL_TREE, integer_type_node,
6712 tree_cons (NULL_TREE, integer_type_node,
6713 tree_cons (NULL_TREE,
6714 integer_type_node,
6715 endlink))))));
6716
6717 tree v8hi_ftype_int_int
6718 = build_function_type (V8HI_type_node,
6719 tree_cons (NULL_TREE, integer_type_node,
6720 tree_cons (NULL_TREE, integer_type_node,
6721 endlink)));
6722
6723 tree void_ftype_int_int
6724 = build_function_type (void_type_node,
6725 tree_cons (NULL_TREE, integer_type_node,
6726 tree_cons (NULL_TREE, integer_type_node,
6727 endlink)));
6728
6729 tree void_ftype_int
6730 = build_function_type (void_type_node,
6731 tree_cons (NULL_TREE, integer_type_node, endlink));
6732
6733 tree v8hi_ftype_v8hi
6734 = build_function_type (V8HI_type_node, tree_cons (NULL_TREE, V8HI_type_node,
6735 endlink));
6736
6737 /* These asserts have been introduced to ensure that the order of builtins
6738 does not get messed up, else the initialization goes wrong. */
6739 gcc_assert (arc_simd_builtin_desc_list [0].args_type == Va_Vb_Vc);
6740 for (i=0; arc_simd_builtin_desc_list [i].args_type == Va_Vb_Vc; i++)
6741 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6742 v8hi_ftype_v8hi_v8hi, arc_simd_builtin_desc_list[i].code);
6743
6744 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Vb_rlimm);
6745 for (; arc_simd_builtin_desc_list [i].args_type == Va_Vb_rlimm; i++)
6746 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6747 v8hi_ftype_v8hi_int, arc_simd_builtin_desc_list[i].code);
6748
6749 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Vb_Ic);
6750 for (; arc_simd_builtin_desc_list [i].args_type == Va_Vb_Ic; i++)
6751 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6752 v8hi_ftype_v8hi_int, arc_simd_builtin_desc_list[i].code);
6753
6754 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Vb_u6);
6755 for (; arc_simd_builtin_desc_list [i].args_type == Va_Vb_u6; i++)
6756 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6757 v8hi_ftype_v8hi_int, arc_simd_builtin_desc_list[i].code);
6758
6759 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Vb_u8);
6760 for (; arc_simd_builtin_desc_list [i].args_type == Va_Vb_u8; i++)
6761 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6762 v8hi_ftype_v8hi_int, arc_simd_builtin_desc_list[i].code);
6763
6764 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_rlimm_u8);
6765 for (; arc_simd_builtin_desc_list [i].args_type == Va_rlimm_u8; i++)
6766 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6767 v8hi_ftype_int_int, arc_simd_builtin_desc_list[i].code);
6768
6769 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Vb);
6770 for (; arc_simd_builtin_desc_list [i].args_type == Va_Vb; i++)
6771 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6772 v8hi_ftype_v8hi, arc_simd_builtin_desc_list[i].code);
6773
6774 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Da_rlimm_rlimm);
6775 for (; arc_simd_builtin_desc_list [i].args_type == Da_rlimm_rlimm; i++)
6776 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list [i].name,
6777 void_ftype_int_int, arc_simd_builtin_desc_list[i].code);
6778
6779 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Da_u3_rlimm);
6780 for (; arc_simd_builtin_desc_list [i].args_type == Da_u3_rlimm; i++)
6781 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6782 void_ftype_int_int, arc_simd_builtin_desc_list[i].code);
6783
6784 gcc_assert (arc_simd_builtin_desc_list [i].args_type == void_rlimm);
6785 for (; arc_simd_builtin_desc_list [i].args_type == void_rlimm; i++)
6786 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6787 void_ftype_int, arc_simd_builtin_desc_list[i].code);
6788
6789 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Vb_Ic_u8);
6790 for (; arc_simd_builtin_desc_list [i].args_type == Va_Vb_Ic_u8; i++)
6791 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6792 v8hi_ftype_v8hi_int_int, arc_simd_builtin_desc_list[i].code);
6793
6794 gcc_assert (arc_simd_builtin_desc_list [i].args_type == Va_Ib_u8);
6795 for (; arc_simd_builtin_desc_list [i].args_type == Va_Ib_u8; i++)
6796 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6797 v8hi_ftype_int_int, arc_simd_builtin_desc_list[i].code);
6798
6799 gcc_assert (arc_simd_builtin_desc_list [i].args_type == void_Va_Ib_u8);
6800 for (; arc_simd_builtin_desc_list [i].args_type == void_Va_Ib_u8; i++)
6801 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list [i].name,
6802 void_ftype_v8hi_int_int, arc_simd_builtin_desc_list[i].code);
6803
6804 gcc_assert (arc_simd_builtin_desc_list [i].args_type == void_Va_u3_Ib_u8);
6805 for (; arc_simd_builtin_desc_list [i].args_type == void_Va_u3_Ib_u8; i++)
6806 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6807 void_ftype_v8hi_int_int_int,
6808 arc_simd_builtin_desc_list[i].code);
6809
6810 gcc_assert (arc_simd_builtin_desc_list [i].args_type == void_u6);
6811 for (; arc_simd_builtin_desc_list [i].args_type == void_u6; i++)
6812 def_mbuiltin (TARGET_SIMD_SET, arc_simd_builtin_desc_list[i].name,
6813 void_ftype_int, arc_simd_builtin_desc_list[i].code);
6814
6815 gcc_assert(i == ARRAY_SIZE (arc_simd_builtin_desc_list));
6816}
6817
6818/* Helper function of arc_expand_builtin; has the same parameters,
6819 except that EXP is now known to be a call to a simd builtin. */
6820
6821static rtx
6822arc_expand_simd_builtin (tree exp,
6823 rtx target,
6824 rtx subtarget ATTRIBUTE_UNUSED,
ef4bddc2 6825 machine_mode mode ATTRIBUTE_UNUSED,
526b7aee
SV
6826 int ignore ATTRIBUTE_UNUSED)
6827{
6828 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6829 tree arg0;
6830 tree arg1;
6831 tree arg2;
6832 tree arg3;
6833 rtx op0;
6834 rtx op1;
6835 rtx op2;
6836 rtx op3;
6837 rtx op4;
6838 rtx pat;
6839 unsigned int i;
6840 int fcode = DECL_FUNCTION_CODE (fndecl);
6841 int icode;
ef4bddc2
RS
6842 machine_mode mode0;
6843 machine_mode mode1;
6844 machine_mode mode2;
6845 machine_mode mode3;
6846 machine_mode mode4;
526b7aee
SV
6847 const struct builtin_description * d;
6848
6849 for (i = 0, d = arc_simd_builtin_desc_list;
6850 i < ARRAY_SIZE (arc_simd_builtin_desc_list); i++, d++)
6851 if (d->code == (const enum arc_builtins) fcode)
6852 break;
6853
6854 /* We must get an entry here. */
6855 gcc_assert (i < ARRAY_SIZE (arc_simd_builtin_desc_list));
6856
6857 switch (d->args_type)
6858 {
6859 case Va_Vb_rlimm:
6860 icode = d->icode;
6861 arg0 = CALL_EXPR_ARG (exp, 0);
6862 arg1 = CALL_EXPR_ARG (exp, 1);
6863 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6864 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6865
6866 target = gen_reg_rtx (V8HImode);
6867 mode0 = insn_data[icode].operand[1].mode;
6868 mode1 = insn_data[icode].operand[2].mode;
6869
6870 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6871 op0 = copy_to_mode_reg (mode0, op0);
6872
6873 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6874 op1 = copy_to_mode_reg (mode1, op1);
6875
6876 pat = GEN_FCN (icode) (target, op0, op1);
6877 if (! pat)
6878 return 0;
6879
6880 emit_insn (pat);
6881 return target;
6882
6883 case Va_Vb_u6:
6884 case Va_Vb_u8:
6885 icode = d->icode;
6886 arg0 = CALL_EXPR_ARG (exp, 0);
6887 arg1 = CALL_EXPR_ARG (exp, 1);
6888 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6889 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6890
6891 target = gen_reg_rtx (V8HImode);
6892 mode0 = insn_data[icode].operand[1].mode;
6893 mode1 = insn_data[icode].operand[2].mode;
6894
6895 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6896 op0 = copy_to_mode_reg (mode0, op0);
6897
6898 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)
6899 || (d->args_type == Va_Vb_u6 && !UNSIGNED_INT6 (INTVAL (op1)))
6900 || (d->args_type == Va_Vb_u8 && !UNSIGNED_INT8 (INTVAL (op1))))
6901 error ("operand 2 of %s instruction should be an unsigned %d-bit value",
6902 d->name,
6903 (d->args_type == Va_Vb_u6)? 6: 8);
6904
6905 pat = GEN_FCN (icode) (target, op0, op1);
6906 if (! pat)
6907 return 0;
6908
6909 emit_insn (pat);
6910 return target;
6911
6912 case Va_rlimm_u8:
6913 icode = d->icode;
6914 arg0 = CALL_EXPR_ARG (exp, 0);
6915 arg1 = CALL_EXPR_ARG (exp, 1);
6916 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6917 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6918
6919 target = gen_reg_rtx (V8HImode);
6920 mode0 = insn_data[icode].operand[1].mode;
6921 mode1 = insn_data[icode].operand[2].mode;
6922
6923 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6924 op0 = copy_to_mode_reg (mode0, op0);
6925
6926 if ( (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
6927 || !(UNSIGNED_INT8 (INTVAL (op1))))
6928 error ("operand 2 of %s instruction should be an unsigned 8-bit value",
6929 d->name);
6930
6931 pat = GEN_FCN (icode) (target, op0, op1);
6932 if (! pat)
6933 return 0;
6934
6935 emit_insn (pat);
6936 return target;
6937
6938 case Va_Vb_Ic:
6939 icode = d->icode;
6940 arg0 = CALL_EXPR_ARG (exp, 0);
6941 arg1 = CALL_EXPR_ARG (exp, 1);
6942 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6943 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6944 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6945
6946 target = gen_reg_rtx (V8HImode);
6947 mode0 = insn_data[icode].operand[1].mode;
6948 mode1 = insn_data[icode].operand[2].mode;
6949
6950 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6951 op0 = copy_to_mode_reg (mode0, op0);
6952
6953 if ( (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
6954 || !(UNSIGNED_INT3 (INTVAL (op1))))
6955 error ("operand 2 of %s instruction should be an unsigned 3-bit value (I0-I7)",
6956 d->name);
6957
6958 pat = GEN_FCN (icode) (target, op0, op1, op2);
6959 if (! pat)
6960 return 0;
6961
6962 emit_insn (pat);
6963 return target;
6964
6965 case Va_Vb_Vc:
6966 icode = d->icode;
6967 arg0 = CALL_EXPR_ARG (exp, 0);
6968 arg1 = CALL_EXPR_ARG (exp, 1);
6969 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6970 op1 = expand_expr (arg1, NULL_RTX, V8HImode, EXPAND_NORMAL);
6971
6972 target = gen_reg_rtx (V8HImode);
6973 mode0 = insn_data[icode].operand[1].mode;
6974 mode1 = insn_data[icode].operand[2].mode;
6975
6976 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6977 op0 = copy_to_mode_reg (mode0, op0);
6978
6979 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6980 op1 = copy_to_mode_reg (mode1, op1);
6981
6982 pat = GEN_FCN (icode) (target, op0, op1);
6983 if (! pat)
6984 return 0;
6985
6986 emit_insn (pat);
6987 return target;
6988
6989 case Va_Vb:
6990 icode = d->icode;
6991 arg0 = CALL_EXPR_ARG (exp, 0);
6992 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6993
6994 target = gen_reg_rtx (V8HImode);
6995 mode0 = insn_data[icode].operand[1].mode;
6996
6997 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6998 op0 = copy_to_mode_reg (mode0, op0);
6999
7000 pat = GEN_FCN (icode) (target, op0);
7001 if (! pat)
7002 return 0;
7003
7004 emit_insn (pat);
7005 return target;
7006
7007 case Da_rlimm_rlimm:
7008 icode = d->icode;
7009 arg0 = CALL_EXPR_ARG (exp, 0);
7010 arg1 = CALL_EXPR_ARG (exp, 1);
7011 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7012 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7013
7014
7015 if (icode == CODE_FOR_vdirun_insn)
7016 target = gen_rtx_REG (SImode, 131);
7017 else if (icode == CODE_FOR_vdorun_insn)
7018 target = gen_rtx_REG (SImode, 139);
7019 else
7020 gcc_unreachable ();
7021
7022 mode0 = insn_data[icode].operand[1].mode;
7023 mode1 = insn_data[icode].operand[2].mode;
7024
7025 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7026 op0 = copy_to_mode_reg (mode0, op0);
7027
7028 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7029 op1 = copy_to_mode_reg (mode1, op1);
7030
7031
7032 pat = GEN_FCN (icode) (target, op0, op1);
7033 if (! pat)
7034 return 0;
7035
7036 emit_insn (pat);
7037 return NULL_RTX;
7038
7039 case Da_u3_rlimm:
7040 icode = d->icode;
7041 arg0 = CALL_EXPR_ARG (exp, 0);
7042 arg1 = CALL_EXPR_ARG (exp, 1);
7043 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7044 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7045
7046
7047 if (! (GET_CODE (op0) == CONST_INT)
7048 || !(UNSIGNED_INT3 (INTVAL (op0))))
7049 error ("operand 1 of %s instruction should be an unsigned 3-bit value (DR0-DR7)",
7050 d->name);
7051
7052 mode1 = insn_data[icode].operand[1].mode;
7053
7054 if (icode == CODE_FOR_vdiwr_insn)
7055 target = gen_rtx_REG (SImode,
7056 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
7057 else if (icode == CODE_FOR_vdowr_insn)
7058 target = gen_rtx_REG (SImode,
7059 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
7060 else
7061 gcc_unreachable ();
7062
7063 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7064 op1 = copy_to_mode_reg (mode1, op1);
7065
7066 pat = GEN_FCN (icode) (target, op1);
7067 if (! pat)
7068 return 0;
7069
7070 emit_insn (pat);
7071 return NULL_RTX;
7072
7073 case void_u6:
7074 icode = d->icode;
7075 arg0 = CALL_EXPR_ARG (exp, 0);
7076
7077 fold (arg0);
7078
7079 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7080 mode0 = insn_data[icode].operand[0].mode;
7081
7082 /* op0 should be u6. */
7083 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)
7084 || !(UNSIGNED_INT6 (INTVAL (op0))))
7085 error ("operand of %s instruction should be an unsigned 6-bit value",
7086 d->name);
7087
7088 pat = GEN_FCN (icode) (op0);
7089 if (! pat)
7090 return 0;
7091
7092 emit_insn (pat);
7093 return NULL_RTX;
7094
7095 case void_rlimm:
7096 icode = d->icode;
7097 arg0 = CALL_EXPR_ARG (exp, 0);
7098
7099 fold (arg0);
7100
7101 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7102 mode0 = insn_data[icode].operand[0].mode;
7103
7104 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7105 op0 = copy_to_mode_reg (mode0, op0);
7106
7107 pat = GEN_FCN (icode) (op0);
7108 if (! pat)
7109 return 0;
7110
7111 emit_insn (pat);
7112 return NULL_RTX;
7113
7114 case Va_Vb_Ic_u8:
7115 {
7116 rtx src_vreg;
7117 icode = d->icode;
7118 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg */
7119 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7 */
7120 arg2 = CALL_EXPR_ARG (exp, 2); /* u8 */
7121
7122 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7123 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); /* [I]0-7 */
7124 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL); /* u8 */
7125 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); /* VR0 */
7126
7127 /* target <- src vreg */
7128 emit_insn (gen_move_insn (target, src_vreg));
7129
7130 /* target <- vec_concat: target, mem(Ib, u8) */
7131 mode0 = insn_data[icode].operand[3].mode;
7132 mode1 = insn_data[icode].operand[1].mode;
7133
7134 if ( (!(*insn_data[icode].operand[3].predicate) (op0, mode0))
7135 || !(UNSIGNED_INT3 (INTVAL (op0))))
7136 error ("operand 1 of %s instruction should be an unsigned 3-bit value (I0-I7)",
7137 d->name);
7138
7139 if ( (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
7140 || !(UNSIGNED_INT8 (INTVAL (op1))))
7141 error ("operand 2 of %s instruction should be an unsigned 8-bit value",
7142 d->name);
7143
7144 pat = GEN_FCN (icode) (target, op1, op2, op0);
7145 if (! pat)
7146 return 0;
7147
7148 emit_insn (pat);
7149 return target;
7150 }
7151
7152 case void_Va_Ib_u8:
7153 icode = d->icode;
7154 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg */
7155 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7 */
7156 arg2 = CALL_EXPR_ARG (exp, 2); /* u8 */
7157
7158 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); /* VR0 */
7159 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); /* I[0-7] */
7160 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL); /* u8 */
7161 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL); /* Vdest */
7162
7163 mode0 = insn_data[icode].operand[0].mode;
7164 mode1 = insn_data[icode].operand[1].mode;
7165 mode2 = insn_data[icode].operand[2].mode;
7166 mode3 = insn_data[icode].operand[3].mode;
7167
7168 if ( (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
7169 || !(UNSIGNED_INT3 (INTVAL (op1))))
7170 error ("operand 2 of %s instruction should be an unsigned 3-bit value (I0-I7)",
7171 d->name);
7172
7173 if ( (!(*insn_data[icode].operand[2].predicate) (op2, mode2))
7174 || !(UNSIGNED_INT8 (INTVAL (op2))))
7175 error ("operand 3 of %s instruction should be an unsigned 8-bit value",
7176 d->name);
7177
7178 if (!(*insn_data[icode].operand[3].predicate) (op3, mode3))
7179 op3 = copy_to_mode_reg (mode3, op3);
7180
7181 pat = GEN_FCN (icode) (op0, op1, op2, op3);
7182 if (! pat)
7183 return 0;
7184
7185 emit_insn (pat);
7186 return NULL_RTX;
7187
7188 case Va_Ib_u8:
7189 icode = d->icode;
7190 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg */
7191 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7 */
7192
7193 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); /* VR0 */
7194 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL); /* I[0-7] */
7195 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); /* u8 */
7196
7197 /* target <- src vreg */
7198 target = gen_reg_rtx (V8HImode);
7199
7200 /* target <- vec_concat: target, mem(Ib, u8) */
7201 mode0 = insn_data[icode].operand[1].mode;
7202 mode1 = insn_data[icode].operand[2].mode;
7203 mode2 = insn_data[icode].operand[3].mode;
7204
7205 if ( (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
7206 || !(UNSIGNED_INT3 (INTVAL (op1))))
7207 error ("operand 1 of %s instruction should be an unsigned 3-bit value (I0-I7)",
7208 d->name);
7209
7210 if ( (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
7211 || !(UNSIGNED_INT8 (INTVAL (op2))))
7212 error ("operand 2 of %s instruction should be an unsigned 8-bit value",
7213 d->name);
7214
7215 pat = GEN_FCN (icode) (target, op0, op1, op2);
7216 if (! pat)
7217 return 0;
7218
7219 emit_insn (pat);
7220 return target;
7221
7222 case void_Va_u3_Ib_u8:
7223 icode = d->icode;
7224 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg */
7225 arg1 = CALL_EXPR_ARG (exp, 1); /* u3 */
7226 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7 */
7227 arg3 = CALL_EXPR_ARG (exp, 3); /* u8 */
7228
7229 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL); /* u8 */
7230 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); /* VR */
7231 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL); /* [I]0-7 */
7232 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);/* vreg to be stored */
7233 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); /* vreg 0-7 subreg no. */
7234
7235 mode0 = insn_data[icode].operand[0].mode;
7236 mode2 = insn_data[icode].operand[2].mode;
7237 mode3 = insn_data[icode].operand[3].mode;
7238 mode4 = insn_data[icode].operand[4].mode;
7239
7240 /* Do some correctness checks for the operands. */
7241 if ( (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
7242 || !(UNSIGNED_INT8 (INTVAL (op0))))
7243 error ("operand 4 of %s instruction should be an unsigned 8-bit value (0-255)",
7244 d->name);
7245
7246 if ( (!(*insn_data[icode].operand[2].predicate) (op2, mode2))
7247 || !(UNSIGNED_INT3 (INTVAL (op2))))
7248 error ("operand 3 of %s instruction should be an unsigned 3-bit value (I0-I7)",
7249 d->name);
7250
7251 if (!(*insn_data[icode].operand[3].predicate) (op3, mode3))
7252 op3 = copy_to_mode_reg (mode3, op3);
7253
7254 if ( (!(*insn_data[icode].operand[4].predicate) (op4, mode4))
7255 || !(UNSIGNED_INT3 (INTVAL (op4))))
7256 error ("operand 2 of %s instruction should be an unsigned 3-bit value (subreg 0-7)",
7257 d->name);
7258 else if (icode == CODE_FOR_vst32_n_insn
7259 && ((INTVAL(op4) % 2 ) != 0))
7260 error ("operand 2 of %s instruction should be an even 3-bit value (subreg 0,2,4,6)",
7261 d->name);
7262
7263 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
7264 if (! pat)
7265 return 0;
7266
7267 emit_insn (pat);
7268 return NULL_RTX;
7269
7270 default:
7271 gcc_unreachable ();
7272 }
7273 return NULL_RTX;
7274}
7275
7276static bool
7277arc_preserve_reload_p (rtx in)
7278{
7279 return (GET_CODE (in) == PLUS
7280 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
7281 && CONST_INT_P (XEXP (in, 1))
7282 && !((INTVAL (XEXP (in, 1)) & 511)));
7283}
7284
7285int
ef4bddc2 7286arc_register_move_cost (machine_mode,
526b7aee
SV
7287 enum reg_class from_class, enum reg_class to_class)
7288{
7289 /* The ARC600 has no bypass for extension registers, hence a nop might be
7290 needed to be inserted after a write so that reads are safe. */
7291 if (TARGET_ARC600)
7292 {
7293 if (to_class == MPY_WRITABLE_CORE_REGS)
7294 return 3;
7295 /* Instructions modifying LP_COUNT need 4 additional cycles before
7296 the register will actually contain the value. */
7297 else if (to_class == LPCOUNT_REG)
7298 return 6;
7299 else if (to_class == WRITABLE_CORE_REGS)
7300 return 6;
7301 }
7302
7303 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7304 if (TARGET_ARC700
7305 && (from_class == LPCOUNT_REG || from_class == ALL_CORE_REGS
7306 || from_class == WRITABLE_CORE_REGS))
7307 return 8;
7308
7309 /* Force an attempt to 'mov Dy,Dx' to spill. */
7310 if (TARGET_ARC700 && TARGET_DPFP
7311 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
7312 return 100;
7313
7314 return 2;
7315}
7316
7317/* Emit code for an addsi3 instruction with OPERANDS.
7318 COND_P indicates if this will use conditional execution.
7319 Return the length of the instruction.
7320 If OUTPUT_P is false, don't actually output the instruction, just return
7321 its length. */
7322int
7323arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
7324{
7325 char format[32];
7326
7327 int match = operands_match_p (operands[0], operands[1]);
7328 int match2 = operands_match_p (operands[0], operands[2]);
7329 int intval = (REG_P (operands[2]) ? 1
7330 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
7331 int neg_intval = -intval;
7332 int short_0 = satisfies_constraint_Rcq (operands[0]);
7333 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
7334 int ret = 0;
7335
7336#define ADDSI_OUTPUT1(FORMAT) do {\
7337 if (output_p) \
7338 output_asm_insn (FORMAT, operands);\
7339 return ret; \
7340} while (0)
7341#define ADDSI_OUTPUT(LIST) do {\
7342 if (output_p) \
7343 sprintf LIST;\
7344 ADDSI_OUTPUT1 (format);\
7345 return ret; \
7346} while (0)
7347
7348 /* First try to emit a 16 bit insn. */
7349 ret = 2;
7350 if (!cond_p
7351 /* If we are actually about to output this insn, don't try a 16 bit
7352 variant if we already decided that we don't want that
7353 (I.e. we upsized this insn to align some following insn.)
7354 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7355 but add1 r0,sp,35 doesn't. */
7356 && (!output_p || (get_attr_length (current_output_insn) & 2)))
7357 {
7358 if (short_p
7359 && (REG_P (operands[2])
7360 ? (match || satisfies_constraint_Rcq (operands[2]))
7361 : (unsigned) intval <= (match ? 127 : 7)))
7362 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7363 if (short_0 && REG_P (operands[1]) && match2)
7364 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7365 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
7366 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
7367 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7368
7369 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
7370 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
7371 && match && !(neg_intval & ~124)))
7372 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7373 }
7374
7375 /* Now try to emit a 32 bit insn without long immediate. */
7376 ret = 4;
7377 if (!match && match2 && REG_P (operands[1]))
7378 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7379 if (match || !cond_p)
7380 {
7381 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
7382 int range_factor = neg_intval & intval;
7383 int shift;
7384
c419f71c 7385 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
526b7aee
SV
7386 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7387
7388 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7389 same size, do, so - the insn latency is lower. */
7390 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7391 0x800 is not. */
7392 if ((intval >= 0 && intval <= limit)
7393 || (intval == -0x800 && limit == 0x7ff))
7394 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7395 else if ((intval < 0 && neg_intval <= limit)
7396 || (intval == 0x800 && limit == 0x7ff))
7397 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7398 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
7399 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
7400 gcc_assert ((((1 << shift) - 1) & intval) == 0);
7401 if (((intval < 0 && intval != -0x4000)
7402 /* sub[123] is slower than add_s / sub, only use it if it
7403 avoids a long immediate. */
7404 && neg_intval <= limit << shift)
7405 || (intval == 0x4000 && limit == 0x7ff))
7406 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
7407 shift, neg_intval >> shift));
7408 else if ((intval >= 0 && intval <= limit << shift)
7409 || (intval == -0x4000 && limit == 0x7ff))
7410 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
7411 }
7412 /* Try to emit a 16 bit opcode with long immediate. */
7413 ret = 6;
7414 if (short_p && match)
7415 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7416
7417 /* We have to use a 32 bit opcode, and with a long immediate. */
7418 ret = 8;
7419 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7420}
7421
7422/* Emit code for an commutative_cond_exec instruction with OPERANDS.
7423 Return the length of the instruction.
7424 If OUTPUT_P is false, don't actually output the instruction, just return
7425 its length. */
7426int
7427arc_output_commutative_cond_exec (rtx *operands, bool output_p)
7428{
7429 enum rtx_code commutative_op = GET_CODE (operands[3]);
7430 const char *pat = NULL;
7431
7432 /* Canonical rtl should not have a constant in the first operand position. */
7433 gcc_assert (!CONSTANT_P (operands[1]));
7434
7435 switch (commutative_op)
7436 {
7437 case AND:
7438 if (satisfies_constraint_C1p (operands[2]))
7439 pat = "bmsk%? %0,%1,%Z2";
7440 else if (satisfies_constraint_Ccp (operands[2]))
7441 pat = "bclr%? %0,%1,%M2";
7442 else if (satisfies_constraint_CnL (operands[2]))
7443 pat = "bic%? %0,%1,%n2-1";
7444 break;
7445 case IOR:
7446 if (satisfies_constraint_C0p (operands[2]))
7447 pat = "bset%? %0,%1,%z2";
7448 break;
7449 case XOR:
7450 if (satisfies_constraint_C0p (operands[2]))
7451 pat = "bxor%? %0,%1,%z2";
7452 break;
7453 case PLUS:
7454 return arc_output_addsi (operands, true, output_p);
7455 default: break;
7456 }
7457 if (output_p)
7458 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
7459 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
7460 return 4;
7461 return 8;
7462}
7463
7464/* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7465 Emit code and return an potentially modified address such that offsets
7466 up to SIZE are can be added to yield a legitimate address.
7467 if REUSE is set, ADDR is a register that may be modified. */
7468
7469static rtx
7470force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
7471{
7472 rtx base = addr;
7473 rtx offs = const0_rtx;
7474
7475 if (GET_CODE (base) == PLUS)
7476 {
7477 offs = XEXP (base, 1);
7478 base = XEXP (base, 0);
7479 }
7480 if (!REG_P (base)
7481 || (REGNO (base) != STACK_POINTER_REGNUM
7482 && REGNO_PTR_FRAME_P (REGNO (addr)))
7483 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
7484 || !SMALL_INT (INTVAL (offs) + size))
7485 {
7486 if (reuse)
7487 emit_insn (gen_add2_insn (addr, offs));
7488 else
7489 addr = copy_to_mode_reg (Pmode, addr);
7490 }
7491 return addr;
7492}
7493
7494/* Like move_by_pieces, but take account of load latency,
7495 and actual offset ranges.
7496 Return true on success. */
7497
7498bool
7499arc_expand_movmem (rtx *operands)
7500{
7501 rtx dst = operands[0];
7502 rtx src = operands[1];
7503 rtx dst_addr, src_addr;
7504 HOST_WIDE_INT size;
7505 int align = INTVAL (operands[3]);
7506 unsigned n_pieces;
7507 int piece = align;
7508 rtx store[2];
7509 rtx tmpx[2];
7510 int i;
7511
7512 if (!CONST_INT_P (operands[2]))
7513 return false;
7514 size = INTVAL (operands[2]);
7515 /* move_by_pieces_ninsns is static, so we can't use it. */
7516 if (align >= 4)
7517 n_pieces = (size + 2) / 4U + (size & 1);
7518 else if (align == 2)
7519 n_pieces = (size + 1) / 2U;
7520 else
7521 n_pieces = size;
7522 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
7523 return false;
7524 if (piece > 4)
7525 piece = 4;
7526 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
7527 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
7528 store[0] = store[1] = NULL_RTX;
7529 tmpx[0] = tmpx[1] = NULL_RTX;
7530 for (i = 0; size > 0; i ^= 1, size -= piece)
7531 {
7532 rtx tmp;
ef4bddc2 7533 machine_mode mode;
526b7aee
SV
7534
7535 if (piece > size)
7536 piece = size & -size;
7537 mode = smallest_mode_for_size (piece * BITS_PER_UNIT, MODE_INT);
7538 /* If we don't re-use temporaries, the scheduler gets carried away,
7539 and the register pressure gets unnecessarily high. */
7540 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
7541 tmp = tmpx[i];
7542 else
7543 tmpx[i] = tmp = gen_reg_rtx (mode);
7544 dst_addr = force_offsettable (dst_addr, piece, 1);
7545 src_addr = force_offsettable (src_addr, piece, 1);
7546 if (store[i])
7547 emit_insn (store[i]);
7548 emit_move_insn (tmp, change_address (src, mode, src_addr));
7549 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
7550 dst_addr = plus_constant (Pmode, dst_addr, piece);
7551 src_addr = plus_constant (Pmode, src_addr, piece);
7552 }
7553 if (store[i])
7554 emit_insn (store[i]);
7555 if (store[i^1])
7556 emit_insn (store[i^1]);
7557 return true;
7558}
7559
7560/* Prepare operands for move in MODE. Return true iff the move has
7561 been emitted. */
7562
7563bool
ef4bddc2 7564prepare_move_operands (rtx *operands, machine_mode mode)
526b7aee
SV
7565{
7566 /* We used to do this only for MODE_INT Modes, but addresses to floating
7567 point variables may well be in the small data section. */
7568 if (1)
7569 {
7570 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
7571 operands[0] = arc_rewrite_small_data (operands[0]);
7572 else if (mode == SImode && flag_pic && SYMBOLIC_CONST (operands[1]))
7573 {
7574 emit_pic_move (operands, SImode);
7575
7576 /* Disable any REG_EQUALs associated with the symref
7577 otherwise the optimization pass undoes the work done
7578 here and references the variable directly. */
7579 }
7580 else if (GET_CODE (operands[0]) != MEM
7581 && !TARGET_NO_SDATA_SET
7582 && small_data_pattern (operands[1], Pmode))
7583 {
7584 /* This is to take care of address calculations involving sdata
7585 variables. */
7586 operands[1] = arc_rewrite_small_data (operands[1]);
7587
f7df4a84 7588 emit_insn (gen_rtx_SET (operands[0],operands[1]));
526b7aee
SV
7589 /* ??? This note is useless, since it only restates the set itself.
7590 We should rather use the original SYMBOL_REF. However, there is
7591 the problem that we are lying to the compiler about these
7592 SYMBOL_REFs to start with. symbol@sda should be encoded specially
7593 so that we can tell it apart from an actual symbol. */
7594 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7595
7596 /* Take care of the REG_EQUAL note that will be attached to mark the
7597 output reg equal to the initial symbol_ref after this code is
7598 executed. */
7599 emit_move_insn (operands[0], operands[0]);
7600 return true;
7601 }
7602 }
7603
7604 if (MEM_P (operands[0])
7605 && !(reload_in_progress || reload_completed))
7606 {
7607 operands[1] = force_reg (mode, operands[1]);
7608 if (!move_dest_operand (operands[0], mode))
7609 {
7610 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7611 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
7612 except that we can't use that function because it is static. */
7613 rtx pat = change_address (operands[0], mode, addr);
7614 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7615 operands[0] = pat;
7616 }
7617 if (!cse_not_expected)
7618 {
7619 rtx pat = XEXP (operands[0], 0);
7620
7621 pat = arc_legitimize_address_0 (pat, pat, mode);
7622 if (pat)
7623 {
7624 pat = change_address (operands[0], mode, pat);
7625 MEM_COPY_ATTRIBUTES (pat, operands[0]);
7626 operands[0] = pat;
7627 }
7628 }
7629 }
7630
7631 if (MEM_P (operands[1]) && !cse_not_expected)
7632 {
7633 rtx pat = XEXP (operands[1], 0);
7634
7635 pat = arc_legitimize_address_0 (pat, pat, mode);
7636 if (pat)
7637 {
7638 pat = change_address (operands[1], mode, pat);
7639 MEM_COPY_ATTRIBUTES (pat, operands[1]);
7640 operands[1] = pat;
7641 }
7642 }
7643
7644 return false;
7645}
7646
7647/* Prepare OPERANDS for an extension using CODE to OMODE.
7648 Return true iff the move has been emitted. */
7649
7650bool
7651prepare_extend_operands (rtx *operands, enum rtx_code code,
ef4bddc2 7652 machine_mode omode)
526b7aee
SV
7653{
7654 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
7655 {
7656 /* This is to take care of address calculations involving sdata
7657 variables. */
7658 operands[1]
7659 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
f7df4a84 7660 emit_insn (gen_rtx_SET (operands[0], operands[1]));
526b7aee
SV
7661 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
7662
7663 /* Take care of the REG_EQUAL note that will be attached to mark the
7664 output reg equal to the initial extension after this code is
7665 executed. */
7666 emit_move_insn (operands[0], operands[0]);
7667 return true;
7668 }
7669 return false;
7670}
7671
7672/* Output a library call to a function called FNAME that has been arranged
7673 to be local to any dso. */
7674
7675const char *
7676arc_output_libcall (const char *fname)
7677{
7678 unsigned len = strlen (fname);
7679 static char buf[64];
7680
7681 gcc_assert (len < sizeof buf - 35);
7682 if (TARGET_LONG_CALLS_SET
7683 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
7684 {
7685 if (flag_pic)
7686 sprintf (buf, "add r12,pcl,@%s-(.&-4)\n\tjl%%!%%* [r12]", fname);
7687 else
7688 sprintf (buf, "jl%%! @%s", fname);
7689 }
7690 else
7691 sprintf (buf, "bl%%!%%* @%s", fname);
7692 return buf;
7693}
7694
7695/* Return the SImode highpart of the DImode value IN. */
7696
7697rtx
7698disi_highpart (rtx in)
7699{
7700 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
7701}
7702
526b7aee
SV
7703/* Return length adjustment for INSN.
7704 For ARC600:
7705 A write to a core reg greater or equal to 32 must not be immediately
7706 followed by a use. Anticipate the length requirement to insert a nop
7707 between PRED and SUCC to prevent a hazard. */
7708
7709static int
647d790d 7710arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee
SV
7711{
7712 if (!TARGET_ARC600)
7713 return 0;
7714 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
7715 in front of SUCC anyway, so there will be separation between PRED and
7716 SUCC. */
7717 if (recog_memoized (succ) == CODE_FOR_doloop_end_i
7718 && LABEL_P (prev_nonnote_insn (succ)))
7719 return 0;
7720 if (recog_memoized (succ) == CODE_FOR_doloop_begin_i)
7721 return 0;
7722 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
647d790d 7723 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
526b7aee 7724 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
647d790d 7725 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
526b7aee
SV
7726 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7727 || recog_memoized (pred) == CODE_FOR_umul_600
7728 || recog_memoized (pred) == CODE_FOR_mac_600
7729 || recog_memoized (pred) == CODE_FOR_mul64_600
7730 || recog_memoized (pred) == CODE_FOR_mac64_600
7731 || recog_memoized (pred) == CODE_FOR_umul64_600
7732 || recog_memoized (pred) == CODE_FOR_umac64_600)
7733 return 0;
36cc6254
RS
7734 subrtx_iterator::array_type array;
7735 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7736 {
7737 const_rtx x = *iter;
7738 switch (GET_CODE (x))
7739 {
7740 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7741 break;
7742 default:
7743 /* This is also fine for PRE/POST_MODIFY, because they
7744 contain a SET. */
7745 continue;
7746 }
7747 rtx dest = XEXP (x, 0);
7748 /* Check if this sets a an extension register. N.B. we use 61 for the
7749 condition codes, which is definitely not an extension register. */
7750 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7751 /* Check if the same register is used by the PAT. */
7752 && (refers_to_regno_p
7753 (REGNO (dest),
7754 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7755 PATTERN (succ), 0)))
7756 return 4;
7757 }
7758 return 0;
526b7aee
SV
7759}
7760
7761/* For ARC600:
7762 A write to a core reg greater or equal to 32 must not be immediately
7763 followed by a use. Anticipate the length requirement to insert a nop
7764 between PRED and SUCC to prevent a hazard. */
7765
7766int
647d790d 7767arc_hazard (rtx_insn *pred, rtx_insn *succ)
526b7aee
SV
7768{
7769 if (!TARGET_ARC600)
7770 return 0;
7771 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7772 return 0;
7773 /* We might have a CALL to a non-returning function before a loop end.
7774 ??? Although the manual says that's OK (the target is outside the loop,
7775 and the loop counter unused there), the assembler barfs on this, so we
7776 must instert a nop before such a call too. */
7777 if (recog_memoized (succ) == CODE_FOR_doloop_end_i
7778 && (JUMP_P (pred) || CALL_P (pred)
7779 || GET_CODE (PATTERN (pred)) == SEQUENCE))
7780 return 4;
7781 return arc600_corereg_hazard (pred, succ);
7782}
7783
7784/* Return length adjustment for INSN. */
7785
7786int
647d790d 7787arc_adjust_insn_length (rtx_insn *insn, int len, bool)
526b7aee
SV
7788{
7789 if (!INSN_P (insn))
7790 return len;
7791 /* We already handle sequences by ignoring the delay sequence flag. */
7792 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
7793 return len;
7794
7795 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
7796 the ZOL mechanism only triggers when advancing to the end address,
7797 so if there's a label at the end of a ZOL, we need to insert a nop.
7798 The ARC600 ZOL also has extra restrictions on jumps at the end of a
7799 loop. */
7800 if (recog_memoized (insn) == CODE_FOR_doloop_end_i)
7801 {
b3458f61 7802 rtx_insn *prev = prev_nonnote_insn (insn);
526b7aee
SV
7803
7804 return ((LABEL_P (prev)
7805 || (TARGET_ARC600
7806 && (JUMP_P (prev)
7807 || CALL_P (prev) /* Could be a noreturn call. */
7808 || (NONJUMP_INSN_P (prev)
7809 && GET_CODE (PATTERN (prev)) == SEQUENCE))))
7810 ? len + 4 : len);
7811 }
7812
7813 /* Check for return with but one preceding insn since function
7814 start / call. */
7815 if (TARGET_PAD_RETURN
7816 && JUMP_P (insn)
7817 && GET_CODE (PATTERN (insn)) != ADDR_VEC
7818 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
7819 && get_attr_type (insn) == TYPE_RETURN)
7820 {
84034c69 7821 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
7822
7823 if (!prev || !(prev = prev_active_insn (prev))
7824 || ((NONJUMP_INSN_P (prev)
7825 && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
7826 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
7827 NON_SIBCALL)
526b7aee
SV
7828 : CALL_ATTR (prev, NON_SIBCALL)))
7829 return len + 4;
7830 }
7831 if (TARGET_ARC600)
7832 {
b3458f61 7833 rtx_insn *succ = next_real_insn (insn);
526b7aee
SV
7834
7835 /* One the ARC600, a write to an extension register must be separated
7836 from a read. */
7837 if (succ && INSN_P (succ))
7838 len += arc600_corereg_hazard (insn, succ);
7839 }
7840
7841 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
7842 can go awry. */
7843 extract_constrain_insn_cached (insn);
7844
7845 return len;
7846}
7847
7848/* Values for length_sensitive. */
7849enum
7850{
7851 ARC_LS_NONE,// Jcc
7852 ARC_LS_25, // 25 bit offset, B
7853 ARC_LS_21, // 21 bit offset, Bcc
7854 ARC_LS_U13,// 13 bit unsigned offset, LP
7855 ARC_LS_10, // 10 bit offset, B_s, Beq_s, Bne_s
7856 ARC_LS_9, // 9 bit offset, BRcc
7857 ARC_LS_8, // 8 bit offset, BRcc_s
7858 ARC_LS_U7, // 7 bit unsigned offset, LPcc
7859 ARC_LS_7 // 7 bit offset, Bcc_s
7860};
7861
7862/* While the infrastructure patch is waiting for review, duplicate the
7863 struct definitions, to allow this file to compile. */
7864#if 1
7865typedef struct
7866{
7867 unsigned align_set;
7868 /* Cost as a branch / call target or call return address. */
7869 int target_cost;
7870 int fallthrough_cost;
7871 int branch_cost;
7872 int length;
7873 /* 0 for not length sensitive, 1 for largest offset range,
7874 * 2 for next smaller etc. */
7875 unsigned length_sensitive : 8;
7876 bool enabled;
7877} insn_length_variant_t;
7878
7879typedef struct insn_length_parameters_s
7880{
7881 int align_unit_log;
7882 int align_base_log;
7883 int max_variants;
647d790d 7884 int (*get_variants) (rtx_insn *, int, bool, bool, insn_length_variant_t *);
526b7aee
SV
7885} insn_length_parameters_t;
7886
7887static void
7888arc_insn_length_parameters (insn_length_parameters_t *ilp) ATTRIBUTE_UNUSED;
7889#endif
7890
7891static int
647d790d 7892arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
526b7aee
SV
7893 insn_length_variant_t *ilv)
7894{
7895 if (!NONDEBUG_INSN_P (insn))
7896 return 0;
7897 enum attr_type type;
7898 /* shorten_branches doesn't take optimize_size into account yet for the
7899 get_variants mechanism, so turn this off for now. */
7900 if (optimize_size)
7901 return 0;
647d790d 7902 if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
526b7aee
SV
7903 {
7904 /* The interaction of a short delay slot insn with a short branch is
7905 too weird for shorten_branches to piece together, so describe the
7906 entire SEQUENCE. */
647d790d 7907 rtx_insn *inner;
526b7aee 7908 if (TARGET_UPSIZE_DBR
84034c69 7909 && get_attr_length (pat->insn (1)) <= 2
647d790d 7910 && (((type = get_attr_type (inner = pat->insn (0)))
526b7aee
SV
7911 == TYPE_UNCOND_BRANCH)
7912 || type == TYPE_BRANCH)
7913 && get_attr_delay_slot_filled (inner) == DELAY_SLOT_FILLED_YES)
7914 {
7915 int n_variants
7916 = arc_get_insn_variants (inner, get_attr_length (inner), true,
7917 target_p, ilv+1);
7918 /* The short variant gets split into a higher-cost aligned
7919 and a lower cost unaligned variant. */
7920 gcc_assert (n_variants);
7921 gcc_assert (ilv[1].length_sensitive == ARC_LS_7
7922 || ilv[1].length_sensitive == ARC_LS_10);
7923 gcc_assert (ilv[1].align_set == 3);
7924 ilv[0] = ilv[1];
7925 ilv[0].align_set = 1;
7926 ilv[0].branch_cost += 1;
7927 ilv[1].align_set = 2;
7928 n_variants++;
7929 for (int i = 0; i < n_variants; i++)
7930 ilv[i].length += 2;
7931 /* In case an instruction with aligned size is wanted, and
7932 the short variants are unavailable / too expensive, add
7933 versions of long branch + long delay slot. */
7934 for (int i = 2, end = n_variants; i < end; i++, n_variants++)
7935 {
7936 ilv[n_variants] = ilv[i];
7937 ilv[n_variants].length += 2;
7938 }
7939 return n_variants;
7940 }
7941 return 0;
7942 }
7943 insn_length_variant_t *first_ilv = ilv;
7944 type = get_attr_type (insn);
7945 bool delay_filled
7946 = (get_attr_delay_slot_filled (insn) == DELAY_SLOT_FILLED_YES);
7947 int branch_align_cost = delay_filled ? 0 : 1;
7948 int branch_unalign_cost = delay_filled ? 0 : TARGET_UNALIGN_BRANCH ? 0 : 1;
7949 /* If the previous instruction is an sfunc call, this insn is always
7950 a target, even though the middle-end is unaware of this. */
7951 bool force_target = false;
b3458f61 7952 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
7953 if (prev && arc_next_active_insn (prev, 0) == insn
7954 && ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
7955 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
7956 NON_SIBCALL)
526b7aee
SV
7957 : (CALL_ATTR (prev, NON_SIBCALL)
7958 && NEXT_INSN (PREV_INSN (prev)) == prev)))
7959 force_target = true;
7960
7961 switch (type)
7962 {
7963 case TYPE_BRCC:
7964 /* Short BRCC only comes in no-delay-slot version, and without limm */
7965 if (!delay_filled)
7966 {
7967 ilv->align_set = 3;
7968 ilv->length = 2;
7969 ilv->branch_cost = 1;
7970 ilv->enabled = (len == 2);
7971 ilv->length_sensitive = ARC_LS_8;
7972 ilv++;
7973 }
7974 /* Fall through. */
7975 case TYPE_BRCC_NO_DELAY_SLOT:
7976 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
7977 (delay slot) scheduling purposes, but they are longer. */
7978 if (GET_CODE (PATTERN (insn)) == PARALLEL
7979 && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET)
7980 return 0;
7981 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
7982 ilv->length = ((type == TYPE_BRCC) ? 4 : 8);
7983 ilv->align_set = 3;
7984 ilv->branch_cost = branch_align_cost;
7985 ilv->enabled = (len <= ilv->length);
7986 ilv->length_sensitive = ARC_LS_9;
7987 if ((target_p || force_target)
7988 || (!delay_filled && TARGET_UNALIGN_BRANCH))
7989 {
7990 ilv[1] = *ilv;
7991 ilv->align_set = 1;
7992 ilv++;
7993 ilv->align_set = 2;
7994 ilv->target_cost = 1;
7995 ilv->branch_cost = branch_unalign_cost;
7996 }
7997 ilv++;
7998
7999 rtx op, op0;
8000 op = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
8001 op0 = XEXP (op, 0);
8002
8003 if (GET_CODE (op0) == ZERO_EXTRACT
8004 && satisfies_constraint_L (XEXP (op0, 2)))
8005 op0 = XEXP (op0, 0);
8006 if (satisfies_constraint_Rcq (op0))
8007 {
8008 ilv->length = ((type == TYPE_BRCC) ? 6 : 10);
8009 ilv->align_set = 3;
8010 ilv->branch_cost = 1 + branch_align_cost;
8011 ilv->fallthrough_cost = 1;
8012 ilv->enabled = true;
8013 ilv->length_sensitive = ARC_LS_21;
8014 if (!delay_filled && TARGET_UNALIGN_BRANCH)
8015 {
8016 ilv[1] = *ilv;
8017 ilv->align_set = 1;
8018 ilv++;
8019 ilv->align_set = 2;
8020 ilv->branch_cost = 1 + branch_unalign_cost;
8021 }
8022 ilv++;
8023 }
8024 ilv->length = ((type == TYPE_BRCC) ? 8 : 12);
8025 ilv->align_set = 3;
8026 ilv->branch_cost = 1 + branch_align_cost;
8027 ilv->fallthrough_cost = 1;
8028 ilv->enabled = true;
8029 ilv->length_sensitive = ARC_LS_21;
8030 if ((target_p || force_target)
8031 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8032 {
8033 ilv[1] = *ilv;
8034 ilv->align_set = 1;
8035 ilv++;
8036 ilv->align_set = 2;
8037 ilv->target_cost = 1;
8038 ilv->branch_cost = 1 + branch_unalign_cost;
8039 }
8040 ilv++;
8041 break;
8042
8043 case TYPE_SFUNC:
8044 ilv->length = 12;
8045 goto do_call;
8046 case TYPE_CALL_NO_DELAY_SLOT:
8047 ilv->length = 8;
8048 goto do_call;
8049 case TYPE_CALL:
8050 ilv->length = 4;
8051 ilv->length_sensitive
8052 = GET_CODE (PATTERN (insn)) == COND_EXEC ? ARC_LS_21 : ARC_LS_25;
8053 do_call:
8054 ilv->align_set = 3;
8055 ilv->fallthrough_cost = branch_align_cost;
8056 ilv->enabled = true;
8057 if ((target_p || force_target)
8058 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8059 {
8060 ilv[1] = *ilv;
8061 ilv->align_set = 1;
8062 ilv++;
8063 ilv->align_set = 2;
8064 ilv->target_cost = 1;
8065 ilv->fallthrough_cost = branch_unalign_cost;
8066 }
8067 ilv++;
8068 break;
8069 case TYPE_UNCOND_BRANCH:
8070 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8071 but that makes no difference at the moment. */
8072 ilv->length_sensitive = ARC_LS_7;
8073 ilv[1].length_sensitive = ARC_LS_25;
8074 goto do_branch;
8075 case TYPE_BRANCH:
8076 ilv->length_sensitive = ARC_LS_10;
8077 ilv[1].length_sensitive = ARC_LS_21;
8078 do_branch:
8079 ilv->align_set = 3;
8080 ilv->length = 2;
8081 ilv->branch_cost = branch_align_cost;
8082 ilv->enabled = (len == ilv->length);
8083 ilv++;
8084 ilv->length = 4;
8085 ilv->align_set = 3;
8086 ilv->branch_cost = branch_align_cost;
8087 ilv->enabled = true;
8088 if ((target_p || force_target)
8089 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8090 {
8091 ilv[1] = *ilv;
8092 ilv->align_set = 1;
8093 ilv++;
8094 ilv->align_set = 2;
8095 ilv->target_cost = 1;
8096 ilv->branch_cost = branch_unalign_cost;
8097 }
8098 ilv++;
8099 break;
8100 case TYPE_JUMP:
8101 return 0;
8102 default:
8103 /* For every short insn, there is generally also a long insn.
8104 trap_s is an exception. */
8105 if ((len & 2) == 0 || recog_memoized (insn) == CODE_FOR_trap_s)
8106 return 0;
8107 ilv->align_set = 3;
8108 ilv->length = len;
8109 ilv->enabled = 1;
8110 ilv++;
8111 ilv->align_set = 3;
8112 ilv->length = len + 2;
8113 ilv->enabled = 1;
8114 if (target_p || force_target)
8115 {
8116 ilv[1] = *ilv;
8117 ilv->align_set = 1;
8118 ilv++;
8119 ilv->align_set = 2;
8120 ilv->target_cost = 1;
8121 }
8122 ilv++;
8123 }
8124 /* If the previous instruction is an sfunc call, this insn is always
8125 a target, even though the middle-end is unaware of this.
8126 Therefore, if we have a call predecessor, transfer the target cost
8127 to the fallthrough and branch costs. */
8128 if (force_target)
8129 {
8130 for (insn_length_variant_t *p = first_ilv; p < ilv; p++)
8131 {
8132 p->fallthrough_cost += p->target_cost;
8133 p->branch_cost += p->target_cost;
8134 p->target_cost = 0;
8135 }
8136 }
8137
8138 return ilv - first_ilv;
8139}
8140
8141static void
8142arc_insn_length_parameters (insn_length_parameters_t *ilp)
8143{
8144 ilp->align_unit_log = 1;
8145 ilp->align_base_log = 1;
8146 ilp->max_variants = 7;
8147 ilp->get_variants = arc_get_insn_variants;
8148}
8149
8150/* Return a copy of COND from *STATEP, inverted if that is indicated by the
8151 CC field of *STATEP. */
8152
8153static rtx
8154arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8155{
8156 rtx cond = statep->cond;
8157 int raw_cc = get_arc_condition_code (cond);
8158 if (reverse)
8159 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8160
8161 if (statep->cc == raw_cc)
8162 return copy_rtx (cond);
8163
8164 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8165
ef4bddc2 8166 machine_mode ccm = GET_MODE (XEXP (cond, 0));
526b7aee
SV
8167 enum rtx_code code = reverse_condition (GET_CODE (cond));
8168 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8169 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8170
8171 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8172 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8173}
8174
bae56bbb
JR
8175/* Return version of PAT conditionalized with COND, which is part of INSN.
8176 ANNULLED indicates if INSN is an annulled delay-slot insn.
8177 Register further changes if necessary. */
8178static rtx
8179conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8180{
8181 /* For commutative operators, we generally prefer to have
8182 the first source match the destination. */
8183 if (GET_CODE (pat) == SET)
8184 {
8185 rtx src = SET_SRC (pat);
8186
8187 if (COMMUTATIVE_P (src))
8188 {
8189 rtx src0 = XEXP (src, 0);
8190 rtx src1 = XEXP (src, 1);
8191 rtx dst = SET_DEST (pat);
8192
8193 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8194 /* Leave add_n alone - the canonical form is to
8195 have the complex summand first. */
8196 && REG_P (src0))
f7df4a84 8197 pat = gen_rtx_SET (dst,
bae56bbb
JR
8198 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8199 src1, src0));
8200 }
8201 }
8202
8203 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8204 what to do with COND_EXEC. */
8205 if (RTX_FRAME_RELATED_P (insn))
8206 {
8207 /* If this is the delay slot insn of an anulled branch,
8208 dwarf2out.c:scan_trace understands the anulling semantics
8209 without the COND_EXEC. */
8210 gcc_assert (annulled);
8211 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8212 REG_NOTES (insn));
8213 validate_change (insn, &REG_NOTES (insn), note, 1);
8214 }
8215 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8216 return pat;
8217}
8218
526b7aee
SV
8219/* Use the ccfsm machinery to do if conversion. */
8220
8221static unsigned
8222arc_ifcvt (void)
8223{
8224 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8225 basic_block merge_bb = 0;
8226
8227 memset (statep, 0, sizeof *statep);
b3458f61 8228 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
526b7aee
SV
8229 {
8230 arc_ccfsm_advance (insn, statep);
8231
8232 switch (statep->state)
8233 {
8234 case 0:
8235 if (JUMP_P (insn))
8236 merge_bb = 0;
8237 break;
8238 case 1: case 2:
8239 {
8240 /* Deleted branch. */
8241 gcc_assert (!merge_bb);
8242 merge_bb = BLOCK_FOR_INSN (insn);
8243 basic_block succ_bb
8244 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn))));
8245 arc_ccfsm_post_advance (insn, statep);
53ea364f 8246 gcc_assert (!IN_RANGE (statep->state, 1, 2));
b3458f61 8247 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
526b7aee
SV
8248 if (seq != insn)
8249 {
8250 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8251 rtx pat = PATTERN (slot);
8252 if (INSN_ANNULLED_BRANCH_P (insn))
8253 {
8254 rtx cond
8255 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8256 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8257 }
8258 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8259 gcc_unreachable ();
8260 PUT_CODE (slot, NOTE);
8261 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8262 if (merge_bb && succ_bb)
8263 merge_blocks (merge_bb, succ_bb);
8264 }
8265 else if (merge_bb && succ_bb)
8266 {
8267 set_insn_deleted (insn);
8268 merge_blocks (merge_bb, succ_bb);
8269 }
8270 else
8271 {
8272 PUT_CODE (insn, NOTE);
8273 NOTE_KIND (insn) = NOTE_INSN_DELETED;
8274 }
8275 continue;
8276 }
8277 case 3:
8278 if (LABEL_P (insn)
8279 && statep->target_label == CODE_LABEL_NUMBER (insn))
8280 {
8281 arc_ccfsm_post_advance (insn, statep);
8282 basic_block succ_bb = BLOCK_FOR_INSN (insn);
8283 if (merge_bb && succ_bb)
8284 merge_blocks (merge_bb, succ_bb);
8285 else if (--LABEL_NUSES (insn) == 0)
8286 {
8287 const char *name = LABEL_NAME (insn);
8288 PUT_CODE (insn, NOTE);
8289 NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
8290 NOTE_DELETED_LABEL_NAME (insn) = name;
8291 }
8292 merge_bb = 0;
8293 continue;
8294 }
8295 /* Fall through. */
8296 case 4: case 5:
8297 if (!NONDEBUG_INSN_P (insn))
8298 break;
8299
8300 /* Conditionalized insn. */
8301
b3458f61
DM
8302 rtx_insn *prev, *pprev;
8303 rtx *patp, pat, cond;
bae56bbb 8304 bool annulled; annulled = false;
526b7aee
SV
8305
8306 /* If this is a delay slot insn in a non-annulled branch,
8307 don't conditionalize it. N.B., this should be fine for
8308 conditional return too. However, don't do this for
8309 unconditional branches, as these would be encountered when
8310 processing an 'else' part. */
8311 prev = PREV_INSN (insn);
8312 pprev = PREV_INSN (prev);
8313 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
bae56bbb
JR
8314 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8315 {
8316 if (!INSN_ANNULLED_BRANCH_P (prev))
8317 break;
8318 annulled = true;
8319 }
526b7aee
SV
8320
8321 patp = &PATTERN (insn);
8322 pat = *patp;
8323 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
8324 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
8325 {
8326 /* ??? don't conditionalize if all side effects are dead
8327 in the not-execute case. */
9bf218f9 8328
bae56bbb 8329 pat = conditionalize_nonjump (pat, cond, insn, annulled);
526b7aee
SV
8330 }
8331 else if (simplejump_p (insn))
8332 {
8333 patp = &SET_SRC (pat);
8334 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
8335 }
8336 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
8337 {
8338 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
f7df4a84 8339 pat = gen_rtx_SET (pc_rtx, pat);
526b7aee
SV
8340 }
8341 else
8342 gcc_unreachable ();
8343 validate_change (insn, patp, pat, 1);
8344 if (!apply_change_group ())
8345 gcc_unreachable ();
8346 if (JUMP_P (insn))
8347 {
b3458f61 8348 rtx_insn *next = next_nonnote_insn (insn);
526b7aee
SV
8349 if (GET_CODE (next) == BARRIER)
8350 delete_insn (next);
8351 if (statep->state == 3)
8352 continue;
8353 }
8354 break;
8355 default:
8356 gcc_unreachable ();
8357 }
8358 arc_ccfsm_post_advance (insn, statep);
8359 }
8360 return 0;
8361}
8362
0bc69b81
JR
8363/* Find annulled delay insns and convert them to use the appropriate predicate.
8364 This allows branch shortening to size up these insns properly. */
8365
8366static unsigned
8367arc_predicate_delay_insns (void)
8368{
b3458f61 8369 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
0bc69b81
JR
8370 {
8371 rtx pat, jump, dlay, src, cond, *patp;
8372 int reverse;
8373
8374 if (!NONJUMP_INSN_P (insn)
8375 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
8376 continue;
8377 jump = XVECEXP (pat, 0, 0);
8378 dlay = XVECEXP (pat, 0, 1);
8379 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
8380 continue;
8381 /* If the branch insn does the annulling, leave the delay insn alone. */
8382 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
8383 continue;
8384 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8385 on the other path. */
8386 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
8387 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
8388 src = SET_SRC (PATTERN (jump));
8389 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
8390 cond = XEXP (src, 0);
8391 if (XEXP (src, 2) == pc_rtx)
8392 reverse = 0;
8393 else if (XEXP (src, 1) == pc_rtx)
8394 reverse = 1;
8395 else
8396 gcc_unreachable ();
9af539fe 8397 if (reverse != !INSN_FROM_TARGET_P (dlay))
0bc69b81 8398 {
ef4bddc2 8399 machine_mode ccm = GET_MODE (XEXP (cond, 0));
0bc69b81
JR
8400 enum rtx_code code = reverse_condition (GET_CODE (cond));
8401 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8402 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8403
8404 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
8405 copy_rtx (XEXP (cond, 0)),
8406 copy_rtx (XEXP (cond, 1)));
8407 }
8408 else
8409 cond = copy_rtx (cond);
8410 patp = &PATTERN (dlay);
8411 pat = *patp;
eeac7d15 8412 pat = conditionalize_nonjump (pat, cond, dlay, true);
0bc69b81
JR
8413 validate_change (dlay, patp, pat, 1);
8414 if (!apply_change_group ())
8415 gcc_unreachable ();
8416 }
8417 return 0;
8418}
8419
526b7aee
SV
8420/* For ARC600: If a write to a core reg >=32 appears in a delay slot
8421 (other than of a forward brcc), it creates a hazard when there is a read
8422 of the same register at the branch target. We can't know what is at the
8423 branch target of calls, and for branches, we don't really know before the
8424 end of delay slot scheduling, either. Not only can individual instruction
8425 be hoisted out into a delay slot, a basic block can also be emptied this
8426 way, and branch and/or fall through targets be redirected. Hence we don't
8427 want such writes in a delay slot. */
526b7aee
SV
8428
8429/* Return nonzreo iff INSN writes to an extension core register. */
8430
8431int
8432arc_write_ext_corereg (rtx insn)
8433{
24dbe738
RS
8434 subrtx_iterator::array_type array;
8435 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
8436 {
8437 const_rtx x = *iter;
8438 switch (GET_CODE (x))
8439 {
8440 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8441 break;
8442 default:
8443 /* This is also fine for PRE/POST_MODIFY, because they
8444 contain a SET. */
8445 continue;
8446 }
8447 const_rtx dest = XEXP (x, 0);
8448 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
8449 return 1;
8450 }
8451 return 0;
526b7aee
SV
8452}
8453
8454/* This is like the hook, but returns NULL when it can't / won't generate
8455 a legitimate address. */
8456
8457static rtx
8458arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 8459 machine_mode mode)
526b7aee
SV
8460{
8461 rtx addr, inner;
8462
8463 if (flag_pic && SYMBOLIC_CONST (x))
8464 (x) = arc_legitimize_pic_address (x, 0);
8465 addr = x;
8466 if (GET_CODE (addr) == CONST)
8467 addr = XEXP (addr, 0);
8468 if (GET_CODE (addr) == PLUS
8469 && CONST_INT_P (XEXP (addr, 1))
8470 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
8471 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
8472 || (REG_P (XEXP (addr, 0))
8473 && (INTVAL (XEXP (addr, 1)) & 252))))
8474 {
8475 HOST_WIDE_INT offs, upper;
8476 int size = GET_MODE_SIZE (mode);
8477
8478 offs = INTVAL (XEXP (addr, 1));
8479 upper = (offs + 256 * size) & ~511 * size;
8480 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
8481#if 0 /* ??? this produces worse code for EEMBC idctrn01 */
8482 if (GET_CODE (x) == CONST)
8483 inner = gen_rtx_CONST (Pmode, inner);
8484#endif
8485 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
8486 x = addr;
8487 }
8488 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
8489 x = force_reg (Pmode, x);
ef4bddc2 8490 if (memory_address_p ((machine_mode) mode, x))
526b7aee
SV
8491 return x;
8492 return NULL_RTX;
8493}
8494
8495static rtx
ef4bddc2 8496arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
526b7aee
SV
8497{
8498 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
8499
8500 if (new_x)
8501 return new_x;
8502 return orig_x;
8503}
8504
8505static rtx
8506arc_delegitimize_address_0 (rtx x)
8507{
8508 rtx u, gp;
8509
8510 if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
8511 {
8512 if (XINT (u, 1) == ARC_UNSPEC_GOT)
8513 return XVECEXP (u, 0, 0);
8514 }
8515 else if (GET_CODE (x) == PLUS
8516 && ((REG_P (gp = XEXP (x, 0))
8517 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8518 || (GET_CODE (gp) == CONST
8519 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8520 && XINT (u, 1) == ARC_UNSPEC_GOT
8521 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8522 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8523 && GET_CODE (XEXP (x, 1)) == CONST
8524 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8525 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8526 return XVECEXP (u, 0, 0);
8527 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
8528 && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
8529 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
8530 || (GET_CODE (gp) == CONST
8531 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
8532 && XINT (u, 1) == ARC_UNSPEC_GOT
8533 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
8534 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
8535 && GET_CODE (XEXP (x, 1)) == CONST
8536 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
8537 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
8538 return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
8539 XVECEXP (u, 0, 0));
8540 else if (GET_CODE (x) == PLUS
8541 && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
8542 return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
8543 return NULL_RTX;
8544}
8545
8546static rtx
8547arc_delegitimize_address (rtx x)
8548{
8549 rtx orig_x = x = delegitimize_mem_from_attrs (x);
8550 if (GET_CODE (x) == MEM)
8551 x = XEXP (x, 0);
8552 x = arc_delegitimize_address_0 (x);
8553 if (x)
8554 {
8555 if (MEM_P (orig_x))
8556 x = replace_equiv_address_nv (orig_x, x);
8557 return x;
8558 }
8559 return orig_x;
8560}
8561
8562/* Return a REG rtx for acc1. N.B. the gcc-internal representation may
8563 differ from the hardware register number in order to allow the generic
8564 code to correctly split the concatenation of acc1 and acc2. */
8565
8566rtx
8567gen_acc1 (void)
8568{
8569 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
8570}
8571
8572/* Return a REG rtx for acc2. N.B. the gcc-internal representation may
8573 differ from the hardware register number in order to allow the generic
8574 code to correctly split the concatenation of acc1 and acc2. */
8575
8576rtx
8577gen_acc2 (void)
8578{
8579 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
8580}
8581
8582/* Return a REG rtx for mlo. N.B. the gcc-internal representation may
8583 differ from the hardware register number in order to allow the generic
8584 code to correctly split the concatenation of mhi and mlo. */
8585
8586rtx
8587gen_mlo (void)
8588{
8589 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
8590}
8591
8592/* Return a REG rtx for mhi. N.B. the gcc-internal representation may
8593 differ from the hardware register number in order to allow the generic
8594 code to correctly split the concatenation of mhi and mlo. */
8595
8596rtx
8597gen_mhi (void)
8598{
8599 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
8600}
8601
8602/* FIXME: a parameter should be added, and code added to final.c,
8603 to reproduce this functionality in shorten_branches. */
8604#if 0
8605/* Return nonzero iff BRANCH should be unaligned if possible by upsizing
8606 a previous instruction. */
8607int
8608arc_unalign_branch_p (rtx branch)
8609{
8610 rtx note;
8611
8612 if (!TARGET_UNALIGN_BRANCH)
8613 return 0;
8614 /* Do not do this if we have a filled delay slot. */
8615 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
4654c0cf 8616 && !NEXT_INSN (branch)->deleted ())
526b7aee
SV
8617 return 0;
8618 note = find_reg_note (branch, REG_BR_PROB, 0);
8619 return (!note
8620 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
8621 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
8622}
8623#endif
8624
8625/* When estimating sizes during arc_reorg, when optimizing for speed, there
8626 are three reasons why we need to consider branches to be length 6:
8627 - annull-false delay slot insns are implemented using conditional execution,
8628 thus preventing short insn formation where used.
8629 - for ARC600: annul-true delay slot insns are implemented where possible
8630 using conditional execution, preventing short insn formation where used.
8631 - for ARC700: likely or somewhat likely taken branches are made long and
8632 unaligned if possible to avoid branch penalty. */
8633
8634bool
8635arc_branch_size_unknown_p (void)
8636{
8637 return !optimize_size && arc_reorg_in_progress;
8638}
8639
8640/* We are about to output a return insn. Add padding if necessary to avoid
8641 a mispredict. A return could happen immediately after the function
8642 start, but after a call we know that there will be at least a blink
8643 restore. */
8644
8645void
8646arc_pad_return (void)
8647{
fa7af581 8648 rtx_insn *insn = current_output_insn;
b3458f61 8649 rtx_insn *prev = prev_active_insn (insn);
526b7aee
SV
8650 int want_long;
8651
8652 if (!prev)
8653 {
8654 fputs ("\tnop_s\n", asm_out_file);
8655 cfun->machine->unalign ^= 2;
8656 want_long = 1;
8657 }
8658 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
8659 because after a call, we'd have to restore blink first. */
8660 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
8661 return;
8662 else
8663 {
8664 want_long = (get_attr_length (prev) == 2);
8665 prev = prev_active_insn (prev);
8666 }
8667 if (!prev
8668 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
84034c69
DM
8669 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8670 NON_SIBCALL)
526b7aee
SV
8671 : CALL_ATTR (prev, NON_SIBCALL)))
8672 {
8673 if (want_long)
8674 cfun->machine->size_reason
8675 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
8676 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
8677 {
8678 cfun->machine->size_reason
8679 = "Long unaligned jump avoids non-delay slot penalty";
8680 want_long = 1;
8681 }
8682 /* Disgorge delay insn, if there is any, and it may be moved. */
8683 if (final_sequence
8684 /* ??? Annulled would be OK if we can and do conditionalize
8685 the delay slot insn accordingly. */
8686 && !INSN_ANNULLED_BRANCH_P (insn)
8687 && (get_attr_cond (insn) != COND_USE
8688 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
8689 XVECEXP (final_sequence, 0, 1))))
8690 {
b3458f61 8691 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
526b7aee
SV
8692 gcc_assert (!prev_real_insn (insn)
8693 || !arc_hazard (prev_real_insn (insn), prev));
8694 cfun->machine->force_short_suffix = !want_long;
8695 rtx save_pred = current_insn_predicate;
8696 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
8697 cfun->machine->force_short_suffix = -1;
4654c0cf 8698 prev->set_deleted ();
526b7aee
SV
8699 current_output_insn = insn;
8700 current_insn_predicate = save_pred;
8701 }
8702 else if (want_long)
8703 fputs ("\tnop\n", asm_out_file);
8704 else
8705 {
8706 fputs ("\tnop_s\n", asm_out_file);
8707 cfun->machine->unalign ^= 2;
8708 }
8709 }
8710 return;
8711}
8712
8713/* The usual; we set up our machine_function data. */
8714
8715static struct machine_function *
8716arc_init_machine_status (void)
8717{
8718 struct machine_function *machine;
766090c2 8719 machine = ggc_cleared_alloc<machine_function> ();
526b7aee
SV
8720 machine->fn_type = ARC_FUNCTION_UNKNOWN;
8721 machine->force_short_suffix = -1;
8722
8723 return machine;
8724}
8725
8726/* Implements INIT_EXPANDERS. We just set up to call the above
8727 function. */
8728
8729void
8730arc_init_expanders (void)
8731{
8732 init_machine_status = arc_init_machine_status;
8733}
8734
8735/* Check if OP is a proper parallel of a millicode call pattern. OFFSET
8736 indicates a number of elements to ignore - that allows to have a
8737 sibcall pattern that starts with (return). LOAD_P is zero for store
8738 multiple (for prologues), and one for load multiples (for epilogues),
8739 and two for load multiples where no final clobber of blink is required.
8740 We also skip the first load / store element since this is supposed to
8741 be checked in the instruction pattern. */
8742
8743int
8744arc_check_millicode (rtx op, int offset, int load_p)
8745{
8746 int len = XVECLEN (op, 0) - offset;
8747 int i;
8748
8749 if (load_p == 2)
8750 {
8751 if (len < 2 || len > 13)
8752 return 0;
8753 load_p = 1;
8754 }
8755 else
8756 {
8757 rtx elt = XVECEXP (op, 0, --len);
8758
8759 if (GET_CODE (elt) != CLOBBER
8760 || !REG_P (XEXP (elt, 0))
8761 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
8762 || len < 3 || len > 13)
8763 return 0;
8764 }
8765 for (i = 1; i < len; i++)
8766 {
8767 rtx elt = XVECEXP (op, 0, i + offset);
8768 rtx reg, mem, addr;
8769
8770 if (GET_CODE (elt) != SET)
8771 return 0;
8772 mem = XEXP (elt, load_p);
8773 reg = XEXP (elt, 1-load_p);
8774 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
8775 return 0;
8776 addr = XEXP (mem, 0);
8777 if (GET_CODE (addr) != PLUS
8778 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
8779 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
8780 return 0;
8781 }
8782 return 1;
8783}
8784
8785/* Accessor functions for cfun->machine->unalign. */
8786
8787int
8788arc_get_unalign (void)
8789{
8790 return cfun->machine->unalign;
8791}
8792
8793void
8794arc_clear_unalign (void)
8795{
8796 if (cfun)
8797 cfun->machine->unalign = 0;
8798}
8799
8800void
8801arc_toggle_unalign (void)
8802{
8803 cfun->machine->unalign ^= 2;
8804}
8805
8806/* Operands 0..2 are the operands of a addsi which uses a 12 bit
8807 constant in operand 2, but which would require a LIMM because of
8808 operand mismatch.
8809 operands 3 and 4 are new SET_SRCs for operands 0. */
8810
8811void
8812split_addsi (rtx *operands)
8813{
8814 int val = INTVAL (operands[2]);
8815
8816 /* Try for two short insns first. Lengths being equal, we prefer
8817 expansions with shorter register lifetimes. */
8818 if (val > 127 && val <= 255
8819 && satisfies_constraint_Rcq (operands[0]))
8820 {
8821 operands[3] = operands[2];
8822 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8823 }
8824 else
8825 {
8826 operands[3] = operands[1];
8827 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
8828 }
8829}
8830
8831/* Operands 0..2 are the operands of a subsi which uses a 12 bit
8832 constant in operand 1, but which would require a LIMM because of
8833 operand mismatch.
8834 operands 3 and 4 are new SET_SRCs for operands 0. */
8835
8836void
8837split_subsi (rtx *operands)
8838{
8839 int val = INTVAL (operands[1]);
8840
8841 /* Try for two short insns first. Lengths being equal, we prefer
8842 expansions with shorter register lifetimes. */
8843 if (satisfies_constraint_Rcq (operands[0])
8844 && satisfies_constraint_Rcq (operands[2]))
8845 {
8846 if (val >= -31 && val <= 127)
8847 {
8848 operands[3] = gen_rtx_NEG (SImode, operands[2]);
8849 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
8850 return;
8851 }
8852 else if (val >= 0 && val < 255)
8853 {
8854 operands[3] = operands[1];
8855 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
8856 return;
8857 }
8858 }
8859 /* If the destination is not an ARCompact16 register, we might
8860 still have a chance to make a short insn if the source is;
8861 we need to start with a reg-reg move for this. */
8862 operands[3] = operands[2];
8863 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
8864}
8865
8866/* Handle DOUBLE_REGS uses.
8867 Operand 0: destination register
8868 Operand 1: source register */
8869
8870static rtx
8871arc_process_double_reg_moves (rtx *operands)
8872{
8873 rtx dest = operands[0];
8874 rtx src = operands[1];
8875 rtx val;
8876
8877 enum usesDxState { none, srcDx, destDx, maxDx };
8878 enum usesDxState state = none;
8879
8880 if (refers_to_regno_p (40, 44, src, 0))
8881 state = srcDx;
8882 if (refers_to_regno_p (40, 44, dest, 0))
8883 {
8884 /* Via arc_register_move_cost, we should never see D,D moves. */
8885 gcc_assert (state == none);
8886 state = destDx;
8887 }
8888
8889 if (state == none)
8890 return NULL_RTX;
8891
8892 start_sequence ();
8893
8894 if (state == srcDx)
8895 {
8896 /* Without the LR insn, we need to split this into a
8897 sequence of insns which will use the DEXCLx and DADDHxy
8898 insns to be able to read the Dx register in question. */
8899 if (TARGET_DPFP_DISABLE_LRSR)
8900 {
8901 /* gen *movdf_insn_nolrsr */
f7df4a84 8902 rtx set = gen_rtx_SET (dest, src);
526b7aee
SV
8903 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
8904 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
8905 }
8906 else
8907 {
8908 /* When we have 'mov D, r' or 'mov D, D' then get the target
8909 register pair for use with LR insn. */
8910 rtx destHigh = simplify_gen_subreg(SImode, dest, DFmode, 4);
8911 rtx destLow = simplify_gen_subreg(SImode, dest, DFmode, 0);
8912
8913 /* Produce the two LR insns to get the high and low parts. */
f7df4a84 8914 emit_insn (gen_rtx_SET (destHigh,
526b7aee
SV
8915 gen_rtx_UNSPEC_VOLATILE (Pmode, gen_rtvec (1, src),
8916 VUNSPEC_LR_HIGH)));
f7df4a84 8917 emit_insn (gen_rtx_SET (destLow,
526b7aee
SV
8918 gen_rtx_UNSPEC_VOLATILE (Pmode, gen_rtvec (1, src),
8919 VUNSPEC_LR)));
8920 }
8921 }
8922 else if (state == destDx)
8923 {
8924 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
8925 LR insn get the target register pair. */
8926 rtx srcHigh = simplify_gen_subreg(SImode, src, DFmode, 4);
8927 rtx srcLow = simplify_gen_subreg(SImode, src, DFmode, 0);
8928
8929 emit_insn (gen_rtx_UNSPEC_VOLATILE (Pmode,
8930 gen_rtvec (3, dest, srcHigh, srcLow),
8931 VUNSPEC_DEXCL_NORES));
8932
8933 }
8934 else
8935 gcc_unreachable ();
8936
8937 val = get_insns ();
8938 end_sequence ();
8939 return val;
8940}
8941
8942/* operands 0..1 are the operands of a 64 bit move instruction.
8943 split it into two moves with operands 2/3 and 4/5. */
8944
8945rtx
8946arc_split_move (rtx *operands)
8947{
ef4bddc2 8948 machine_mode mode = GET_MODE (operands[0]);
526b7aee
SV
8949 int i;
8950 int swap = 0;
8951 rtx xop[4];
8952 rtx val;
8953
8954 if (TARGET_DPFP)
8955 {
8956 val = arc_process_double_reg_moves (operands);
8957 if (val)
8958 return val;
8959 }
8960
8961 for (i = 0; i < 2; i++)
8962 {
8963 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
8964 {
8965 rtx addr = XEXP (operands[i], 0);
8966 rtx r, o;
8967 enum rtx_code code;
8968
8969 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
8970 switch (GET_CODE (addr))
8971 {
8972 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
8973 case PRE_INC: o = GEN_INT (8); goto pre_modify;
8974 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
8975 pre_modify:
8976 code = PRE_MODIFY;
8977 break;
8978 case POST_DEC: o = GEN_INT (-8); goto post_modify;
8979 case POST_INC: o = GEN_INT (8); goto post_modify;
8980 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
8981 post_modify:
8982 code = POST_MODIFY;
8983 swap = 2;
8984 break;
8985 default:
8986 gcc_unreachable ();
8987 }
8988 r = XEXP (addr, 0);
8989 xop[0+i] = adjust_automodify_address_nv
8990 (operands[i], SImode,
8991 gen_rtx_fmt_ee (code, Pmode, r,
8992 gen_rtx_PLUS (Pmode, r, o)),
8993 0);
8994 xop[2+i] = adjust_automodify_address_nv
8995 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
8996 }
8997 else
8998 {
8999 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9000 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9001 }
9002 }
9003 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9004 {
9005 swap = 2;
9006 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9007 }
9008 operands[2+swap] = xop[0];
9009 operands[3+swap] = xop[1];
9010 operands[4-swap] = xop[2];
9011 operands[5-swap] = xop[3];
9012
9013 start_sequence ();
f7df4a84
RS
9014 emit_insn (gen_rtx_SET (operands[2], operands[3]));
9015 emit_insn (gen_rtx_SET (operands[4], operands[5]));
526b7aee
SV
9016 val = get_insns ();
9017 end_sequence ();
9018
9019 return val;
9020}
9021
9022/* Select between the instruction output templates s_tmpl (for short INSNs)
9023 and l_tmpl (for long INSNs). */
9024
9025const char *
b3458f61 9026arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
526b7aee
SV
9027{
9028 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9029
9030 extract_constrain_insn_cached (insn);
9031 return is_short ? s_tmpl : l_tmpl;
9032}
9033
9034/* Searches X for any reference to REGNO, returning the rtx of the
9035 reference found if any. Otherwise, returns NULL_RTX. */
9036
9037rtx
9038arc_regno_use_in (unsigned int regno, rtx x)
9039{
9040 const char *fmt;
9041 int i, j;
9042 rtx tem;
9043
c9bd6bcd 9044 if (REG_P (x) && refers_to_regno_p (regno, x))
526b7aee
SV
9045 return x;
9046
9047 fmt = GET_RTX_FORMAT (GET_CODE (x));
9048 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9049 {
9050 if (fmt[i] == 'e')
9051 {
9052 if ((tem = regno_use_in (regno, XEXP (x, i))))
9053 return tem;
9054 }
9055 else if (fmt[i] == 'E')
9056 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9057 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9058 return tem;
9059 }
9060
9061 return NULL_RTX;
9062}
9063
9064/* Return the integer value of the "type" attribute for INSN, or -1 if
9065 INSN can't have attributes. */
9066
9067int
84034c69 9068arc_attr_type (rtx_insn *insn)
526b7aee
SV
9069{
9070 if (NONJUMP_INSN_P (insn)
9071 ? (GET_CODE (PATTERN (insn)) == USE
9072 || GET_CODE (PATTERN (insn)) == CLOBBER)
9073 : JUMP_P (insn)
9074 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9075 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9076 : !CALL_P (insn))
9077 return -1;
9078 return get_attr_type (insn);
9079}
9080
9081/* Return true if insn sets the condition codes. */
9082
9083bool
84034c69 9084arc_sets_cc_p (rtx_insn *insn)
526b7aee 9085{
84034c69
DM
9086 if (NONJUMP_INSN_P (insn))
9087 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9088 insn = seq->insn (seq->len () - 1);
526b7aee
SV
9089 return arc_attr_type (insn) == TYPE_COMPARE;
9090}
9091
9092/* Return true if INSN is an instruction with a delay slot we may want
9093 to fill. */
9094
9095bool
b3458f61 9096arc_need_delay (rtx_insn *insn)
526b7aee 9097{
b3458f61 9098 rtx_insn *next;
526b7aee
SV
9099
9100 if (!flag_delayed_branch)
9101 return false;
9102 /* The return at the end of a function needs a delay slot. */
9103 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9104 && (!(next = next_active_insn (insn))
9105 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9106 && arc_attr_type (next) == TYPE_RETURN))
9107 && (!TARGET_PAD_RETURN
9108 || (prev_active_insn (insn)
9109 && prev_active_insn (prev_active_insn (insn))
9110 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9111 return true;
9112 if (NONJUMP_INSN_P (insn)
9113 ? (GET_CODE (PATTERN (insn)) == USE
9114 || GET_CODE (PATTERN (insn)) == CLOBBER
9115 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9116 : JUMP_P (insn)
9117 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9118 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9119 : !CALL_P (insn))
9120 return false;
9121 return num_delay_slots (insn) != 0;
9122}
9123
9124/* Return true if the scheduling pass(es) has/have already run,
9125 i.e. where possible, we should try to mitigate high latencies
9126 by different instruction selection. */
9127
9128bool
9129arc_scheduling_not_expected (void)
9130{
9131 return cfun->machine->arc_reorg_started;
9132}
9133
9134/* Oddly enough, sometimes we get a zero overhead loop that branch
9135 shortening doesn't think is a loop - observed with compile/pr24883.c
9136 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9137 alignment visible for branch shortening (we actually align the loop
9138 insn before it, but that is equivalent since the loop insn is 4 byte
9139 long.) */
9140
9141int
9142arc_label_align (rtx label)
9143{
9144 int loop_align = LOOP_ALIGN (LABEL);
9145
9146 if (loop_align > align_labels_log)
9147 {
b3458f61 9148 rtx_insn *prev = prev_nonnote_insn (label);
526b7aee
SV
9149
9150 if (prev && NONJUMP_INSN_P (prev)
9151 && GET_CODE (PATTERN (prev)) == PARALLEL
9152 && recog_memoized (prev) == CODE_FOR_doloop_begin_i)
9153 return loop_align;
9154 }
9155 /* Code has a minimum p2 alignment of 1, which we must restore after an
9156 ADDR_DIFF_VEC. */
9157 if (align_labels_log < 1)
9158 {
b3458f61 9159 rtx_insn *next = next_nonnote_nondebug_insn (label);
526b7aee
SV
9160 if (INSN_P (next) && recog_memoized (next) >= 0)
9161 return 1;
9162 }
9163 return align_labels_log;
9164}
9165
9166/* Return true if LABEL is in executable code. */
9167
9168bool
b32d5189 9169arc_text_label (rtx_insn *label)
526b7aee 9170{
b3458f61 9171 rtx_insn *next;
526b7aee
SV
9172
9173 /* ??? We use deleted labels like they were still there, see
9174 gcc.c-torture/compile/20000326-2.c . */
9175 gcc_assert (GET_CODE (label) == CODE_LABEL
9176 || (GET_CODE (label) == NOTE
9177 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9178 next = next_nonnote_insn (label);
9179 if (next)
9180 return (!JUMP_TABLE_DATA_P (next)
9181 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9182 else if (!PREV_INSN (label))
9183 /* ??? sometimes text labels get inserted very late, see
9184 gcc.dg/torture/stackalign/comp-goto-1.c */
9185 return true;
9186 return false;
9187}
9188
9189/* Return the size of the pretend args for DECL. */
9190
9191int
9192arc_decl_pretend_args (tree decl)
9193{
9194 /* struct function is in DECL_STRUCT_FUNCTION (decl), but no
9195 pretend_args there... See PR38391. */
9196 gcc_assert (decl == current_function_decl);
9197 return crtl->args.pretend_args_size;
9198}
9199
9200/* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9201 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
339ba33b 9202 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
526b7aee
SV
9203 to redirect two breqs. */
9204
9205static bool
c1ce59ab 9206arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
526b7aee
SV
9207{
9208 /* ??? get_attr_type is declared to take an rtx. */
c1ce59ab 9209 union { const rtx_insn *c; rtx_insn *r; } u;
526b7aee
SV
9210
9211 u.c = follower;
339ba33b 9212 if (CROSSING_JUMP_P (followee))
526b7aee
SV
9213 switch (get_attr_type (u.r))
9214 {
9215 case TYPE_BRCC:
9216 case TYPE_BRCC_NO_DELAY_SLOT:
9217 return false;
9218 default:
9219 return true;
9220 }
9221 return true;
9222}
9223
9224/* Implement EPILOGUE__USES.
9225 Return true if REGNO should be added to the deemed uses of the epilogue.
9226
9227 We use the return address
9228 arc_return_address_regs[arc_compute_function_type (cfun)] .
9229 But also, we have to make sure all the register restore instructions
9230 are known to be live in interrupt functions. */
9231
9232bool
9233arc_epilogue_uses (int regno)
9234{
9235 if (reload_completed)
9236 {
9237 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9238 {
9239 if (!fixed_regs[regno])
9240 return true;
9241 return regno == arc_return_address_regs[cfun->machine->fn_type];
9242 }
9243 else
9244 return regno == RETURN_ADDR_REGNUM;
9245 }
9246 else
9247 return regno == arc_return_address_regs[arc_compute_function_type (cfun)];
9248}
9249
9250#ifndef TARGET_NO_LRA
9251#define TARGET_NO_LRA !TARGET_LRA
9252#endif
9253
9254static bool
9255arc_lra_p (void)
9256{
9257 return !TARGET_NO_LRA;
9258}
9259
9260/* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9261 Rcq registers, because some insn are shorter with them. OTOH we already
9262 have separate alternatives for this purpose, and other insns don't
9263 mind, so maybe we should rather prefer the other registers?
9264 We need more data, and we can only get that if we allow people to
9265 try all options. */
9266static int
9267arc_register_priority (int r)
9268{
9269 switch (arc_lra_priority_tag)
9270 {
9271 case ARC_LRA_PRIORITY_NONE:
9272 return 0;
9273 case ARC_LRA_PRIORITY_NONCOMPACT:
9274 return ((((r & 7) ^ 4) - 4) & 15) != r;
9275 case ARC_LRA_PRIORITY_COMPACT:
9276 return ((((r & 7) ^ 4) - 4) & 15) == r;
9277 default:
9278 gcc_unreachable ();
9279 }
9280}
9281
9282static reg_class_t
ef4bddc2 9283arc_spill_class (reg_class_t /* orig_class */, machine_mode)
526b7aee
SV
9284{
9285 return GENERAL_REGS;
9286}
9287
9288bool
ef4bddc2 9289arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
526b7aee
SV
9290 int itype)
9291{
9292 rtx x = *p;
9293 enum reload_type type = (enum reload_type) itype;
9294
9295 if (GET_CODE (x) == PLUS
9296 && CONST_INT_P (XEXP (x, 1))
9297 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9298 || (REG_P (XEXP (x, 0))
9299 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9300 {
9301 int scale = GET_MODE_SIZE (mode);
9302 int shift;
9303 rtx index_rtx = XEXP (x, 1);
9304 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9305 rtx reg, sum, sum2;
9306
9307 if (scale > 4)
9308 scale = 4;
9309 if ((scale-1) & offset)
9310 scale = 1;
9311 shift = scale >> 1;
c419f71c
JL
9312 offset_base
9313 = ((offset + (256 << shift))
4e671509 9314 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
526b7aee
SV
9315 /* Sometimes the normal form does not suit DImode. We
9316 could avoid that by using smaller ranges, but that
9317 would give less optimized code when SImode is
9318 prevalent. */
9319 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9320 {
9321 int regno;
9322
9323 reg = XEXP (x, 0);
9324 regno = REGNO (reg);
9325 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9326
9327 if (reg_equiv_constant (regno))
9328 {
9329 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9330 offset_base);
9331 if (GET_CODE (sum2) == PLUS)
9332 sum2 = gen_rtx_CONST (Pmode, sum2);
9333 }
9334 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9335 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9336 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9337 type);
9338 return true;
9339 }
9340 }
9341 /* We must re-recognize what we created before. */
9342 else if (GET_CODE (x) == PLUS
9343 && GET_CODE (XEXP (x, 0)) == PLUS
9344 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9345 && REG_P (XEXP (XEXP (x, 0), 0))
9346 && CONST_INT_P (XEXP (x, 1)))
9347 {
9348 /* Because this address is so complex, we know it must have
9349 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9350 it is already unshared, and needs no further unsharing. */
9351 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9352 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
9353 return true;
9354 }
9355 return false;
9356}
9357
ad23f5d4
JG
9358/* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9359
9360static bool
445d7826 9361arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
ad23f5d4
JG
9362 unsigned int align,
9363 enum by_pieces_operation op,
9364 bool speed_p)
9365{
9366 /* Let the movmem expander handle small block moves. */
9367 if (op == MOVE_BY_PIECES)
9368 return false;
9369
9370 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
9371}
9372
526b7aee
SV
9373struct gcc_target targetm = TARGET_INITIALIZER;
9374
9375#include "gt-arc.h"