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