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