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