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