comparison gcc/config/spu/spu.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 1 /* Copyright (C) 2006-2017 Free Software Foundation, Inc.
2 2
3 This file is free software; you can redistribute it and/or modify it under 3 This file is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free 4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3 of the License, or (at your option) 5 Software Foundation; either version 3 of the License, or (at your option)
6 any later version. 6 any later version.
15 <http://www.gnu.org/licenses/>. */ 15 <http://www.gnu.org/licenses/>. */
16 16
17 #include "config.h" 17 #include "config.h"
18 #include "system.h" 18 #include "system.h"
19 #include "coretypes.h" 19 #include "coretypes.h"
20 #include "tm.h" 20 #include "backend.h"
21 #include "target.h"
21 #include "rtl.h" 22 #include "rtl.h"
23 #include "tree.h"
24 #include "gimple.h"
25 #include "cfghooks.h"
26 #include "cfgloop.h"
27 #include "df.h"
28 #include "memmodel.h"
29 #include "tm_p.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "expmed.h"
33 #include "optabs.h"
22 #include "regs.h" 34 #include "regs.h"
23 #include "hard-reg-set.h" 35 #include "emit-rtl.h"
24 #include "insn-config.h" 36 #include "recog.h"
25 #include "conditions.h" 37 #include "diagnostic-core.h"
26 #include "insn-attr.h" 38 #include "insn-attr.h"
27 #include "flags.h" 39 #include "alias.h"
28 #include "recog.h" 40 #include "fold-const.h"
29 #include "obstack.h" 41 #include "stor-layout.h"
30 #include "tree.h" 42 #include "calls.h"
43 #include "varasm.h"
44 #include "explow.h"
31 #include "expr.h" 45 #include "expr.h"
32 #include "optabs.h"
33 #include "except.h"
34 #include "function.h"
35 #include "output.h" 46 #include "output.h"
36 #include "basic-block.h" 47 #include "cfgrtl.h"
37 #include "integrate.h" 48 #include "cfgbuild.h"
38 #include "diagnostic-core.h"
39 #include "ggc.h"
40 #include "hashtab.h"
41 #include "tm_p.h"
42 #include "target.h"
43 #include "target-def.h"
44 #include "langhooks.h" 49 #include "langhooks.h"
45 #include "reload.h" 50 #include "reload.h"
46 #include "cfglayout.h"
47 #include "sched-int.h" 51 #include "sched-int.h"
48 #include "params.h" 52 #include "params.h"
49 #include "machmode.h" 53 #include "gimplify.h"
50 #include "gimple.h"
51 #include "tm-constrs.h" 54 #include "tm-constrs.h"
52 #include "ddg.h" 55 #include "ddg.h"
53 #include "sbitmap.h" 56 #include "dumpfile.h"
54 #include "timevar.h" 57 #include "builtins.h"
55 #include "df.h" 58 #include "rtl-iter.h"
59
60 /* This file should be included last. */
61 #include "target-def.h"
56 62
57 /* Builtin types, data and prototypes. */ 63 /* Builtin types, data and prototypes. */
58 64
59 enum spu_builtin_type_index 65 enum spu_builtin_type_index
60 { 66 {
145 151
146 /* Target specific attribute specifications. */ 152 /* Target specific attribute specifications. */
147 char regs_ever_allocated[FIRST_PSEUDO_REGISTER]; 153 char regs_ever_allocated[FIRST_PSEUDO_REGISTER];
148 154
149 /* Prototypes and external defs. */ 155 /* Prototypes and external defs. */
150 static void spu_option_override (void); 156 static int get_pipe (rtx_insn *insn);
151 static void spu_option_init_struct (struct gcc_options *opts);
152 static void spu_option_default_params (void);
153 static void spu_init_builtins (void);
154 static tree spu_builtin_decl (unsigned, bool);
155 static bool spu_scalar_mode_supported_p (enum machine_mode mode);
156 static bool spu_vector_mode_supported_p (enum machine_mode mode);
157 static bool spu_legitimate_address_p (enum machine_mode, rtx, bool);
158 static bool spu_addr_space_legitimate_address_p (enum machine_mode, rtx,
159 bool, addr_space_t);
160 static rtx adjust_operand (rtx op, HOST_WIDE_INT * start);
161 static rtx get_pic_reg (void);
162 static int need_to_save_reg (int regno, int saving);
163 static rtx frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset);
164 static rtx frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset);
165 static rtx frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm,
166 rtx scratch);
167 static void emit_nop_for_insn (rtx insn);
168 static bool insn_clobbers_hbr (rtx insn);
169 static void spu_emit_branch_hint (rtx before, rtx branch, rtx target,
170 int distance, sbitmap blocks);
171 static rtx spu_emit_vector_compare (enum rtx_code rcode, rtx op0, rtx op1,
172 enum machine_mode dmode);
173 static rtx get_branch_target (rtx branch);
174 static void spu_machine_dependent_reorg (void);
175 static int spu_sched_issue_rate (void);
176 static int spu_sched_variable_issue (FILE * dump, int verbose, rtx insn,
177 int can_issue_more);
178 static int get_pipe (rtx insn);
179 static int spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost);
180 static void spu_sched_init_global (FILE *, int, int);
181 static void spu_sched_init (FILE *, int, int);
182 static int spu_sched_reorder (FILE *, int, rtx *, int *, int);
183 static tree spu_handle_fndecl_attribute (tree * node, tree name, tree args,
184 int flags,
185 bool *no_add_attrs);
186 static tree spu_handle_vector_attribute (tree * node, tree name, tree args,
187 int flags,
188 bool *no_add_attrs);
189 static int spu_naked_function_p (tree func); 157 static int spu_naked_function_p (tree func);
190 static bool spu_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
191 const_tree type, bool named);
192 static rtx spu_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
193 const_tree type, bool named);
194 static void spu_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
195 const_tree type, bool named);
196 static tree spu_build_builtin_va_list (void);
197 static void spu_va_start (tree, rtx);
198 static tree spu_gimplify_va_arg_expr (tree valist, tree type,
199 gimple_seq * pre_p, gimple_seq * post_p);
200 static int store_with_one_insn_p (rtx mem);
201 static int mem_is_padded_component_ref (rtx x); 158 static int mem_is_padded_component_ref (rtx x);
202 static int reg_aligned_for_addr (rtx x);
203 static bool spu_assemble_integer (rtx x, unsigned int size, int aligned_p);
204 static void spu_asm_globalize_label (FILE * file, const char *name);
205 static bool spu_rtx_costs (rtx x, int code, int outer_code,
206 int *total, bool speed);
207 static bool spu_function_ok_for_sibcall (tree decl, tree exp);
208 static void spu_init_libfuncs (void);
209 static bool spu_return_in_memory (const_tree type, const_tree fntype);
210 static void fix_range (const char *); 159 static void fix_range (const char *);
211 static void spu_encode_section_info (tree, rtx, int);
212 static rtx spu_legitimize_address (rtx, rtx, enum machine_mode);
213 static rtx spu_addr_space_legitimize_address (rtx, rtx, enum machine_mode,
214 addr_space_t);
215 static tree spu_builtin_mul_widen_even (tree);
216 static tree spu_builtin_mul_widen_odd (tree);
217 static tree spu_builtin_mask_for_load (void);
218 static int spu_builtin_vectorization_cost (enum vect_cost_for_stmt, tree, int);
219 static bool spu_vector_alignment_reachable (const_tree, bool);
220 static tree spu_builtin_vec_perm (tree, tree *);
221 static enum machine_mode spu_addr_space_pointer_mode (addr_space_t);
222 static enum machine_mode spu_addr_space_address_mode (addr_space_t);
223 static bool spu_addr_space_subset_p (addr_space_t, addr_space_t);
224 static rtx spu_addr_space_convert (rtx, tree, tree);
225 static int spu_sms_res_mii (struct ddg *g);
226 static void asm_file_start (void);
227 static unsigned int spu_section_type_flags (tree, const char *, int);
228 static section *spu_select_section (tree, int, unsigned HOST_WIDE_INT);
229 static void spu_unique_section (tree, int);
230 static rtx spu_expand_load (rtx, rtx, rtx, int); 160 static rtx spu_expand_load (rtx, rtx, rtx, int);
231 static void spu_trampoline_init (rtx, tree, rtx);
232 static void spu_conditional_register_usage (void);
233 static bool spu_ref_may_alias_errno (ao_ref *);
234 161
235 /* Which instruction set architecture to use. */ 162 /* Which instruction set architecture to use. */
236 int spu_arch; 163 int spu_arch;
237 /* Which cpu are we tuning for. */ 164 /* Which cpu are we tuning for. */
238 int spu_tune; 165 int spu_tune;
242 compiler needs to see before inserting a hint, and then the compiler 169 compiler needs to see before inserting a hint, and then the compiler
243 will insert enough nops to make it at least 8 insns. The default is 170 will insert enough nops to make it at least 8 insns. The default is
244 for the compiler to allow up to 2 nops be emitted. The nops are 171 for the compiler to allow up to 2 nops be emitted. The nops are
245 inserted in pairs, so we round down. */ 172 inserted in pairs, so we round down. */
246 int spu_hint_dist = (8*4) - (2*4); 173 int spu_hint_dist = (8*4) - (2*4);
247
248 /* Determines whether we run variable tracking in machine dependent
249 reorganization. */
250 static int spu_flag_var_tracking;
251 174
252 enum spu_immediate { 175 enum spu_immediate {
253 SPU_NONE, 176 SPU_NONE,
254 SPU_IL, 177 SPU_IL,
255 SPU_ILA, 178 SPU_ILA,
274 197
275 static enum spu_immediate which_immediate_load (HOST_WIDE_INT val); 198 static enum spu_immediate which_immediate_load (HOST_WIDE_INT val);
276 static enum spu_immediate which_logical_immediate (HOST_WIDE_INT val); 199 static enum spu_immediate which_logical_immediate (HOST_WIDE_INT val);
277 static int cpat_info(unsigned char *arr, int size, int *prun, int *pstart); 200 static int cpat_info(unsigned char *arr, int size, int *prun, int *pstart);
278 static enum immediate_class classify_immediate (rtx op, 201 static enum immediate_class classify_immediate (rtx op,
279 enum machine_mode mode); 202 machine_mode mode);
280
281 static enum machine_mode spu_unwind_word_mode (void);
282
283 static enum machine_mode
284 spu_libgcc_cmp_return_mode (void);
285
286 static enum machine_mode
287 spu_libgcc_shift_count_mode (void);
288 203
289 /* Pointer mode for __ea references. */ 204 /* Pointer mode for __ea references. */
290 #define EAmode (spu_ea_model != 32 ? DImode : SImode) 205 #define EAmode (spu_ea_model != 32 ? DImode : SImode)
291 206
292 207
293 /* Table of machine attributes. */ 208 /* Define the structure for the machine field in struct function. */
294 static const struct attribute_spec spu_attribute_table[] = 209 struct GTY(()) machine_function
295 { 210 {
296 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ 211 /* Register to use for PIC accesses. */
297 { "naked", 0, 0, true, false, false, spu_handle_fndecl_attribute }, 212 rtx pic_reg;
298 { "spu_vector", 0, 0, false, true, false, spu_handle_vector_attribute },
299 { NULL, 0, 0, false, false, false, NULL }
300 }; 213 };
301 214
302 /* TARGET overrides. */ 215 /* How to allocate a 'struct machine_function'. */
303 216 static struct machine_function *
304 #undef TARGET_ADDR_SPACE_POINTER_MODE 217 spu_init_machine_status (void)
305 #define TARGET_ADDR_SPACE_POINTER_MODE spu_addr_space_pointer_mode 218 {
306 219 return ggc_cleared_alloc<machine_function> ();
307 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
308 #define TARGET_ADDR_SPACE_ADDRESS_MODE spu_addr_space_address_mode
309
310 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
311 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
312 spu_addr_space_legitimate_address_p
313
314 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
315 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS spu_addr_space_legitimize_address
316
317 #undef TARGET_ADDR_SPACE_SUBSET_P
318 #define TARGET_ADDR_SPACE_SUBSET_P spu_addr_space_subset_p
319
320 #undef TARGET_ADDR_SPACE_CONVERT
321 #define TARGET_ADDR_SPACE_CONVERT spu_addr_space_convert
322
323 #undef TARGET_INIT_BUILTINS
324 #define TARGET_INIT_BUILTINS spu_init_builtins
325 #undef TARGET_BUILTIN_DECL
326 #define TARGET_BUILTIN_DECL spu_builtin_decl
327
328 #undef TARGET_EXPAND_BUILTIN
329 #define TARGET_EXPAND_BUILTIN spu_expand_builtin
330
331 #undef TARGET_UNWIND_WORD_MODE
332 #define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode
333
334 #undef TARGET_LEGITIMIZE_ADDRESS
335 #define TARGET_LEGITIMIZE_ADDRESS spu_legitimize_address
336
337 /* The current assembler doesn't like .4byte foo@ppu, so use the normal .long
338 and .quad for the debugger. When it is known that the assembler is fixed,
339 these can be removed. */
340 #undef TARGET_ASM_UNALIGNED_SI_OP
341 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
342
343 #undef TARGET_ASM_ALIGNED_DI_OP
344 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
345
346 /* The .8byte directive doesn't seem to work well for a 32 bit
347 architecture. */
348 #undef TARGET_ASM_UNALIGNED_DI_OP
349 #define TARGET_ASM_UNALIGNED_DI_OP NULL
350
351 #undef TARGET_RTX_COSTS
352 #define TARGET_RTX_COSTS spu_rtx_costs
353
354 #undef TARGET_ADDRESS_COST
355 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
356
357 #undef TARGET_SCHED_ISSUE_RATE
358 #define TARGET_SCHED_ISSUE_RATE spu_sched_issue_rate
359
360 #undef TARGET_SCHED_INIT_GLOBAL
361 #define TARGET_SCHED_INIT_GLOBAL spu_sched_init_global
362
363 #undef TARGET_SCHED_INIT
364 #define TARGET_SCHED_INIT spu_sched_init
365
366 #undef TARGET_SCHED_VARIABLE_ISSUE
367 #define TARGET_SCHED_VARIABLE_ISSUE spu_sched_variable_issue
368
369 #undef TARGET_SCHED_REORDER
370 #define TARGET_SCHED_REORDER spu_sched_reorder
371
372 #undef TARGET_SCHED_REORDER2
373 #define TARGET_SCHED_REORDER2 spu_sched_reorder
374
375 #undef TARGET_SCHED_ADJUST_COST
376 #define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost
377
378 #undef TARGET_ATTRIBUTE_TABLE
379 #define TARGET_ATTRIBUTE_TABLE spu_attribute_table
380
381 #undef TARGET_ASM_INTEGER
382 #define TARGET_ASM_INTEGER spu_assemble_integer
383
384 #undef TARGET_SCALAR_MODE_SUPPORTED_P
385 #define TARGET_SCALAR_MODE_SUPPORTED_P spu_scalar_mode_supported_p
386
387 #undef TARGET_VECTOR_MODE_SUPPORTED_P
388 #define TARGET_VECTOR_MODE_SUPPORTED_P spu_vector_mode_supported_p
389
390 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
391 #define TARGET_FUNCTION_OK_FOR_SIBCALL spu_function_ok_for_sibcall
392
393 #undef TARGET_ASM_GLOBALIZE_LABEL
394 #define TARGET_ASM_GLOBALIZE_LABEL spu_asm_globalize_label
395
396 #undef TARGET_PASS_BY_REFERENCE
397 #define TARGET_PASS_BY_REFERENCE spu_pass_by_reference
398
399 #undef TARGET_FUNCTION_ARG
400 #define TARGET_FUNCTION_ARG spu_function_arg
401
402 #undef TARGET_FUNCTION_ARG_ADVANCE
403 #define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance
404
405 #undef TARGET_MUST_PASS_IN_STACK
406 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
407
408 #undef TARGET_BUILD_BUILTIN_VA_LIST
409 #define TARGET_BUILD_BUILTIN_VA_LIST spu_build_builtin_va_list
410
411 #undef TARGET_EXPAND_BUILTIN_VA_START
412 #define TARGET_EXPAND_BUILTIN_VA_START spu_va_start
413
414 #undef TARGET_SETUP_INCOMING_VARARGS
415 #define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs
416
417 #undef TARGET_MACHINE_DEPENDENT_REORG
418 #define TARGET_MACHINE_DEPENDENT_REORG spu_machine_dependent_reorg
419
420 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
421 #define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr
422
423 #undef TARGET_DEFAULT_TARGET_FLAGS
424 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT)
425
426 #undef TARGET_INIT_LIBFUNCS
427 #define TARGET_INIT_LIBFUNCS spu_init_libfuncs
428
429 #undef TARGET_RETURN_IN_MEMORY
430 #define TARGET_RETURN_IN_MEMORY spu_return_in_memory
431
432 #undef TARGET_ENCODE_SECTION_INFO
433 #define TARGET_ENCODE_SECTION_INFO spu_encode_section_info
434
435 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
436 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN spu_builtin_mul_widen_even
437
438 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
439 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD spu_builtin_mul_widen_odd
440
441 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
442 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD spu_builtin_mask_for_load
443
444 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
445 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST spu_builtin_vectorization_cost
446
447 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
448 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable
449
450 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
451 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM spu_builtin_vec_perm
452
453 #undef TARGET_LIBGCC_CMP_RETURN_MODE
454 #define TARGET_LIBGCC_CMP_RETURN_MODE spu_libgcc_cmp_return_mode
455
456 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
457 #define TARGET_LIBGCC_SHIFT_COUNT_MODE spu_libgcc_shift_count_mode
458
459 #undef TARGET_SCHED_SMS_RES_MII
460 #define TARGET_SCHED_SMS_RES_MII spu_sms_res_mii
461
462 #undef TARGET_ASM_FILE_START
463 #define TARGET_ASM_FILE_START asm_file_start
464
465 #undef TARGET_SECTION_TYPE_FLAGS
466 #define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags
467
468 #undef TARGET_ASM_SELECT_SECTION
469 #define TARGET_ASM_SELECT_SECTION spu_select_section
470
471 #undef TARGET_ASM_UNIQUE_SECTION
472 #define TARGET_ASM_UNIQUE_SECTION spu_unique_section
473
474 #undef TARGET_LEGITIMATE_ADDRESS_P
475 #define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p
476
477 #undef TARGET_TRAMPOLINE_INIT
478 #define TARGET_TRAMPOLINE_INIT spu_trampoline_init
479
480 #undef TARGET_OPTION_OVERRIDE
481 #define TARGET_OPTION_OVERRIDE spu_option_override
482
483 #undef TARGET_OPTION_INIT_STRUCT
484 #define TARGET_OPTION_INIT_STRUCT spu_option_init_struct
485
486 #undef TARGET_OPTION_DEFAULT_PARAMS
487 #define TARGET_OPTION_DEFAULT_PARAMS spu_option_default_params
488
489 #undef TARGET_EXCEPT_UNWIND_INFO
490 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
491
492 #undef TARGET_CONDITIONAL_REGISTER_USAGE
493 #define TARGET_CONDITIONAL_REGISTER_USAGE spu_conditional_register_usage
494
495 #undef TARGET_REF_MAY_ALIAS_ERRNO
496 #define TARGET_REF_MAY_ALIAS_ERRNO spu_ref_may_alias_errno
497
498 struct gcc_target targetm = TARGET_INITIALIZER;
499
500 static void
501 spu_option_init_struct (struct gcc_options *opts)
502 {
503 /* With so many registers this is better on by default. */
504 opts->x_flag_rename_registers = 1;
505 }
506
507 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
508 static void
509 spu_option_default_params (void)
510 {
511 /* Override some of the default param values. With so many registers
512 larger values are better for these params. */
513 set_default_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 128);
514 } 220 }
515 221
516 /* Implement TARGET_OPTION_OVERRIDE. */ 222 /* Implement TARGET_OPTION_OVERRIDE. */
517 static void 223 static void
518 spu_option_override (void) 224 spu_option_override (void)
519 { 225 {
226 /* Set up function hooks. */
227 init_machine_status = spu_init_machine_status;
228
520 /* Small loops will be unpeeled at -O3. For SPU it is more important 229 /* Small loops will be unpeeled at -O3. For SPU it is more important
521 to keep code small by default. */ 230 to keep code small by default. */
522 if (!flag_unroll_loops && !flag_peel_loops) 231 if (!flag_unroll_loops && !flag_peel_loops)
523 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 4, 232 maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 4,
524 global_options.x_param_values, 233 global_options.x_param_values,
570 } 279 }
571 280
572 REAL_MODE_FORMAT (SFmode) = &spu_single_format; 281 REAL_MODE_FORMAT (SFmode) = &spu_single_format;
573 } 282 }
574 283
284 /* Implement TARGET_HARD_REGNO_NREGS. */
285
286 static unsigned int
287 spu_hard_regno_nregs (unsigned int, machine_mode mode)
288 {
289 return CEIL (GET_MODE_BITSIZE (mode), MAX_FIXED_MODE_SIZE);
290 }
291
575 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in 292 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
576 struct attribute_spec.handler. */ 293 struct attribute_spec.handler. */
577 294
578 /* True if MODE is valid for the target. By "valid", we mean able to 295 /* True if MODE is valid for the target. By "valid", we mean able to
579 be manipulated in non-trivial ways. In particular, this means all 296 be manipulated in non-trivial ways. In particular, this means all
580 the arithmetic is supported. */ 297 the arithmetic is supported. */
581 static bool 298 static bool
582 spu_scalar_mode_supported_p (enum machine_mode mode) 299 spu_scalar_mode_supported_p (scalar_mode mode)
583 { 300 {
584 switch (mode) 301 switch (mode)
585 { 302 {
586 case QImode: 303 case E_QImode:
587 case HImode: 304 case E_HImode:
588 case SImode: 305 case E_SImode:
589 case SFmode: 306 case E_SFmode:
590 case DImode: 307 case E_DImode:
591 case TImode: 308 case E_TImode:
592 case DFmode: 309 case E_DFmode:
593 return true; 310 return true;
594 311
595 default: 312 default:
596 return false; 313 return false;
597 } 314 }
599 316
600 /* Similarly for vector modes. "Supported" here is less strict. At 317 /* Similarly for vector modes. "Supported" here is less strict. At
601 least some operations are supported; need to check optabs or builtins 318 least some operations are supported; need to check optabs or builtins
602 for further details. */ 319 for further details. */
603 static bool 320 static bool
604 spu_vector_mode_supported_p (enum machine_mode mode) 321 spu_vector_mode_supported_p (machine_mode mode)
605 { 322 {
606 switch (mode) 323 switch (mode)
607 { 324 {
608 case V16QImode: 325 case E_V16QImode:
609 case V8HImode: 326 case E_V8HImode:
610 case V4SImode: 327 case E_V4SImode:
611 case V2DImode: 328 case E_V2DImode:
612 case V4SFmode: 329 case E_V4SFmode:
613 case V2DFmode: 330 case E_V2DFmode:
614 return true; 331 return true;
615 332
616 default: 333 default:
617 return false; 334 return false;
618 } 335 }
622 least significant bytes of the outer mode. This function returns 339 least significant bytes of the outer mode. This function returns
623 TRUE for the SUBREG's where this is correct. */ 340 TRUE for the SUBREG's where this is correct. */
624 int 341 int
625 valid_subreg (rtx op) 342 valid_subreg (rtx op)
626 { 343 {
627 enum machine_mode om = GET_MODE (op); 344 machine_mode om = GET_MODE (op);
628 enum machine_mode im = GET_MODE (SUBREG_REG (op)); 345 machine_mode im = GET_MODE (SUBREG_REG (op));
629 return om != VOIDmode && im != VOIDmode 346 return om != VOIDmode && im != VOIDmode
630 && (GET_MODE_SIZE (im) == GET_MODE_SIZE (om) 347 && (GET_MODE_SIZE (im) == GET_MODE_SIZE (om)
631 || (GET_MODE_SIZE (im) <= 4 && GET_MODE_SIZE (om) <= 4) 348 || (GET_MODE_SIZE (im) <= 4 && GET_MODE_SIZE (om) <= 4)
632 || (GET_MODE_SIZE (im) >= 16 && GET_MODE_SIZE (om) >= 16)); 349 || (GET_MODE_SIZE (im) >= 16 && GET_MODE_SIZE (om) >= 16));
633 } 350 }
635 /* When insv and ext[sz]v ar passed a TI SUBREG, we want to strip it off 352 /* When insv and ext[sz]v ar passed a TI SUBREG, we want to strip it off
636 and adjust the start offset. */ 353 and adjust the start offset. */
637 static rtx 354 static rtx
638 adjust_operand (rtx op, HOST_WIDE_INT * start) 355 adjust_operand (rtx op, HOST_WIDE_INT * start)
639 { 356 {
640 enum machine_mode mode; 357 machine_mode mode;
641 int op_size; 358 int op_size;
642 /* Strip any paradoxical SUBREG. */ 359 /* Strip any paradoxical SUBREG. */
643 if (GET_CODE (op) == SUBREG 360 if (GET_CODE (op) == SUBREG
644 && (GET_MODE_BITSIZE (GET_MODE (op)) 361 && (GET_MODE_BITSIZE (GET_MODE (op))
645 > GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op))))) 362 > GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op)))))
657 if (start) 374 if (start)
658 *start += 32 - op_size; 375 *start += 32 - op_size;
659 op_size = 32; 376 op_size = 32;
660 } 377 }
661 /* If it is not a MODE_INT (and/or it is smaller than SI) add a SUBREG. */ 378 /* If it is not a MODE_INT (and/or it is smaller than SI) add a SUBREG. */
662 mode = mode_for_size (op_size, MODE_INT, 0); 379 mode = int_mode_for_size (op_size, 0).require ();
663 if (mode != GET_MODE (op)) 380 if (mode != GET_MODE (op))
664 op = gen_rtx_SUBREG (mode, op, 0); 381 op = gen_rtx_SUBREG (mode, op, 0);
665 return op; 382 return op;
666 } 383 }
667 384
722 { 439 {
723 rtx r = SUBREG_REG (src); 440 rtx r = SUBREG_REG (src);
724 gcc_assert (REG_P (r) && SCALAR_INT_MODE_P (GET_MODE (r))); 441 gcc_assert (REG_P (r) && SCALAR_INT_MODE_P (GET_MODE (r)));
725 s0 = gen_reg_rtx (TImode); 442 s0 = gen_reg_rtx (TImode);
726 if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode)) 443 if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode))
727 emit_insn (gen_rtx_SET (VOIDmode, s0, gen_rtx_ZERO_EXTEND (TImode, r))); 444 emit_insn (gen_rtx_SET (s0, gen_rtx_ZERO_EXTEND (TImode, r)));
728 else 445 else
729 emit_move_insn (s0, src); 446 emit_move_insn (s0, src);
730 } 447 }
731 else 448 else
732 { 449 {
739 456
740 if (start) 457 if (start)
741 emit_insn (gen_rotlti3 (s0, s0, GEN_INT (start))); 458 emit_insn (gen_rotlti3 (s0, s0, GEN_INT (start)));
742 459
743 if (128 - width) 460 if (128 - width)
744 { 461 s0 = expand_shift (RSHIFT_EXPR, TImode, s0, 128 - width, s0, unsignedp);
745 tree c = build_int_cst (NULL_TREE, 128 - width);
746 s0 = expand_shift (RSHIFT_EXPR, TImode, s0, c, s0, unsignedp);
747 }
748 462
749 emit_move_insn (dst, s0); 463 emit_move_insn (dst, s0);
750 } 464 }
751 465
752 void 466 void
753 spu_expand_insv (rtx ops[]) 467 spu_expand_insv (rtx ops[])
754 { 468 {
755 HOST_WIDE_INT width = INTVAL (ops[1]); 469 HOST_WIDE_INT width = INTVAL (ops[1]);
756 HOST_WIDE_INT start = INTVAL (ops[2]); 470 HOST_WIDE_INT start = INTVAL (ops[2]);
757 HOST_WIDE_INT maskbits; 471 unsigned HOST_WIDE_INT maskbits;
758 enum machine_mode dst_mode; 472 machine_mode dst_mode;
759 rtx dst = ops[0], src = ops[3]; 473 rtx dst = ops[0], src = ops[3];
760 int dst_size; 474 int dst_size;
761 rtx mask; 475 rtx mask;
762 rtx shift_reg; 476 rtx shift_reg;
763 int shift; 477 int shift;
770 dst_mode = GET_MODE (dst); 484 dst_mode = GET_MODE (dst);
771 dst_size = GET_MODE_BITSIZE (GET_MODE (dst)); 485 dst_size = GET_MODE_BITSIZE (GET_MODE (dst));
772 486
773 if (CONSTANT_P (src)) 487 if (CONSTANT_P (src))
774 { 488 {
775 enum machine_mode m = 489 machine_mode m =
776 (width <= 32 ? SImode : width <= 64 ? DImode : TImode); 490 (width <= 32 ? SImode : width <= 64 ? DImode : TImode);
777 src = force_reg (m, convert_to_mode (m, src, 0)); 491 src = force_reg (m, convert_to_mode (m, src, 0));
778 } 492 }
779 src = adjust_operand (src, 0); 493 src = adjust_operand (src, 0);
780 494
788 502
789 if (shift > 0) 503 if (shift > 0)
790 { 504 {
791 switch (dst_mode) 505 switch (dst_mode)
792 { 506 {
793 case SImode: 507 case E_SImode:
794 emit_insn (gen_ashlsi3 (shift_reg, shift_reg, GEN_INT (shift))); 508 emit_insn (gen_ashlsi3 (shift_reg, shift_reg, GEN_INT (shift)));
795 break; 509 break;
796 case DImode: 510 case E_DImode:
797 emit_insn (gen_ashldi3 (shift_reg, shift_reg, GEN_INT (shift))); 511 emit_insn (gen_ashldi3 (shift_reg, shift_reg, GEN_INT (shift)));
798 break; 512 break;
799 case TImode: 513 case E_TImode:
800 emit_insn (gen_ashlti3 (shift_reg, shift_reg, GEN_INT (shift))); 514 emit_insn (gen_ashlti3 (shift_reg, shift_reg, GEN_INT (shift)));
801 break; 515 break;
802 default: 516 default:
803 abort (); 517 abort ();
804 } 518 }
807 abort (); 521 abort ();
808 522
809 switch (dst_size) 523 switch (dst_size)
810 { 524 {
811 case 32: 525 case 32:
812 maskbits = (-1ll << (32 - width - start)); 526 maskbits = (~(unsigned HOST_WIDE_INT)0 << (32 - width - start));
813 if (start) 527 if (start)
814 maskbits += (1ll << (32 - start)); 528 maskbits += ((unsigned HOST_WIDE_INT)1 << (32 - start));
815 emit_move_insn (mask, GEN_INT (maskbits)); 529 emit_move_insn (mask, GEN_INT (maskbits));
816 break; 530 break;
817 case 64: 531 case 64:
818 maskbits = (-1ll << (64 - width - start)); 532 maskbits = (~(unsigned HOST_WIDE_INT)0 << (64 - width - start));
819 if (start) 533 if (start)
820 maskbits += (1ll << (64 - start)); 534 maskbits += ((unsigned HOST_WIDE_INT)1 << (64 - start));
821 emit_move_insn (mask, GEN_INT (maskbits)); 535 emit_move_insn (mask, GEN_INT (maskbits));
822 break; 536 break;
823 case 128: 537 case 128:
824 { 538 {
825 unsigned char arr[16]; 539 unsigned char arr[16];
859 { 573 {
860 rtx shl = gen_reg_rtx (SImode); 574 rtx shl = gen_reg_rtx (SImode);
861 rtx mask1 = gen_reg_rtx (TImode); 575 rtx mask1 = gen_reg_rtx (TImode);
862 rtx dst1 = gen_reg_rtx (TImode); 576 rtx dst1 = gen_reg_rtx (TImode);
863 rtx mem1; 577 rtx mem1;
864 addr1 = plus_constant (addr, 16); 578 addr1 = plus_constant (Pmode, addr, 16);
865 addr1 = gen_rtx_AND (Pmode, addr1, GEN_INT (-16)); 579 addr1 = gen_rtx_AND (Pmode, addr1, GEN_INT (-16));
866 emit_insn (gen_subsi3 (shl, GEN_INT (16), low)); 580 emit_insn (gen_subsi3 (shl, GEN_INT (16), low));
867 emit_insn (gen_shlqby_ti (mask1, mask, shl)); 581 emit_insn (gen_shlqby_ti (mask1, mask, shl));
868 mem1 = change_address (ops[0], TImode, addr1); 582 mem1 = change_address (ops[0], TImode, addr1);
869 set_mem_alias_set (mem1, 0); 583 set_mem_alias_set (mem1, 0);
957 { 671 {
958 int reverse_compare = 0; 672 int reverse_compare = 0;
959 int reverse_test = 0; 673 int reverse_test = 0;
960 rtx compare_result, eq_result; 674 rtx compare_result, eq_result;
961 rtx comp_rtx, eq_rtx; 675 rtx comp_rtx, eq_rtx;
962 enum machine_mode comp_mode; 676 machine_mode comp_mode;
963 enum machine_mode op_mode; 677 machine_mode op_mode;
964 enum spu_comp_code scode, eq_code; 678 enum spu_comp_code scode, eq_code;
965 enum insn_code ior_code; 679 enum insn_code ior_code;
966 enum rtx_code code = GET_CODE (cmp); 680 enum rtx_code code = GET_CODE (cmp);
967 rtx op0 = XEXP (cmp, 0); 681 rtx op0 = XEXP (cmp, 0);
968 rtx op1 = XEXP (cmp, 1); 682 rtx op1 = XEXP (cmp, 1);
990 code = GTU; 704 code = GTU;
991 break; 705 break;
992 case LTU: 706 case LTU:
993 op1 = GEN_INT (val); 707 op1 = GEN_INT (val);
994 code = LEU; 708 code = LEU;
709 break;
710 default:
711 break;
712 }
713 }
714
715 /* However, if we generate an integer result, performing a reverse test
716 would require an extra negation, so avoid that where possible. */
717 if (GET_CODE (op1) == CONST_INT && is_set == 1)
718 {
719 HOST_WIDE_INT val = INTVAL (op1) + 1;
720 if (trunc_int_for_mode (val, GET_MODE (op0)) == val)
721 switch (code)
722 {
723 case LE:
724 op1 = GEN_INT (val);
725 code = LT;
726 break;
727 case LEU:
728 op1 = GEN_INT (val);
729 code = LTU;
995 break; 730 break;
996 default: 731 default:
997 break; 732 break;
998 } 733 }
999 } 734 }
1073 break; 808 break;
1074 } 809 }
1075 810
1076 switch (op_mode) 811 switch (op_mode)
1077 { 812 {
1078 case QImode: 813 case E_QImode:
1079 index = 0; 814 index = 0;
1080 comp_mode = QImode; 815 comp_mode = QImode;
1081 break; 816 break;
1082 case HImode: 817 case E_HImode:
1083 index = 1; 818 index = 1;
1084 comp_mode = HImode; 819 comp_mode = HImode;
1085 break; 820 break;
1086 case SImode: 821 case E_SImode:
1087 index = 2; 822 index = 2;
1088 break; 823 break;
1089 case DImode: 824 case E_DImode:
1090 index = 3; 825 index = 3;
1091 break; 826 break;
1092 case TImode: 827 case E_TImode:
1093 index = 4; 828 index = 4;
1094 break; 829 break;
1095 case SFmode: 830 case E_SFmode:
1096 index = 5; 831 index = 5;
1097 break; 832 break;
1098 case DFmode: 833 case E_DFmode:
1099 index = 6; 834 index = 6;
1100 break; 835 break;
1101 case V16QImode: 836 case E_V16QImode:
1102 index = 7; 837 index = 7;
1103 comp_mode = op_mode; 838 comp_mode = op_mode;
1104 break; 839 break;
1105 case V8HImode: 840 case E_V8HImode:
1106 index = 8; 841 index = 8;
1107 comp_mode = op_mode; 842 comp_mode = op_mode;
1108 break; 843 break;
1109 case V4SImode: 844 case E_V4SImode:
1110 index = 9; 845 index = 9;
1111 comp_mode = op_mode; 846 comp_mode = op_mode;
1112 break; 847 break;
1113 case V4SFmode: 848 case E_V4SFmode:
1114 index = 10; 849 index = 10;
1115 comp_mode = V4SImode; 850 comp_mode = V4SImode;
1116 break; 851 break;
1117 case V2DFmode: 852 case E_V2DFmode:
1118 index = 11; 853 index = 11;
1119 comp_mode = V2DImode; 854 comp_mode = V2DImode;
1120 break; 855 break;
1121 case V2DImode: 856 case E_V2DImode:
1122 default: 857 default:
1123 abort (); 858 abort ();
1124 } 859 }
1125 860
1126 if (GET_MODE (op1) == DFmode 861 if (GET_MODE (op1) == DFmode
1127 && (scode != SPU_GT && scode != SPU_EQ)) 862 && (scode != SPU_GT && scode != SPU_EQ))
1128 abort (); 863 abort ();
1129 864
1130 if (is_set == 0 && op1 == const0_rtx 865 if (is_set == 0 && op1 == const0_rtx
1131 && (GET_MODE (op0) == SImode 866 && (GET_MODE (op0) == SImode
1132 || GET_MODE (op0) == HImode) && scode == SPU_EQ) 867 || GET_MODE (op0) == HImode
868 || GET_MODE (op0) == QImode) && scode == SPU_EQ)
1133 { 869 {
1134 /* Don't need to set a register with the result when we are 870 /* Don't need to set a register with the result when we are
1135 comparing against zero and branching. */ 871 comparing against zero and branching. */
1136 reverse_test = !reverse_test; 872 reverse_test = !reverse_test;
1137 compare_result = op0; 873 compare_result = op0;
1196 bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx); 932 bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx);
1197 else 933 else
1198 bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx); 934 bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx);
1199 935
1200 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]); 936 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1201 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 937 emit_jump_insn (gen_rtx_SET (pc_rtx,
1202 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, 938 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1203 loc_ref, pc_rtx))); 939 loc_ref, pc_rtx)));
1204 } 940 }
1205 else if (is_set == 2) 941 else if (is_set == 2)
1206 { 942 {
1207 rtx target = operands[0]; 943 rtx target = operands[0];
1208 int compare_size = GET_MODE_BITSIZE (comp_mode); 944 int compare_size = GET_MODE_BITSIZE (comp_mode);
1209 int target_size = GET_MODE_BITSIZE (GET_MODE (target)); 945 int target_size = GET_MODE_BITSIZE (GET_MODE (target));
1210 enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0); 946 machine_mode mode = int_mode_for_size (target_size, 0).require ();
1211 rtx select_mask; 947 rtx select_mask;
1212 rtx op_t = operands[2]; 948 rtx op_t = operands[2];
1213 rtx op_f = operands[3]; 949 rtx op_f = operands[3];
1214 950
1215 /* The result of the comparison can be SI, HI or QI mode. Create a 951 /* The result of the comparison can be SI, HI or QI mode. Create a
1239 } 975 }
1240 else 976 else
1241 { 977 {
1242 rtx target = operands[0]; 978 rtx target = operands[0];
1243 if (reverse_test) 979 if (reverse_test)
1244 emit_insn (gen_rtx_SET (VOIDmode, compare_result, 980 emit_insn (gen_rtx_SET (compare_result,
1245 gen_rtx_NOT (comp_mode, compare_result))); 981 gen_rtx_NOT (comp_mode, compare_result)));
1246 if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode) 982 if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode)
1247 emit_insn (gen_extendhisi2 (target, compare_result)); 983 emit_insn (gen_extendhisi2 (target, compare_result));
1248 else if (GET_MODE (target) == SImode 984 else if (GET_MODE (target) == SImode
1249 && GET_MODE (compare_result) == QImode) 985 && GET_MODE (compare_result) == QImode)
1255 991
1256 HOST_WIDE_INT 992 HOST_WIDE_INT
1257 const_double_to_hwint (rtx x) 993 const_double_to_hwint (rtx x)
1258 { 994 {
1259 HOST_WIDE_INT val; 995 HOST_WIDE_INT val;
1260 REAL_VALUE_TYPE rv;
1261 if (GET_MODE (x) == SFmode) 996 if (GET_MODE (x) == SFmode)
1262 { 997 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
1263 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1264 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1265 }
1266 else if (GET_MODE (x) == DFmode) 998 else if (GET_MODE (x) == DFmode)
1267 { 999 {
1268 long l[2]; 1000 long l[2];
1269 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); 1001 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
1270 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1271 val = l[0]; 1002 val = l[0];
1272 val = (val << 32) | (l[1] & 0xffffffff); 1003 val = (val << 32) | (l[1] & 0xffffffff);
1273 } 1004 }
1274 else 1005 else
1275 abort (); 1006 abort ();
1276 return val; 1007 return val;
1277 } 1008 }
1278 1009
1279 rtx 1010 rtx
1280 hwint_to_const_double (enum machine_mode mode, HOST_WIDE_INT v) 1011 hwint_to_const_double (machine_mode mode, HOST_WIDE_INT v)
1281 { 1012 {
1282 long tv[2]; 1013 long tv[2];
1283 REAL_VALUE_TYPE rv; 1014 REAL_VALUE_TYPE rv;
1284 gcc_assert (mode == SFmode || mode == DFmode); 1015 gcc_assert (mode == SFmode || mode == DFmode);
1285 1016
1289 { 1020 {
1290 tv[1] = (v << 32) >> 32; 1021 tv[1] = (v << 32) >> 32;
1291 tv[0] = v >> 32; 1022 tv[0] = v >> 32;
1292 } 1023 }
1293 real_from_target (&rv, tv, mode); 1024 real_from_target (&rv, tv, mode);
1294 return CONST_DOUBLE_FROM_REAL_VALUE (rv, mode); 1025 return const_double_from_real_value (rv, mode);
1295 } 1026 }
1296 1027
1297 void 1028 void
1298 print_operand_address (FILE * file, register rtx addr) 1029 print_operand_address (FILE * file, register rtx addr)
1299 { 1030 {
1342 } 1073 }
1343 1074
1344 void 1075 void
1345 print_operand (FILE * file, rtx x, int code) 1076 print_operand (FILE * file, rtx x, int code)
1346 { 1077 {
1347 enum machine_mode mode = GET_MODE (x); 1078 machine_mode mode = GET_MODE (x);
1348 HOST_WIDE_INT val; 1079 HOST_WIDE_INT val;
1349 unsigned char arr[16]; 1080 unsigned char arr[16];
1350 int xcode = GET_CODE (x); 1081 int xcode = GET_CODE (x);
1351 int i, info; 1082 int i, info;
1352 if (GET_MODE (x) == VOIDmode) 1083 if (GET_MODE (x) == VOIDmode)
1616 { 1347 {
1617 if (GET_CODE (XEXP (x, 0)) == REG) 1348 if (GET_CODE (XEXP (x, 0)) == REG)
1618 /* Used in indirect function calls. */ 1349 /* Used in indirect function calls. */
1619 fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]); 1350 fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]);
1620 else 1351 else
1621 output_address (XEXP (x, 0)); 1352 output_address (GET_MODE (x), XEXP (x, 0));
1622 } 1353 }
1623 return; 1354 return;
1624 1355
1625 case 'p': /* load/store */ 1356 case 'p': /* load/store */
1626 if (xcode == MEM) 1357 if (xcode == MEM)
1709 1440
1710 case 0: 1441 case 0:
1711 if (xcode == REG) 1442 if (xcode == REG)
1712 fprintf (file, "%s", reg_names[REGNO (x)]); 1443 fprintf (file, "%s", reg_names[REGNO (x)]);
1713 else if (xcode == MEM) 1444 else if (xcode == MEM)
1714 output_address (XEXP (x, 0)); 1445 output_address (GET_MODE (x), XEXP (x, 0));
1715 else if (xcode == CONST_VECTOR) 1446 else if (xcode == CONST_VECTOR)
1716 print_operand (file, CONST_VECTOR_ELT (x, 0), 0); 1447 print_operand (file, CONST_VECTOR_ELT (x, 0), 0);
1717 else 1448 else
1718 output_addr_const (file, x); 1449 output_addr_const (file, x);
1719 return; 1450 return;
1733 pic register. This routine is only valid after register allocation 1464 pic register. This routine is only valid after register allocation
1734 is completed, so we can pick an unused register. */ 1465 is completed, so we can pick an unused register. */
1735 static rtx 1466 static rtx
1736 get_pic_reg (void) 1467 get_pic_reg (void)
1737 { 1468 {
1738 rtx pic_reg = pic_offset_table_rtx;
1739 if (!reload_completed && !reload_in_progress) 1469 if (!reload_completed && !reload_in_progress)
1740 abort (); 1470 abort ();
1741 if (current_function_is_leaf && !df_regs_ever_live_p (LAST_ARG_REGNUM)) 1471
1742 pic_reg = gen_rtx_REG (SImode, LAST_ARG_REGNUM); 1472 /* If we've already made the decision, we need to keep with it. Once we've
1743 return pic_reg; 1473 decided to use LAST_ARG_REGNUM, future calls to df_regs_ever_live_p may
1474 return true since the register is now live; this should not cause us to
1475 "switch back" to using pic_offset_table_rtx. */
1476 if (!cfun->machine->pic_reg)
1477 {
1478 if (crtl->is_leaf && !df_regs_ever_live_p (LAST_ARG_REGNUM))
1479 cfun->machine->pic_reg = gen_rtx_REG (SImode, LAST_ARG_REGNUM);
1480 else
1481 cfun->machine->pic_reg = pic_offset_table_rtx;
1482 }
1483
1484 return cfun->machine->pic_reg;
1744 } 1485 }
1745 1486
1746 /* Split constant addresses to handle cases that are too large. 1487 /* Split constant addresses to handle cases that are too large.
1747 Add in the pic register when in PIC mode. 1488 Add in the pic register when in PIC mode.
1748 Split immediates that require more than 1 instruction. */ 1489 Split immediates that require more than 1 instruction. */
1749 int 1490 int
1750 spu_split_immediate (rtx * ops) 1491 spu_split_immediate (rtx * ops)
1751 { 1492 {
1752 enum machine_mode mode = GET_MODE (ops[0]); 1493 machine_mode mode = GET_MODE (ops[0]);
1753 enum immediate_class c = classify_immediate (ops[1], mode); 1494 enum immediate_class c = classify_immediate (ops[1], mode);
1754 1495
1755 switch (c) 1496 switch (c)
1756 { 1497 {
1757 case IC_IL2: 1498 case IC_IL2:
1758 { 1499 {
1759 unsigned char arrhi[16]; 1500 unsigned char arrhi[16];
1760 unsigned char arrlo[16]; 1501 unsigned char arrlo[16];
1761 rtx to, temp, hi, lo; 1502 rtx to, temp, hi, lo;
1762 int i; 1503 int i;
1763 enum machine_mode imode = mode;
1764 /* We need to do reals as ints because the constant used in the 1504 /* We need to do reals as ints because the constant used in the
1765 IOR might not be a legitimate real constant. */ 1505 IOR might not be a legitimate real constant. */
1766 imode = int_mode_for_mode (mode); 1506 scalar_int_mode imode = int_mode_for_mode (mode).require ();
1767 constant_to_array (mode, ops[1], arrhi); 1507 constant_to_array (mode, ops[1], arrhi);
1768 if (imode != mode) 1508 if (imode != mode)
1769 to = simplify_gen_subreg (imode, ops[0], mode, 0); 1509 to = simplify_gen_subreg (imode, ops[0], mode, 0);
1770 else 1510 else
1771 to = ops[0]; 1511 to = ops[0];
1778 arrhi[i + 2] = arrhi[i + 3] = 0; 1518 arrhi[i + 2] = arrhi[i + 3] = 0;
1779 } 1519 }
1780 hi = array_to_constant (imode, arrhi); 1520 hi = array_to_constant (imode, arrhi);
1781 lo = array_to_constant (imode, arrlo); 1521 lo = array_to_constant (imode, arrlo);
1782 emit_move_insn (temp, hi); 1522 emit_move_insn (temp, hi);
1783 emit_insn (gen_rtx_SET 1523 emit_insn (gen_rtx_SET (to, gen_rtx_IOR (imode, temp, lo)));
1784 (VOIDmode, to, gen_rtx_IOR (imode, temp, lo)));
1785 return 1; 1524 return 1;
1786 } 1525 }
1787 case IC_FSMBI2: 1526 case IC_FSMBI2:
1788 { 1527 {
1789 unsigned char arr_fsmbi[16]; 1528 unsigned char arr_fsmbi[16];
1790 unsigned char arr_andbi[16]; 1529 unsigned char arr_andbi[16];
1791 rtx to, reg_fsmbi, reg_and; 1530 rtx to, reg_fsmbi, reg_and;
1792 int i; 1531 int i;
1793 enum machine_mode imode = mode;
1794 /* We need to do reals as ints because the constant used in the 1532 /* We need to do reals as ints because the constant used in the
1795 * AND might not be a legitimate real constant. */ 1533 * AND might not be a legitimate real constant. */
1796 imode = int_mode_for_mode (mode); 1534 scalar_int_mode imode = int_mode_for_mode (mode).require ();
1797 constant_to_array (mode, ops[1], arr_fsmbi); 1535 constant_to_array (mode, ops[1], arr_fsmbi);
1798 if (imode != mode) 1536 if (imode != mode)
1799 to = simplify_gen_subreg(imode, ops[0], GET_MODE (ops[0]), 0); 1537 to = simplify_gen_subreg(imode, ops[0], GET_MODE (ops[0]), 0);
1800 else 1538 else
1801 to = ops[0]; 1539 to = ops[0];
1808 for (i = 1; i < 16; i++) 1546 for (i = 1; i < 16; i++)
1809 arr_andbi[i] = arr_andbi[0]; 1547 arr_andbi[i] = arr_andbi[0];
1810 reg_fsmbi = array_to_constant (imode, arr_fsmbi); 1548 reg_fsmbi = array_to_constant (imode, arr_fsmbi);
1811 reg_and = array_to_constant (imode, arr_andbi); 1549 reg_and = array_to_constant (imode, arr_andbi);
1812 emit_move_insn (to, reg_fsmbi); 1550 emit_move_insn (to, reg_fsmbi);
1813 emit_insn (gen_rtx_SET 1551 emit_insn (gen_rtx_SET (to, gen_rtx_AND (imode, to, reg_and)));
1814 (VOIDmode, to, gen_rtx_AND (imode, to, reg_and)));
1815 return 1; 1552 return 1;
1816 } 1553 }
1817 case IC_POOL: 1554 case IC_POOL:
1818 if (reload_in_progress || reload_completed) 1555 if (reload_in_progress || reload_completed)
1819 { 1556 {
1841 emit_insn (gen_pic (ops[0], ops[1])); 1578 emit_insn (gen_pic (ops[0], ops[1]));
1842 if (flag_pic) 1579 if (flag_pic)
1843 { 1580 {
1844 rtx pic_reg = get_pic_reg (); 1581 rtx pic_reg = get_pic_reg ();
1845 emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg)); 1582 emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
1846 crtl->uses_pic_offset_table = 1;
1847 } 1583 }
1848 return flag_pic || c == IC_IL2s; 1584 return flag_pic || c == IC_IL2s;
1849 } 1585 }
1850 break; 1586 break;
1851 case IC_IL1: 1587 case IC_IL1:
1867 { 1603 {
1868 if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) 1604 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
1869 return 1; 1605 return 1;
1870 if (flag_pic 1606 if (flag_pic
1871 && regno == PIC_OFFSET_TABLE_REGNUM 1607 && regno == PIC_OFFSET_TABLE_REGNUM
1872 && (!saving || crtl->uses_pic_offset_table) 1608 && (!saving || cfun->machine->pic_reg == pic_offset_table_rtx))
1873 && (!saving
1874 || !current_function_is_leaf || df_regs_ever_live_p (LAST_ARG_REGNUM)))
1875 return 1; 1609 return 1;
1876 return 0; 1610 return 0;
1877 } 1611 }
1878 1612
1879 /* This function is only correct starting with local register 1613 /* This function is only correct starting with local register
1888 if (need_to_save_reg (regno, 0)) 1622 if (need_to_save_reg (regno, 0))
1889 reg_save_size += 0x10; 1623 reg_save_size += 0x10;
1890 return reg_save_size; 1624 return reg_save_size;
1891 } 1625 }
1892 1626
1893 static rtx 1627 static rtx_insn *
1894 frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset) 1628 frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset)
1895 { 1629 {
1896 rtx reg = gen_rtx_REG (V4SImode, regno); 1630 rtx reg = gen_rtx_REG (V4SImode, regno);
1897 rtx mem = 1631 rtx mem =
1898 gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset))); 1632 gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset)));
1899 return emit_insn (gen_movv4si (mem, reg)); 1633 return emit_insn (gen_movv4si (mem, reg));
1900 } 1634 }
1901 1635
1902 static rtx 1636 static rtx_insn *
1903 frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset) 1637 frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset)
1904 { 1638 {
1905 rtx reg = gen_rtx_REG (V4SImode, regno); 1639 rtx reg = gen_rtx_REG (V4SImode, regno);
1906 rtx mem = 1640 rtx mem =
1907 gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset))); 1641 gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset)));
1908 return emit_insn (gen_movv4si (reg, mem)); 1642 return emit_insn (gen_movv4si (reg, mem));
1909 } 1643 }
1910 1644
1911 /* This happens after reload, so we need to expand it. */ 1645 /* This happens after reload, so we need to expand it. */
1912 static rtx 1646 static rtx_insn *
1913 frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm, rtx scratch) 1647 frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm, rtx scratch)
1914 { 1648 {
1915 rtx insn; 1649 rtx_insn *insn;
1916 if (satisfies_constraint_K (GEN_INT (imm))) 1650 if (satisfies_constraint_K (GEN_INT (imm)))
1917 { 1651 {
1918 insn = emit_insn (gen_addsi3 (dst, src, GEN_INT (imm))); 1652 insn = emit_insn (gen_addsi3 (dst, src, GEN_INT (imm)));
1919 } 1653 }
1920 else 1654 else
1937 if (cfun->static_chain_decl == 0 1671 if (cfun->static_chain_decl == 0
1938 && (spu_saved_regs_size () 1672 && (spu_saved_regs_size ()
1939 + get_frame_size () 1673 + get_frame_size ()
1940 + crtl->outgoing_args_size 1674 + crtl->outgoing_args_size
1941 + crtl->args.pretend_args_size == 0) 1675 + crtl->args.pretend_args_size == 0)
1942 && current_function_is_leaf) 1676 && crtl->is_leaf)
1943 return 1; 1677 return 1;
1944 } 1678 }
1945 return 0; 1679 return 0;
1946 } 1680 }
1947 1681
1981 HOST_WIDE_INT size = get_frame_size (), offset, regno; 1715 HOST_WIDE_INT size = get_frame_size (), offset, regno;
1982 HOST_WIDE_INT total_size; 1716 HOST_WIDE_INT total_size;
1983 HOST_WIDE_INT saved_regs_size; 1717 HOST_WIDE_INT saved_regs_size;
1984 rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); 1718 rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
1985 rtx scratch_reg_0, scratch_reg_1; 1719 rtx scratch_reg_0, scratch_reg_1;
1986 rtx insn, real; 1720 rtx_insn *insn;
1987 1721 rtx real;
1988 if (flag_pic && optimize == 0) 1722
1989 crtl->uses_pic_offset_table = 1; 1723 if (flag_pic && optimize == 0 && !cfun->machine->pic_reg)
1724 cfun->machine->pic_reg = pic_offset_table_rtx;
1990 1725
1991 if (spu_naked_function_p (current_function_decl)) 1726 if (spu_naked_function_p (current_function_decl))
1992 return; 1727 return;
1993 1728
1994 scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1); 1729 scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1);
1997 saved_regs_size = spu_saved_regs_size (); 1732 saved_regs_size = spu_saved_regs_size ();
1998 total_size = size + saved_regs_size 1733 total_size = size + saved_regs_size
1999 + crtl->outgoing_args_size 1734 + crtl->outgoing_args_size
2000 + crtl->args.pretend_args_size; 1735 + crtl->args.pretend_args_size;
2001 1736
2002 if (!current_function_is_leaf 1737 if (!crtl->is_leaf
2003 || cfun->calls_alloca || total_size > 0) 1738 || cfun->calls_alloca || total_size > 0)
2004 total_size += STACK_POINTER_OFFSET; 1739 total_size += STACK_POINTER_OFFSET;
2005 1740
2006 /* Save this first because code after this might use the link 1741 /* Save this first because code after this might use the link
2007 register as a scratch register. */ 1742 register as a scratch register. */
2008 if (!current_function_is_leaf) 1743 if (!crtl->is_leaf)
2009 { 1744 {
2010 insn = frame_emit_store (LINK_REGISTER_REGNUM, sp_reg, 16); 1745 insn = frame_emit_store (LINK_REGISTER_REGNUM, sp_reg, 16);
2011 RTX_FRAME_RELATED_P (insn) = 1; 1746 RTX_FRAME_RELATED_P (insn) = 1;
2012 } 1747 }
2013 1748
2021 insn = frame_emit_store (regno, sp_reg, offset); 1756 insn = frame_emit_store (regno, sp_reg, offset);
2022 RTX_FRAME_RELATED_P (insn) = 1; 1757 RTX_FRAME_RELATED_P (insn) = 1;
2023 } 1758 }
2024 } 1759 }
2025 1760
2026 if (flag_pic && crtl->uses_pic_offset_table) 1761 if (flag_pic && cfun->machine->pic_reg)
2027 { 1762 {
2028 rtx pic_reg = get_pic_reg (); 1763 rtx pic_reg = cfun->machine->pic_reg;
2029 insn = emit_insn (gen_load_pic_offset (pic_reg, scratch_reg_0)); 1764 insn = emit_insn (gen_load_pic_offset (pic_reg, scratch_reg_0));
2030 insn = emit_insn (gen_subsi3 (pic_reg, pic_reg, scratch_reg_0)); 1765 insn = emit_insn (gen_subsi3 (pic_reg, pic_reg, scratch_reg_0));
2031 } 1766 }
2032 1767
2033 if (total_size > 0) 1768 if (total_size > 0)
2034 { 1769 {
2035 if (flag_stack_check) 1770 if (flag_stack_check || flag_stack_clash_protection)
2036 { 1771 {
2037 /* We compare against total_size-1 because 1772 /* We compare against total_size-1 because
2038 ($sp >= total_size) <=> ($sp > total_size-1) */ 1773 ($sp >= total_size) <=> ($sp > total_size-1) */
2039 rtx scratch_v4si = gen_rtx_REG (V4SImode, REGNO (scratch_reg_0)); 1774 rtx scratch_v4si = gen_rtx_REG (V4SImode, REGNO (scratch_reg_0));
2040 rtx sp_v4si = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM); 1775 rtx sp_v4si = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM);
2043 { 1778 {
2044 emit_move_insn (scratch_v4si, size_v4si); 1779 emit_move_insn (scratch_v4si, size_v4si);
2045 size_v4si = scratch_v4si; 1780 size_v4si = scratch_v4si;
2046 } 1781 }
2047 emit_insn (gen_cgt_v4si (scratch_v4si, sp_v4si, size_v4si)); 1782 emit_insn (gen_cgt_v4si (scratch_v4si, sp_v4si, size_v4si));
2048 emit_insn (gen_vec_extractv4si 1783 emit_insn (gen_vec_extractv4sisi
2049 (scratch_reg_0, scratch_v4si, GEN_INT (1))); 1784 (scratch_reg_0, scratch_v4si, GEN_INT (1)));
2050 emit_insn (gen_spu_heq (scratch_reg_0, GEN_INT (0))); 1785 emit_insn (gen_spu_heq (scratch_reg_0, GEN_INT (0)));
2051 } 1786 }
2052 1787
2053 /* Adjust the stack pointer, and make sure scratch_reg_0 contains 1788 /* Adjust the stack pointer, and make sure scratch_reg_0 contains
2088 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real); 1823 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
2089 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY; 1824 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
2090 } 1825 }
2091 } 1826 }
2092 1827
2093 if (flag_stack_usage) 1828 if (flag_stack_usage_info)
2094 current_function_static_stack_size = total_size; 1829 current_function_static_stack_size = total_size;
2095 } 1830 }
2096 1831
2097 void 1832 void
2098 spu_expand_epilogue (bool sibcall_p) 1833 spu_expand_epilogue (bool sibcall_p)
2099 { 1834 {
2100 int size = get_frame_size (), offset, regno; 1835 int size = get_frame_size (), offset, regno;
2101 HOST_WIDE_INT saved_regs_size, total_size; 1836 HOST_WIDE_INT saved_regs_size, total_size;
2102 rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); 1837 rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
2103 rtx jump, scratch_reg_0; 1838 rtx scratch_reg_0;
2104 1839
2105 if (spu_naked_function_p (current_function_decl)) 1840 if (spu_naked_function_p (current_function_decl))
2106 return; 1841 return;
2107 1842
2108 scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1); 1843 scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1);
2110 saved_regs_size = spu_saved_regs_size (); 1845 saved_regs_size = spu_saved_regs_size ();
2111 total_size = size + saved_regs_size 1846 total_size = size + saved_regs_size
2112 + crtl->outgoing_args_size 1847 + crtl->outgoing_args_size
2113 + crtl->args.pretend_args_size; 1848 + crtl->args.pretend_args_size;
2114 1849
2115 if (!current_function_is_leaf 1850 if (!crtl->is_leaf
2116 || cfun->calls_alloca || total_size > 0) 1851 || cfun->calls_alloca || total_size > 0)
2117 total_size += STACK_POINTER_OFFSET; 1852 total_size += STACK_POINTER_OFFSET;
2118 1853
2119 if (total_size > 0) 1854 if (total_size > 0)
2120 { 1855 {
2134 frame_emit_load (regno, sp_reg, offset); 1869 frame_emit_load (regno, sp_reg, offset);
2135 } 1870 }
2136 } 1871 }
2137 } 1872 }
2138 1873
2139 if (!current_function_is_leaf) 1874 if (!crtl->is_leaf)
2140 frame_emit_load (LINK_REGISTER_REGNUM, sp_reg, 16); 1875 frame_emit_load (LINK_REGISTER_REGNUM, sp_reg, 16);
2141 1876
2142 if (!sibcall_p) 1877 if (!sibcall_p)
2143 { 1878 {
2144 emit_use (gen_rtx_REG (SImode, LINK_REGISTER_REGNUM)); 1879 emit_use (gen_rtx_REG (SImode, LINK_REGISTER_REGNUM));
2145 jump = emit_jump_insn (gen__return ()); 1880 emit_jump_insn (gen__return ());
2146 emit_barrier_after (jump); 1881 }
2147 }
2148
2149 } 1882 }
2150 1883
2151 rtx 1884 rtx
2152 spu_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) 1885 spu_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
2153 { 1886 {
2165 1898
2166 /* Given VAL, generate a constant appropriate for MODE. 1899 /* Given VAL, generate a constant appropriate for MODE.
2167 If MODE is a vector mode, every element will be VAL. 1900 If MODE is a vector mode, every element will be VAL.
2168 For TImode, VAL will be zero extended to 128 bits. */ 1901 For TImode, VAL will be zero extended to 128 bits. */
2169 rtx 1902 rtx
2170 spu_const (enum machine_mode mode, HOST_WIDE_INT val) 1903 spu_const (machine_mode mode, HOST_WIDE_INT val)
2171 { 1904 {
2172 rtx inner; 1905 rtx inner;
2173 rtvec v; 1906 rtvec v;
2174 int units, i; 1907 int units, i;
2175 1908
2200 return gen_rtx_CONST_VECTOR (mode, v); 1933 return gen_rtx_CONST_VECTOR (mode, v);
2201 } 1934 }
2202 1935
2203 /* Create a MODE vector constant from 4 ints. */ 1936 /* Create a MODE vector constant from 4 ints. */
2204 rtx 1937 rtx
2205 spu_const_from_ints(enum machine_mode mode, int a, int b, int c, int d) 1938 spu_const_from_ints(machine_mode mode, int a, int b, int c, int d)
2206 { 1939 {
2207 unsigned char arr[16]; 1940 unsigned char arr[16];
2208 arr[0] = (a >> 24) & 0xff; 1941 arr[0] = (a >> 24) & 0xff;
2209 arr[1] = (a >> 16) & 0xff; 1942 arr[1] = (a >> 16) & 0xff;
2210 arr[2] = (a >> 8) & 0xff; 1943 arr[2] = (a >> 8) & 0xff;
2227 /* branch hint stuff */ 1960 /* branch hint stuff */
2228 1961
2229 /* An array of these is used to propagate hints to predecessor blocks. */ 1962 /* An array of these is used to propagate hints to predecessor blocks. */
2230 struct spu_bb_info 1963 struct spu_bb_info
2231 { 1964 {
2232 rtx prop_jump; /* propagated from another block */ 1965 rtx_insn *prop_jump; /* propagated from another block */
2233 int bb_index; /* the original block. */ 1966 int bb_index; /* the original block. */
2234 }; 1967 };
2235 static struct spu_bb_info *spu_bb_info; 1968 static struct spu_bb_info *spu_bb_info;
2236 1969
2237 #define STOP_HINT_P(INSN) \ 1970 #define STOP_HINT_P(INSN) \
2238 (GET_CODE(INSN) == CALL_INSN \ 1971 (CALL_P(INSN) \
2239 || INSN_CODE(INSN) == CODE_FOR_divmodsi4 \ 1972 || INSN_CODE(INSN) == CODE_FOR_divmodsi4 \
2240 || INSN_CODE(INSN) == CODE_FOR_udivmodsi4) 1973 || INSN_CODE(INSN) == CODE_FOR_udivmodsi4)
2241 1974
2242 /* 1 when RTX is a hinted branch or its target. We keep track of 1975 /* 1 when RTX is a hinted branch or its target. We keep track of
2243 what has been hinted so the safe-hint code can test it easily. */ 1976 what has been hinted so the safe-hint code can test it easily. */
2249 (RTL_FLAG_CHECK2("SCHED_ON_EVEN_P", (RTX), JUMP_INSN, CALL_INSN)->in_struct) 1982 (RTL_FLAG_CHECK2("SCHED_ON_EVEN_P", (RTX), JUMP_INSN, CALL_INSN)->in_struct)
2250 1983
2251 /* Emit a nop for INSN such that the two will dual issue. This assumes 1984 /* Emit a nop for INSN such that the two will dual issue. This assumes
2252 INSN is 8-byte aligned. When INSN is inline asm we emit an lnop. 1985 INSN is 8-byte aligned. When INSN is inline asm we emit an lnop.
2253 We check for TImode to handle a MULTI1 insn which has dual issued its 1986 We check for TImode to handle a MULTI1 insn which has dual issued its
2254 first instruction. get_pipe returns -1 for MULTI0, inline asm, or 1987 first instruction. get_pipe returns -1 for MULTI0 or inline asm. */
2255 ADDR_VEC insns. */
2256 static void 1988 static void
2257 emit_nop_for_insn (rtx insn) 1989 emit_nop_for_insn (rtx_insn *insn)
2258 { 1990 {
2259 int p; 1991 int p;
2260 rtx new_insn; 1992 rtx_insn *new_insn;
1993
1994 /* We need to handle JUMP_TABLE_DATA separately. */
1995 if (JUMP_TABLE_DATA_P (insn))
1996 {
1997 new_insn = emit_insn_after (gen_lnop(), insn);
1998 recog_memoized (new_insn);
1999 INSN_LOCATION (new_insn) = UNKNOWN_LOCATION;
2000 return;
2001 }
2002
2261 p = get_pipe (insn); 2003 p = get_pipe (insn);
2262 if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn)) 2004 if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn))
2263 new_insn = emit_insn_after (gen_lnop (), insn); 2005 new_insn = emit_insn_after (gen_lnop (), insn);
2264 else if (p == 1 && GET_MODE (insn) == TImode) 2006 else if (p == 1 && GET_MODE (insn) == TImode)
2265 { 2007 {
2268 PUT_MODE (insn, VOIDmode); 2010 PUT_MODE (insn, VOIDmode);
2269 } 2011 }
2270 else 2012 else
2271 new_insn = emit_insn_after (gen_lnop (), insn); 2013 new_insn = emit_insn_after (gen_lnop (), insn);
2272 recog_memoized (new_insn); 2014 recog_memoized (new_insn);
2273 INSN_LOCATOR (new_insn) = INSN_LOCATOR (insn); 2015 INSN_LOCATION (new_insn) = INSN_LOCATION (insn);
2274 } 2016 }
2275 2017
2276 /* Insert nops in basic blocks to meet dual issue alignment 2018 /* Insert nops in basic blocks to meet dual issue alignment
2277 requirements. Also make sure hbrp and hint instructions are at least 2019 requirements. Also make sure hbrp and hint instructions are at least
2278 one cycle apart, possibly inserting a nop. */ 2020 one cycle apart, possibly inserting a nop. */
2279 static void 2021 static void
2280 pad_bb(void) 2022 pad_bb(void)
2281 { 2023 {
2282 rtx insn, next_insn, prev_insn, hbr_insn = 0; 2024 rtx_insn *insn, *next_insn, *prev_insn, *hbr_insn = 0;
2283 int length; 2025 int length;
2284 int addr; 2026 int addr;
2285 2027
2286 /* This sets up INSN_ADDRESSES. */ 2028 /* This sets up INSN_ADDRESSES. */
2287 shorten_branches (get_insns ()); 2029 shorten_branches (get_insns ());
2307 || (a1 - a0 == 4)) 2049 || (a1 - a0 == 4))
2308 { 2050 {
2309 prev_insn = emit_insn_before (gen_lnop (), insn); 2051 prev_insn = emit_insn_before (gen_lnop (), insn);
2310 PUT_MODE (prev_insn, GET_MODE (insn)); 2052 PUT_MODE (prev_insn, GET_MODE (insn));
2311 PUT_MODE (insn, TImode); 2053 PUT_MODE (insn, TImode);
2312 INSN_LOCATOR (prev_insn) = INSN_LOCATOR (insn); 2054 INSN_LOCATION (prev_insn) = INSN_LOCATION (insn);
2313 length += 4; 2055 length += 4;
2314 } 2056 }
2315 } 2057 }
2316 hbr_insn = insn; 2058 hbr_insn = insn;
2317 } 2059 }
2318 if (INSN_CODE (insn) == CODE_FOR_blockage) 2060 if (INSN_CODE (insn) == CODE_FOR_blockage && next_insn)
2319 { 2061 {
2320 if (GET_MODE (insn) == TImode) 2062 if (GET_MODE (insn) == TImode)
2321 PUT_MODE (next_insn, TImode); 2063 PUT_MODE (next_insn, TImode);
2322 insn = next_insn; 2064 insn = next_insn;
2323 next_insn = next_active_insn (insn); 2065 next_insn = next_active_insn (insn);
2347 2089
2348 2090
2349 /* Routines for branch hints. */ 2091 /* Routines for branch hints. */
2350 2092
2351 static void 2093 static void
2352 spu_emit_branch_hint (rtx before, rtx branch, rtx target, 2094 spu_emit_branch_hint (rtx_insn *before, rtx_insn *branch, rtx target,
2353 int distance, sbitmap blocks) 2095 int distance, sbitmap blocks)
2354 { 2096 {
2355 rtx branch_label = 0; 2097 rtx_insn *hint;
2356 rtx hint; 2098 rtx_insn *insn;
2357 rtx insn; 2099 rtx_jump_table_data *table;
2358 rtx table;
2359 2100
2360 if (before == 0 || branch == 0 || target == 0) 2101 if (before == 0 || branch == 0 || target == 0)
2361 return; 2102 return;
2362 2103
2363 /* While scheduling we require hints to be no further than 600, so 2104 /* While scheduling we require hints to be no further than 600, so
2367 2108
2368 /* If we have a Basic block note, emit it after the basic block note. */ 2109 /* If we have a Basic block note, emit it after the basic block note. */
2369 if (NOTE_INSN_BASIC_BLOCK_P (before)) 2110 if (NOTE_INSN_BASIC_BLOCK_P (before))
2370 before = NEXT_INSN (before); 2111 before = NEXT_INSN (before);
2371 2112
2372 branch_label = gen_label_rtx (); 2113 rtx_code_label *branch_label = gen_label_rtx ();
2373 LABEL_NUSES (branch_label)++; 2114 LABEL_NUSES (branch_label)++;
2374 LABEL_PRESERVE_P (branch_label) = 1; 2115 LABEL_PRESERVE_P (branch_label) = 1;
2375 insn = emit_label_before (branch_label, branch); 2116 insn = emit_label_before (branch_label, branch);
2376 branch_label = gen_rtx_LABEL_REF (VOIDmode, branch_label); 2117 rtx branch_label_ref = gen_rtx_LABEL_REF (VOIDmode, branch_label);
2377 SET_BIT (blocks, BLOCK_FOR_INSN (branch)->index); 2118 bitmap_set_bit (blocks, BLOCK_FOR_INSN (branch)->index);
2378 2119
2379 hint = emit_insn_before (gen_hbr (branch_label, target), before); 2120 hint = emit_insn_before (gen_hbr (branch_label_ref, target), before);
2380 recog_memoized (hint); 2121 recog_memoized (hint);
2381 INSN_LOCATOR (hint) = INSN_LOCATOR (branch); 2122 INSN_LOCATION (hint) = INSN_LOCATION (branch);
2382 HINTED_P (branch) = 1; 2123 HINTED_P (branch) = 1;
2383 2124
2384 if (GET_CODE (target) == LABEL_REF) 2125 if (GET_CODE (target) == LABEL_REF)
2385 HINTED_P (XEXP (target, 0)) = 1; 2126 HINTED_P (XEXP (target, 0)) = 1;
2386 else if (tablejump_p (branch, 0, &table)) 2127 else if (tablejump_p (branch, 0, &table))
2399 { 2140 {
2400 /* Make sure the hint isn't scheduled any earlier than this point, 2141 /* Make sure the hint isn't scheduled any earlier than this point,
2401 which could make it too far for the branch offest to fit */ 2142 which could make it too far for the branch offest to fit */
2402 insn = emit_insn_before (gen_blockage (), hint); 2143 insn = emit_insn_before (gen_blockage (), hint);
2403 recog_memoized (insn); 2144 recog_memoized (insn);
2404 INSN_LOCATOR (insn) = INSN_LOCATOR (hint); 2145 INSN_LOCATION (insn) = INSN_LOCATION (hint);
2405 } 2146 }
2406 else if (distance <= 8 * 4) 2147 else if (distance <= 8 * 4)
2407 { 2148 {
2408 /* To guarantee at least 8 insns between the hint and branch we 2149 /* To guarantee at least 8 insns between the hint and branch we
2409 insert nops. */ 2150 insert nops. */
2411 for (d = distance; d < 8 * 4; d += 4) 2152 for (d = distance; d < 8 * 4; d += 4)
2412 { 2153 {
2413 insn = 2154 insn =
2414 emit_insn_after (gen_nopn_nv (gen_rtx_REG (SImode, 127)), hint); 2155 emit_insn_after (gen_nopn_nv (gen_rtx_REG (SImode, 127)), hint);
2415 recog_memoized (insn); 2156 recog_memoized (insn);
2416 INSN_LOCATOR (insn) = INSN_LOCATOR (hint); 2157 INSN_LOCATION (insn) = INSN_LOCATION (hint);
2417 } 2158 }
2418 2159
2419 /* Make sure any nops inserted aren't scheduled before the hint. */ 2160 /* Make sure any nops inserted aren't scheduled before the hint. */
2420 insn = emit_insn_after (gen_blockage (), hint); 2161 insn = emit_insn_after (gen_blockage (), hint);
2421 recog_memoized (insn); 2162 recog_memoized (insn);
2422 INSN_LOCATOR (insn) = INSN_LOCATOR (hint); 2163 INSN_LOCATION (insn) = INSN_LOCATION (hint);
2423 2164
2424 /* Make sure any nops inserted aren't scheduled after the call. */ 2165 /* Make sure any nops inserted aren't scheduled after the call. */
2425 if (CALL_P (branch) && distance < 8 * 4) 2166 if (CALL_P (branch) && distance < 8 * 4)
2426 { 2167 {
2427 insn = emit_insn_before (gen_blockage (), branch); 2168 insn = emit_insn_before (gen_blockage (), branch);
2428 recog_memoized (insn); 2169 recog_memoized (insn);
2429 INSN_LOCATOR (insn) = INSN_LOCATOR (branch); 2170 INSN_LOCATION (insn) = INSN_LOCATION (branch);
2430 } 2171 }
2431 } 2172 }
2432 } 2173 }
2433 2174
2434 /* Returns 0 if we don't want a hint for this branch. Otherwise return 2175 /* Returns 0 if we don't want a hint for this branch. Otherwise return
2435 the rtx for the branch target. */ 2176 the rtx for the branch target. */
2436 static rtx 2177 static rtx
2437 get_branch_target (rtx branch) 2178 get_branch_target (rtx_insn *branch)
2438 { 2179 {
2439 if (GET_CODE (branch) == JUMP_INSN) 2180 if (JUMP_P (branch))
2440 { 2181 {
2441 rtx set, src; 2182 rtx set, src;
2442 2183
2443 /* Return statements */ 2184 /* Return statements */
2444 if (GET_CODE (PATTERN (branch)) == RETURN) 2185 if (GET_CODE (PATTERN (branch)) == RETURN)
2445 return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM); 2186 return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM);
2446
2447 /* jump table */
2448 if (GET_CODE (PATTERN (branch)) == ADDR_VEC
2449 || GET_CODE (PATTERN (branch)) == ADDR_DIFF_VEC)
2450 return 0;
2451 2187
2452 /* ASM GOTOs. */ 2188 /* ASM GOTOs. */
2453 if (extract_asm_operands (PATTERN (branch)) != NULL) 2189 if (extract_asm_operands (PATTERN (branch)) != NULL)
2454 return NULL; 2190 return NULL;
2455 2191
2464 rtx note = find_reg_note (branch, REG_BR_PROB, 0); 2200 rtx note = find_reg_note (branch, REG_BR_PROB, 0);
2465 if (note) 2201 if (note)
2466 { 2202 {
2467 /* If the more probable case is not a fall through, then 2203 /* If the more probable case is not a fall through, then
2468 try a branch hint. */ 2204 try a branch hint. */
2469 HOST_WIDE_INT prob = INTVAL (XEXP (note, 0)); 2205 int prob = profile_probability::from_reg_br_prob_note
2206 (XINT (note, 0)).to_reg_br_prob_base ();
2470 if (prob > (REG_BR_PROB_BASE * 6 / 10) 2207 if (prob > (REG_BR_PROB_BASE * 6 / 10)
2471 && GET_CODE (XEXP (src, 1)) != PC) 2208 && GET_CODE (XEXP (src, 1)) != PC)
2472 lab = XEXP (src, 1); 2209 lab = XEXP (src, 1);
2473 else if (prob < (REG_BR_PROB_BASE * 4 / 10) 2210 else if (prob < (REG_BR_PROB_BASE * 4 / 10)
2474 && GET_CODE (XEXP (src, 2)) != PC) 2211 && GET_CODE (XEXP (src, 2)) != PC)
2483 return 0; 2220 return 0;
2484 } 2221 }
2485 2222
2486 return src; 2223 return src;
2487 } 2224 }
2488 else if (GET_CODE (branch) == CALL_INSN) 2225 else if (CALL_P (branch))
2489 { 2226 {
2490 rtx call; 2227 rtx call;
2491 /* All of our call patterns are in a PARALLEL and the CALL is 2228 /* All of our call patterns are in a PARALLEL and the CALL is
2492 the first pattern in the PARALLEL. */ 2229 the first pattern in the PARALLEL. */
2493 if (GET_CODE (PATTERN (branch)) != PARALLEL) 2230 if (GET_CODE (PATTERN (branch)) != PARALLEL)
2505 /* The special $hbr register is used to prevent the insn scheduler from 2242 /* The special $hbr register is used to prevent the insn scheduler from
2506 moving hbr insns across instructions which invalidate them. It 2243 moving hbr insns across instructions which invalidate them. It
2507 should only be used in a clobber, and this function searches for 2244 should only be used in a clobber, and this function searches for
2508 insns which clobber it. */ 2245 insns which clobber it. */
2509 static bool 2246 static bool
2510 insn_clobbers_hbr (rtx insn) 2247 insn_clobbers_hbr (rtx_insn *insn)
2511 { 2248 {
2512 if (INSN_P (insn) 2249 if (INSN_P (insn)
2513 && GET_CODE (PATTERN (insn)) == PARALLEL) 2250 && GET_CODE (PATTERN (insn)) == PARALLEL)
2514 { 2251 {
2515 rtx parallel = PATTERN (insn); 2252 rtx parallel = PATTERN (insn);
2536 an even address. 2273 an even address.
2537 At then end of the search, insert an hbrp within 4 insns of FIRST, 2274 At then end of the search, insert an hbrp within 4 insns of FIRST,
2538 and an hbrp within 16 instructions of FIRST. 2275 and an hbrp within 16 instructions of FIRST.
2539 */ 2276 */
2540 static void 2277 static void
2541 insert_hbrp_for_ilb_runout (rtx first) 2278 insert_hbrp_for_ilb_runout (rtx_insn *first)
2542 { 2279 {
2543 rtx insn, before_4 = 0, before_16 = 0; 2280 rtx_insn *insn, *before_4 = 0, *before_16 = 0;
2544 int addr = 0, length, first_addr = -1; 2281 int addr = 0, length, first_addr = -1;
2545 int hbrp_addr0 = 128 * 4, hbrp_addr1 = 128 * 4; 2282 int hbrp_addr0 = 128 * 4, hbrp_addr1 = 128 * 4;
2546 int insert_lnop_after = 0; 2283 int insert_lnop_after = 0;
2547 for (insn = first; insn; insn = NEXT_INSN (insn)) 2284 for (insn = first; insn; insn = NEXT_INSN (insn))
2548 if (INSN_P (insn)) 2285 if (INSN_P (insn))
2610 if (hbrp_addr0 > 4 * 4) 2347 if (hbrp_addr0 > 4 * 4)
2611 { 2348 {
2612 insn = 2349 insn =
2613 emit_insn_before (gen_iprefetch (GEN_INT (1)), before_4); 2350 emit_insn_before (gen_iprefetch (GEN_INT (1)), before_4);
2614 recog_memoized (insn); 2351 recog_memoized (insn);
2615 INSN_LOCATOR (insn) = INSN_LOCATOR (before_4); 2352 INSN_LOCATION (insn) = INSN_LOCATION (before_4);
2616 INSN_ADDRESSES_NEW (insn, 2353 INSN_ADDRESSES_NEW (insn,
2617 INSN_ADDRESSES (INSN_UID (before_4))); 2354 INSN_ADDRESSES (INSN_UID (before_4)));
2618 PUT_MODE (insn, GET_MODE (before_4)); 2355 PUT_MODE (insn, GET_MODE (before_4));
2619 PUT_MODE (before_4, TImode); 2356 PUT_MODE (before_4, TImode);
2620 if (insert_lnop_after & 1) 2357 if (insert_lnop_after & 1)
2621 { 2358 {
2622 insn = emit_insn_before (gen_lnop (), before_4); 2359 insn = emit_insn_before (gen_lnop (), before_4);
2623 recog_memoized (insn); 2360 recog_memoized (insn);
2624 INSN_LOCATOR (insn) = INSN_LOCATOR (before_4); 2361 INSN_LOCATION (insn) = INSN_LOCATION (before_4);
2625 INSN_ADDRESSES_NEW (insn, 2362 INSN_ADDRESSES_NEW (insn,
2626 INSN_ADDRESSES (INSN_UID (before_4))); 2363 INSN_ADDRESSES (INSN_UID (before_4)));
2627 PUT_MODE (insn, TImode); 2364 PUT_MODE (insn, TImode);
2628 } 2365 }
2629 } 2366 }
2631 && hbrp_addr1 > 16 * 4) 2368 && hbrp_addr1 > 16 * 4)
2632 { 2369 {
2633 insn = 2370 insn =
2634 emit_insn_before (gen_iprefetch (GEN_INT (2)), before_16); 2371 emit_insn_before (gen_iprefetch (GEN_INT (2)), before_16);
2635 recog_memoized (insn); 2372 recog_memoized (insn);
2636 INSN_LOCATOR (insn) = INSN_LOCATOR (before_16); 2373 INSN_LOCATION (insn) = INSN_LOCATION (before_16);
2637 INSN_ADDRESSES_NEW (insn, 2374 INSN_ADDRESSES_NEW (insn,
2638 INSN_ADDRESSES (INSN_UID (before_16))); 2375 INSN_ADDRESSES (INSN_UID (before_16)));
2639 PUT_MODE (insn, GET_MODE (before_16)); 2376 PUT_MODE (insn, GET_MODE (before_16));
2640 PUT_MODE (before_16, TImode); 2377 PUT_MODE (before_16, TImode);
2641 if (insert_lnop_after & 2) 2378 if (insert_lnop_after & 2)
2642 { 2379 {
2643 insn = emit_insn_before (gen_lnop (), before_16); 2380 insn = emit_insn_before (gen_lnop (), before_16);
2644 recog_memoized (insn); 2381 recog_memoized (insn);
2645 INSN_LOCATOR (insn) = INSN_LOCATOR (before_16); 2382 INSN_LOCATION (insn) = INSN_LOCATION (before_16);
2646 INSN_ADDRESSES_NEW (insn, 2383 INSN_ADDRESSES_NEW (insn,
2647 INSN_ADDRESSES (INSN_UID 2384 INSN_ADDRESSES (INSN_UID
2648 (before_16))); 2385 (before_16)));
2649 PUT_MODE (insn, TImode); 2386 PUT_MODE (insn, TImode);
2650 } 2387 }
2657 2394
2658 } 2395 }
2659 2396
2660 /* The SPU might hang when it executes 48 inline instructions after a 2397 /* The SPU might hang when it executes 48 inline instructions after a
2661 hinted branch jumps to its hinted target. The beginning of a 2398 hinted branch jumps to its hinted target. The beginning of a
2662 function and the return from a call might have been hinted, and must 2399 function and the return from a call might have been hinted, and
2663 be handled as well. To prevent a hang we insert 2 hbrps. The first 2400 must be handled as well. To prevent a hang we insert 2 hbrps. The
2664 should be within 6 insns of the branch target. The second should be 2401 first should be within 6 insns of the branch target. The second
2665 within 22 insns of the branch target. When determining if hbrps are 2402 should be within 22 insns of the branch target. When determining
2666 necessary, we look for only 32 inline instructions, because up to to 2403 if hbrps are necessary, we look for only 32 inline instructions,
2667 12 nops and 4 hbrps could be inserted. Similarily, when inserting 2404 because up to 12 nops and 4 hbrps could be inserted. Similarily,
2668 new hbrps, we insert them within 4 and 16 insns of the target. */ 2405 when inserting new hbrps, we insert them within 4 and 16 insns of
2406 the target. */
2669 static void 2407 static void
2670 insert_hbrp (void) 2408 insert_hbrp (void)
2671 { 2409 {
2672 rtx insn; 2410 rtx_insn *insn;
2673 if (TARGET_SAFE_HINTS) 2411 if (TARGET_SAFE_HINTS)
2674 { 2412 {
2675 shorten_branches (get_insns ()); 2413 shorten_branches (get_insns ());
2676 /* Insert hbrp at beginning of function */ 2414 /* Insert hbrp at beginning of function */
2677 insn = next_active_insn (get_insns ()); 2415 insn = next_active_insn (get_insns ());
2684 } 2422 }
2685 } 2423 }
2686 2424
2687 static int in_spu_reorg; 2425 static int in_spu_reorg;
2688 2426
2427 static void
2428 spu_var_tracking (void)
2429 {
2430 if (flag_var_tracking)
2431 {
2432 df_analyze ();
2433 timevar_push (TV_VAR_TRACKING);
2434 variable_tracking_main ();
2435 timevar_pop (TV_VAR_TRACKING);
2436 df_finish_pass (false);
2437 }
2438 }
2439
2689 /* Insert branch hints. There are no branch optimizations after this 2440 /* Insert branch hints. There are no branch optimizations after this
2690 pass, so it's safe to set our branch hints now. */ 2441 pass, so it's safe to set our branch hints now. */
2691 static void 2442 static void
2692 spu_machine_dependent_reorg (void) 2443 spu_machine_dependent_reorg (void)
2693 { 2444 {
2694 sbitmap blocks; 2445 sbitmap blocks;
2695 basic_block bb; 2446 basic_block bb;
2696 rtx branch, insn; 2447 rtx_insn *branch, *insn;
2697 rtx branch_target = 0; 2448 rtx branch_target = 0;
2698 int branch_addr = 0, insn_addr, required_dist = 0; 2449 int branch_addr = 0, insn_addr, required_dist = 0;
2699 int i; 2450 int i;
2700 unsigned int j; 2451 unsigned int j;
2701 2452
2702 if (!TARGET_BRANCH_HINTS || optimize == 0) 2453 if (!TARGET_BRANCH_HINTS || optimize == 0)
2703 { 2454 {
2704 /* We still do it for unoptimized code because an external 2455 /* We still do it for unoptimized code because an external
2705 function might have hinted a call or return. */ 2456 function might have hinted a call or return. */
2457 compute_bb_for_insn ();
2706 insert_hbrp (); 2458 insert_hbrp ();
2707 pad_bb (); 2459 pad_bb ();
2460 spu_var_tracking ();
2461 free_bb_for_insn ();
2708 return; 2462 return;
2709 } 2463 }
2710 2464
2711 blocks = sbitmap_alloc (last_basic_block); 2465 blocks = sbitmap_alloc (last_basic_block_for_fn (cfun));
2712 sbitmap_zero (blocks); 2466 bitmap_clear (blocks);
2713 2467
2714 in_spu_reorg = 1; 2468 in_spu_reorg = 1;
2715 compute_bb_for_insn (); 2469 compute_bb_for_insn ();
2716 2470
2471 /* (Re-)discover loops so that bb->loop_father can be used
2472 in the analysis below. */
2473 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
2474
2717 compact_blocks (); 2475 compact_blocks ();
2718 2476
2719 spu_bb_info = 2477 spu_bb_info =
2720 (struct spu_bb_info *) xcalloc (n_basic_blocks, 2478 (struct spu_bb_info *) xcalloc (n_basic_blocks_for_fn (cfun),
2721 sizeof (struct spu_bb_info)); 2479 sizeof (struct spu_bb_info));
2722 2480
2723 /* We need exact insn addresses and lengths. */ 2481 /* We need exact insn addresses and lengths. */
2724 shorten_branches (get_insns ()); 2482 shorten_branches (get_insns ());
2725 2483
2726 for (i = n_basic_blocks - 1; i >= 0; i--) 2484 for (i = n_basic_blocks_for_fn (cfun) - 1; i >= 0; i--)
2727 { 2485 {
2728 bb = BASIC_BLOCK (i); 2486 bb = BASIC_BLOCK_FOR_FN (cfun, i);
2729 branch = 0; 2487 branch = 0;
2730 if (spu_bb_info[i].prop_jump) 2488 if (spu_bb_info[i].prop_jump)
2731 { 2489 {
2732 branch = spu_bb_info[i].prop_jump; 2490 branch = spu_bb_info[i].prop_jump;
2733 branch_target = get_branch_target (branch); 2491 branch_target = get_branch_target (branch);
2756 && ((GET_CODE (branch_target) == REG 2514 && ((GET_CODE (branch_target) == REG
2757 && set_of (branch_target, insn) != NULL_RTX) 2515 && set_of (branch_target, insn) != NULL_RTX)
2758 || insn_clobbers_hbr (insn) 2516 || insn_clobbers_hbr (insn)
2759 || branch_addr - insn_addr > 600)) 2517 || branch_addr - insn_addr > 600))
2760 { 2518 {
2761 rtx next = NEXT_INSN (insn); 2519 rtx_insn *next = NEXT_INSN (insn);
2762 int next_addr = INSN_ADDRESSES (INSN_UID (next)); 2520 int next_addr = INSN_ADDRESSES (INSN_UID (next));
2763 if (insn != BB_END (bb) 2521 if (insn != BB_END (bb)
2764 && branch_addr - next_addr >= required_dist) 2522 && branch_addr - next_addr >= required_dist)
2765 { 2523 {
2766 if (dump_file) 2524 if (dump_file)
2795 if (branch) 2553 if (branch)
2796 { 2554 {
2797 /* If we haven't emitted a hint for this branch yet, it might 2555 /* If we haven't emitted a hint for this branch yet, it might
2798 be profitable to emit it in one of the predecessor blocks, 2556 be profitable to emit it in one of the predecessor blocks,
2799 especially for loops. */ 2557 especially for loops. */
2800 rtx bbend; 2558 rtx_insn *bbend;
2801 basic_block prev = 0, prop = 0, prev2 = 0; 2559 basic_block prev = 0, prop = 0, prev2 = 0;
2802 int loop_exit = 0, simple_loop = 0; 2560 int loop_exit = 0, simple_loop = 0;
2803 int next_addr = INSN_ADDRESSES (INSN_UID (NEXT_INSN (insn))); 2561 int next_addr = INSN_ADDRESSES (INSN_UID (NEXT_INSN (insn)));
2804 2562
2805 for (j = 0; j < EDGE_COUNT (bb->preds); j++) 2563 for (j = 0; j < EDGE_COUNT (bb->preds); j++)
2816 2574
2817 /* If this branch is a loop exit then propagate to previous 2575 /* If this branch is a loop exit then propagate to previous
2818 fallthru block. This catches the cases when it is a simple 2576 fallthru block. This catches the cases when it is a simple
2819 loop or when there is an initial branch into the loop. */ 2577 loop or when there is an initial branch into the loop. */
2820 if (prev && (loop_exit || simple_loop) 2578 if (prev && (loop_exit || simple_loop)
2821 && prev->loop_depth <= bb->loop_depth) 2579 && bb_loop_depth (prev) <= bb_loop_depth (bb))
2822 prop = prev; 2580 prop = prev;
2823 2581
2824 /* If there is only one adjacent predecessor. Don't propagate 2582 /* If there is only one adjacent predecessor. Don't propagate
2825 outside this loop. This loop_depth test isn't perfect, but 2583 outside this loop. */
2826 I'm not sure the loop_father member is valid at this point. */
2827 else if (prev && single_pred_p (bb) 2584 else if (prev && single_pred_p (bb)
2828 && prev->loop_depth == bb->loop_depth) 2585 && prev->loop_father == bb->loop_father)
2829 prop = prev; 2586 prop = prev;
2830 2587
2831 /* If this is the JOIN block of a simple IF-THEN then 2588 /* If this is the JOIN block of a simple IF-THEN then
2832 propogate the hint to the HEADER block. */ 2589 propagate the hint to the HEADER block. */
2833 else if (prev && prev2 2590 else if (prev && prev2
2834 && EDGE_COUNT (bb->preds) == 2 2591 && EDGE_COUNT (bb->preds) == 2
2835 && EDGE_COUNT (prev->preds) == 1 2592 && EDGE_COUNT (prev->preds) == 1
2836 && EDGE_PRED (prev, 0)->src == prev2 2593 && EDGE_PRED (prev, 0)->src == prev2
2837 && prev2->loop_depth == bb->loop_depth 2594 && prev2->loop_father == bb->loop_father
2838 && GET_CODE (branch_target) != REG) 2595 && GET_CODE (branch_target) != REG)
2839 prop = prev; 2596 prop = prev;
2840 2597
2841 /* Don't propagate when: 2598 /* Don't propagate when:
2842 - this is a simple loop and the hint would be too far 2599 - this is a simple loop and the hint would be too far
2854 && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend))) 2611 && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend)))
2855 { 2612 {
2856 if (dump_file) 2613 if (dump_file)
2857 fprintf (dump_file, "propagate from %i to %i (loop depth %i) " 2614 fprintf (dump_file, "propagate from %i to %i (loop depth %i) "
2858 "for %i (loop_exit %i simple_loop %i dist %i)\n", 2615 "for %i (loop_exit %i simple_loop %i dist %i)\n",
2859 bb->index, prop->index, bb->loop_depth, 2616 bb->index, prop->index, bb_loop_depth (bb),
2860 INSN_UID (branch), loop_exit, simple_loop, 2617 INSN_UID (branch), loop_exit, simple_loop,
2861 branch_addr - INSN_ADDRESSES (INSN_UID (bbend))); 2618 branch_addr - INSN_ADDRESSES (INSN_UID (bbend)));
2862 2619
2863 spu_bb_info[prop->index].prop_jump = branch; 2620 spu_bb_info[prop->index].prop_jump = branch;
2864 spu_bb_info[prop->index].bb_index = i; 2621 spu_bb_info[prop->index].bb_index = i;
2875 branch = 0; 2632 branch = 0;
2876 } 2633 }
2877 } 2634 }
2878 free (spu_bb_info); 2635 free (spu_bb_info);
2879 2636
2880 if (!sbitmap_empty_p (blocks)) 2637 if (!bitmap_empty_p (blocks))
2881 find_many_sub_basic_blocks (blocks); 2638 find_many_sub_basic_blocks (blocks);
2882 2639
2883 /* We have to schedule to make sure alignment is ok. */ 2640 /* We have to schedule to make sure alignment is ok. */
2884 FOR_EACH_BB (bb) bb->flags &= ~BB_DISABLE_SCHEDULE; 2641 FOR_EACH_BB_FN (bb, cfun) bb->flags &= ~BB_DISABLE_SCHEDULE;
2885 2642
2886 /* The hints need to be scheduled, so call it again. */ 2643 /* The hints need to be scheduled, so call it again. */
2887 schedule_insns (); 2644 schedule_insns ();
2888 df_finish_pass (true); 2645 df_finish_pass (true);
2889 2646
2897 /* Adjust the LABEL_REF in a hint when we have inserted a nop 2654 /* Adjust the LABEL_REF in a hint when we have inserted a nop
2898 between its branch label and the branch . We don't move the 2655 between its branch label and the branch . We don't move the
2899 label because GCC expects it at the beginning of the block. */ 2656 label because GCC expects it at the beginning of the block. */
2900 rtx unspec = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 2657 rtx unspec = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
2901 rtx label_ref = XVECEXP (unspec, 0, 0); 2658 rtx label_ref = XVECEXP (unspec, 0, 0);
2902 rtx label = XEXP (label_ref, 0); 2659 rtx_insn *label = as_a <rtx_insn *> (XEXP (label_ref, 0));
2903 rtx branch; 2660 rtx_insn *branch;
2904 int offset = 0; 2661 int offset = 0;
2905 for (branch = NEXT_INSN (label); 2662 for (branch = NEXT_INSN (label);
2906 !JUMP_P (branch) && !CALL_P (branch); 2663 !JUMP_P (branch) && !CALL_P (branch);
2907 branch = NEXT_INSN (branch)) 2664 branch = NEXT_INSN (branch))
2908 if (NONJUMP_INSN_P (branch)) 2665 if (NONJUMP_INSN_P (branch))
2909 offset += get_attr_length (branch); 2666 offset += get_attr_length (branch);
2910 if (offset > 0) 2667 if (offset > 0)
2911 XVECEXP (unspec, 0, 0) = plus_constant (label_ref, offset); 2668 XVECEXP (unspec, 0, 0) = plus_constant (Pmode, label_ref, offset);
2912 } 2669 }
2913 2670
2914 if (spu_flag_var_tracking) 2671 spu_var_tracking ();
2915 { 2672
2916 df_analyze (); 2673 loop_optimizer_finalize ();
2917 timevar_push (TV_VAR_TRACKING);
2918 variable_tracking_main ();
2919 timevar_pop (TV_VAR_TRACKING);
2920 df_finish_pass (false);
2921 }
2922 2674
2923 free_bb_for_insn (); 2675 free_bb_for_insn ();
2924 2676
2925 in_spu_reorg = 0; 2677 in_spu_reorg = 0;
2926 } 2678 }
2932 { 2684 {
2933 return 2; 2685 return 2;
2934 } 2686 }
2935 2687
2936 static int 2688 static int
2937 uses_ls_unit(rtx insn) 2689 uses_ls_unit(rtx_insn *insn)
2938 { 2690 {
2939 rtx set = single_set (insn); 2691 rtx set = single_set (insn);
2940 if (set != 0 2692 if (set != 0
2941 && (GET_CODE (SET_DEST (set)) == MEM 2693 && (GET_CODE (SET_DEST (set)) == MEM
2942 || GET_CODE (SET_SRC (set)) == MEM)) 2694 || GET_CODE (SET_SRC (set)) == MEM))
2943 return 1; 2695 return 1;
2944 return 0; 2696 return 0;
2945 } 2697 }
2946 2698
2947 static int 2699 static int
2948 get_pipe (rtx insn) 2700 get_pipe (rtx_insn *insn)
2949 { 2701 {
2950 enum attr_type t; 2702 enum attr_type t;
2951 /* Handle inline asm */ 2703 /* Handle inline asm */
2952 if (INSN_CODE (insn) == -1) 2704 if (INSN_CODE (insn) == -1)
2953 return -1; 2705 return -1;
3039 prev_priority = -1; 2791 prev_priority = -1;
3040 } 2792 }
3041 2793
3042 static int 2794 static int
3043 spu_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED, 2795 spu_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED,
3044 int verbose ATTRIBUTE_UNUSED, rtx insn, int more) 2796 int verbose ATTRIBUTE_UNUSED,
2797 rtx_insn *insn, int more)
3045 { 2798 {
3046 int len; 2799 int len;
3047 int p; 2800 int p;
3048 if (GET_CODE (PATTERN (insn)) == USE 2801 if (GET_CODE (PATTERN (insn)) == USE
3049 || GET_CODE (PATTERN (insn)) == CLOBBER 2802 || GET_CODE (PATTERN (insn)) == CLOBBER
3088 that don't have INSN_PRIORITY */ 2841 that don't have INSN_PRIORITY */
3089 if (more >= 0) 2842 if (more >= 0)
3090 prev_priority = INSN_PRIORITY (insn); 2843 prev_priority = INSN_PRIORITY (insn);
3091 } 2844 }
3092 2845
3093 /* Always try issueing more insns. spu_sched_reorder will decide 2846 /* Always try issuing more insns. spu_sched_reorder will decide
3094 when the cycle should be advanced. */ 2847 when the cycle should be advanced. */
3095 return 1; 2848 return 1;
3096 } 2849 }
3097 2850
3098 /* This function is called for both TARGET_SCHED_REORDER and 2851 /* This function is called for both TARGET_SCHED_REORDER and
3099 TARGET_SCHED_REORDER2. */ 2852 TARGET_SCHED_REORDER2. */
3100 static int 2853 static int
3101 spu_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, 2854 spu_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
3102 rtx *ready, int *nreadyp, int clock) 2855 rtx_insn **ready, int *nreadyp, int clock)
3103 { 2856 {
3104 int i, nready = *nreadyp; 2857 int i, nready = *nreadyp;
3105 int pipe_0, pipe_1, pipe_hbrp, pipe_ls, schedule_i; 2858 int pipe_0, pipe_1, pipe_hbrp, pipe_ls, schedule_i;
3106 rtx insn; 2859 rtx_insn *insn;
3107 2860
3108 clock_var = clock; 2861 clock_var = clock;
3109 2862
3110 if (nready <= 0 || pipe1_clock >= clock) 2863 if (nready <= 0 || pipe1_clock >= clock)
3111 return 0; 2864 return 0;
3146 pipe_0 = i; 2899 pipe_0 = i;
3147 break; 2900 break;
3148 case TYPE_LOAD: 2901 case TYPE_LOAD:
3149 case TYPE_STORE: 2902 case TYPE_STORE:
3150 pipe_ls = i; 2903 pipe_ls = i;
2904 /* FALLTHRU */
3151 case TYPE_LNOP: 2905 case TYPE_LNOP:
3152 case TYPE_SHUF: 2906 case TYPE_SHUF:
3153 case TYPE_BR: 2907 case TYPE_BR:
3154 case TYPE_MULTI1: 2908 case TYPE_MULTI1:
3155 case TYPE_HBR: 2909 case TYPE_HBR:
3195 without effecting the critical path. We look at INSN_PRIORITY to 2949 without effecting the critical path. We look at INSN_PRIORITY to
3196 make a good guess, but it isn't perfect so -mdual-nops=n can be 2950 make a good guess, but it isn't perfect so -mdual-nops=n can be
3197 used to effect it. */ 2951 used to effect it. */
3198 if (in_spu_reorg && spu_dual_nops < 10) 2952 if (in_spu_reorg && spu_dual_nops < 10)
3199 { 2953 {
3200 /* When we are at an even address and we are not issueing nops to 2954 /* When we are at an even address and we are not issuing nops to
3201 improve scheduling then we need to advance the cycle. */ 2955 improve scheduling then we need to advance the cycle. */
3202 if ((spu_sched_length & 7) == 0 && prev_clock_var == clock 2956 if ((spu_sched_length & 7) == 0 && prev_clock_var == clock
3203 && (spu_dual_nops == 0 2957 && (spu_dual_nops == 0
3204 || (pipe_1 != -1 2958 || (pipe_1 != -1
3205 && prev_priority > 2959 && prev_priority >
3236 return 0; 2990 return 0;
3237 } 2991 }
3238 2992
3239 /* INSN is dependent on DEP_INSN. */ 2993 /* INSN is dependent on DEP_INSN. */
3240 static int 2994 static int
3241 spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) 2995 spu_sched_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn,
2996 int cost, unsigned int)
3242 { 2997 {
3243 rtx set; 2998 rtx set;
3244 2999
3245 /* The blockage pattern is used to prevent instructions from being 3000 /* The blockage pattern is used to prevent instructions from being
3246 moved across it and has no cost. */ 3001 moved across it and has no cost. */
3297 3052
3298 /* The dfa scheduler sets cost to 0 for all anti-dependencies and the 3053 /* The dfa scheduler sets cost to 0 for all anti-dependencies and the
3299 scheduler makes every insn in a block anti-dependent on the final 3054 scheduler makes every insn in a block anti-dependent on the final
3300 jump_insn. We adjust here so higher cost insns will get scheduled 3055 jump_insn. We adjust here so higher cost insns will get scheduled
3301 earlier. */ 3056 earlier. */
3302 if (JUMP_P (insn) && REG_NOTE_KIND (link) == REG_DEP_ANTI) 3057 if (JUMP_P (insn) && dep_type == REG_DEP_ANTI)
3303 return insn_cost (dep_insn) - 3; 3058 return insn_sched_cost (dep_insn) - 3;
3304 3059
3305 return cost; 3060 return cost;
3306 } 3061 }
3307 3062
3308 /* Create a CONST_DOUBLE from a string. */ 3063 /* Create a CONST_DOUBLE from a string. */
3309 struct rtx_def * 3064 rtx
3310 spu_float_const (const char *string, enum machine_mode mode) 3065 spu_float_const (const char *string, machine_mode mode)
3311 { 3066 {
3312 REAL_VALUE_TYPE value; 3067 REAL_VALUE_TYPE value;
3313 value = REAL_VALUE_ATOF (string, mode); 3068 value = REAL_VALUE_ATOF (string, mode);
3314 return CONST_DOUBLE_FROM_REAL_VALUE (value, mode); 3069 return const_double_from_real_value (value, mode);
3315 } 3070 }
3316 3071
3317 int 3072 int
3318 spu_constant_address_p (rtx x) 3073 spu_constant_address_p (rtx x)
3319 { 3074 {
3340 } 3095 }
3341 3096
3342 /* Return true when OP can be loaded by one of the il instructions, or 3097 /* Return true when OP can be loaded by one of the il instructions, or
3343 when flow2 is not completed and OP can be loaded using ilhu and iohl. */ 3098 when flow2 is not completed and OP can be loaded using ilhu and iohl. */
3344 int 3099 int
3345 immediate_load_p (rtx op, enum machine_mode mode) 3100 immediate_load_p (rtx op, machine_mode mode)
3346 { 3101 {
3347 if (CONSTANT_P (op)) 3102 if (CONSTANT_P (op))
3348 { 3103 {
3349 enum immediate_class c = classify_immediate (op, mode); 3104 enum immediate_class c = classify_immediate (op, mode);
3350 return c == IC_IL1 || c == IC_IL1s 3105 return c == IC_IL1 || c == IC_IL1s
3403 } 3158 }
3404 3159
3405 /* OP is a CONSTANT_P. Determine what instructions can be used to load 3160 /* OP is a CONSTANT_P. Determine what instructions can be used to load
3406 it into a register. MODE is only valid when OP is a CONST_INT. */ 3161 it into a register. MODE is only valid when OP is a CONST_INT. */
3407 static enum immediate_class 3162 static enum immediate_class
3408 classify_immediate (rtx op, enum machine_mode mode) 3163 classify_immediate (rtx op, machine_mode mode)
3409 { 3164 {
3410 HOST_WIDE_INT val; 3165 HOST_WIDE_INT val;
3411 unsigned char arr[16]; 3166 unsigned char arr[16];
3412 int i, j, repeated, fsmbi, repeat; 3167 int i, j, repeated, fsmbi, repeat;
3413 3168
3419 /* A V4SI const_vector with all identical symbols is ok. */ 3174 /* A V4SI const_vector with all identical symbols is ok. */
3420 if (!flag_pic 3175 if (!flag_pic
3421 && mode == V4SImode 3176 && mode == V4SImode
3422 && GET_CODE (op) == CONST_VECTOR 3177 && GET_CODE (op) == CONST_VECTOR
3423 && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT 3178 && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
3424 && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE 3179 && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE)
3425 && CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1) 3180 op = unwrap_const_vec_duplicate (op);
3426 && CONST_VECTOR_ELT (op, 1) == CONST_VECTOR_ELT (op, 2)
3427 && CONST_VECTOR_ELT (op, 2) == CONST_VECTOR_ELT (op, 3))
3428 op = CONST_VECTOR_ELT (op, 0);
3429 3181
3430 switch (GET_CODE (op)) 3182 switch (GET_CODE (op))
3431 { 3183 {
3432 case SYMBOL_REF: 3184 case SYMBOL_REF:
3433 case LABEL_REF: 3185 case LABEL_REF:
3543 return 0; 3295 return 0;
3544 return 1; 3296 return 1;
3545 } 3297 }
3546 3298
3547 int 3299 int
3548 logical_immediate_p (rtx op, enum machine_mode mode) 3300 logical_immediate_p (rtx op, machine_mode mode)
3549 { 3301 {
3550 HOST_WIDE_INT val; 3302 HOST_WIDE_INT val;
3551 unsigned char arr[16]; 3303 unsigned char arr[16];
3552 int i, j; 3304 int i, j;
3553 3305
3575 i = which_logical_immediate (val); 3327 i = which_logical_immediate (val);
3576 return i != SPU_NONE && i != SPU_IOHL; 3328 return i != SPU_NONE && i != SPU_IOHL;
3577 } 3329 }
3578 3330
3579 int 3331 int
3580 iohl_immediate_p (rtx op, enum machine_mode mode) 3332 iohl_immediate_p (rtx op, machine_mode mode)
3581 { 3333 {
3582 HOST_WIDE_INT val; 3334 HOST_WIDE_INT val;
3583 unsigned char arr[16]; 3335 unsigned char arr[16];
3584 int i, j; 3336 int i, j;
3585 3337
3606 3358
3607 return val >= 0 && val <= 0xffff; 3359 return val >= 0 && val <= 0xffff;
3608 } 3360 }
3609 3361
3610 int 3362 int
3611 arith_immediate_p (rtx op, enum machine_mode mode, 3363 arith_immediate_p (rtx op, machine_mode mode,
3612 HOST_WIDE_INT low, HOST_WIDE_INT high) 3364 HOST_WIDE_INT low, HOST_WIDE_INT high)
3613 { 3365 {
3614 HOST_WIDE_INT val; 3366 HOST_WIDE_INT val;
3615 unsigned char arr[16]; 3367 unsigned char arr[16];
3616 int bytes, i, j; 3368 int bytes, i, j;
3625 if (GET_MODE (op) != VOIDmode) 3377 if (GET_MODE (op) != VOIDmode)
3626 mode = GET_MODE (op); 3378 mode = GET_MODE (op);
3627 3379
3628 constant_to_array (mode, op, arr); 3380 constant_to_array (mode, op, arr);
3629 3381
3630 if (VECTOR_MODE_P (mode)) 3382 bytes = GET_MODE_UNIT_SIZE (mode);
3631 mode = GET_MODE_INNER (mode); 3383 mode = int_mode_for_mode (GET_MODE_INNER (mode)).require ();
3632
3633 bytes = GET_MODE_SIZE (mode);
3634 mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
3635 3384
3636 /* Check that bytes are repeated. */ 3385 /* Check that bytes are repeated. */
3637 for (i = bytes; i < 16; i += bytes) 3386 for (i = bytes; i < 16; i += bytes)
3638 for (j = 0; j < bytes; j++) 3387 for (j = 0; j < bytes; j++)
3639 if (arr[j] != arr[i + j]) 3388 if (arr[j] != arr[i + j])
3650 3399
3651 /* TRUE when op is an immediate and an exact power of 2, and given that 3400 /* TRUE when op is an immediate and an exact power of 2, and given that
3652 OP is 2^scale, scale >= LOW && scale <= HIGH. When OP is a vector, 3401 OP is 2^scale, scale >= LOW && scale <= HIGH. When OP is a vector,
3653 all entries must be the same. */ 3402 all entries must be the same. */
3654 bool 3403 bool
3655 exp2_immediate_p (rtx op, enum machine_mode mode, int low, int high) 3404 exp2_immediate_p (rtx op, machine_mode mode, int low, int high)
3656 { 3405 {
3657 enum machine_mode int_mode; 3406 machine_mode int_mode;
3658 HOST_WIDE_INT val; 3407 HOST_WIDE_INT val;
3659 unsigned char arr[16]; 3408 unsigned char arr[16];
3660 int bytes, i, j; 3409 int bytes, i, j;
3661 3410
3662 gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE 3411 gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
3669 if (GET_MODE (op) != VOIDmode) 3418 if (GET_MODE (op) != VOIDmode)
3670 mode = GET_MODE (op); 3419 mode = GET_MODE (op);
3671 3420
3672 constant_to_array (mode, op, arr); 3421 constant_to_array (mode, op, arr);
3673 3422
3674 if (VECTOR_MODE_P (mode)) 3423 mode = GET_MODE_INNER (mode);
3675 mode = GET_MODE_INNER (mode);
3676 3424
3677 bytes = GET_MODE_SIZE (mode); 3425 bytes = GET_MODE_SIZE (mode);
3678 int_mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0); 3426 int_mode = int_mode_for_mode (mode).require ();
3679 3427
3680 /* Check that bytes are repeated. */ 3428 /* Check that bytes are repeated. */
3681 for (i = bytes; i < 16; i += bytes) 3429 for (i = bytes; i < 16; i += bytes)
3682 for (j = 0; j < bytes; j++) 3430 for (j = 0; j < bytes; j++)
3683 if (arr[j] != arr[i + j]) 3431 if (arr[j] != arr[i + j])
3700 return FALSE; 3448 return FALSE;
3701 } 3449 }
3702 3450
3703 /* Return true if X is a SYMBOL_REF to an __ea qualified variable. */ 3451 /* Return true if X is a SYMBOL_REF to an __ea qualified variable. */
3704 3452
3705 static int 3453 static bool
3706 ea_symbol_ref (rtx *px, void *data ATTRIBUTE_UNUSED) 3454 ea_symbol_ref_p (const_rtx x)
3707 { 3455 {
3708 rtx x = *px;
3709 tree decl; 3456 tree decl;
3710 3457
3711 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) 3458 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
3712 { 3459 {
3713 rtx plus = XEXP (x, 0); 3460 rtx plus = XEXP (x, 0);
3727 - any 32-bit constant (SImode, SFmode) 3474 - any 32-bit constant (SImode, SFmode)
3728 - any constant that can be generated with fsmbi (any mode) 3475 - any constant that can be generated with fsmbi (any mode)
3729 - a 64-bit constant where the high and low bits are identical 3476 - a 64-bit constant where the high and low bits are identical
3730 (DImode, DFmode) 3477 (DImode, DFmode)
3731 - a 128-bit constant where the four 32-bit words match. */ 3478 - a 128-bit constant where the four 32-bit words match. */
3732 int 3479 bool
3733 spu_legitimate_constant_p (rtx x) 3480 spu_legitimate_constant_p (machine_mode mode, rtx x)
3734 { 3481 {
3482 subrtx_iterator::array_type array;
3735 if (GET_CODE (x) == HIGH) 3483 if (GET_CODE (x) == HIGH)
3736 x = XEXP (x, 0); 3484 x = XEXP (x, 0);
3737 3485
3738 /* Reject any __ea qualified reference. These can't appear in 3486 /* Reject any __ea qualified reference. These can't appear in
3739 instructions but must be forced to the constant pool. */ 3487 instructions but must be forced to the constant pool. */
3740 if (for_each_rtx (&x, ea_symbol_ref, 0)) 3488 FOR_EACH_SUBRTX (iter, array, x, ALL)
3741 return 0; 3489 if (ea_symbol_ref_p (*iter))
3490 return 0;
3742 3491
3743 /* V4SI with all identical symbols is valid. */ 3492 /* V4SI with all identical symbols is valid. */
3744 if (!flag_pic 3493 if (!flag_pic
3745 && GET_MODE (x) == V4SImode 3494 && mode == V4SImode
3746 && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF 3495 && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF
3747 || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF 3496 || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF
3748 || GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST)) 3497 || GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST))
3749 return CONST_VECTOR_ELT (x, 0) == CONST_VECTOR_ELT (x, 1) 3498 return const_vec_duplicate_p (x);
3750 && CONST_VECTOR_ELT (x, 1) == CONST_VECTOR_ELT (x, 2)
3751 && CONST_VECTOR_ELT (x, 2) == CONST_VECTOR_ELT (x, 3);
3752 3499
3753 if (GET_CODE (x) == CONST_VECTOR 3500 if (GET_CODE (x) == CONST_VECTOR
3754 && !const_vector_immediate_p (x)) 3501 && !const_vector_immediate_p (x))
3755 return 0; 3502 return 0;
3756 return 1; 3503 return 1;
3764 The alignment matters in the reg+const case because lqd and stqd 3511 The alignment matters in the reg+const case because lqd and stqd
3765 ignore the 4 least significant bits of the const. We only care about 3512 ignore the 4 least significant bits of the const. We only care about
3766 16 byte modes because the expand phase will change all smaller MEM 3513 16 byte modes because the expand phase will change all smaller MEM
3767 references to TImode. */ 3514 references to TImode. */
3768 static bool 3515 static bool
3769 spu_legitimate_address_p (enum machine_mode mode, 3516 spu_legitimate_address_p (machine_mode mode,
3770 rtx x, bool reg_ok_strict) 3517 rtx x, bool reg_ok_strict)
3771 { 3518 {
3772 int aligned = GET_MODE_SIZE (mode) >= 16; 3519 int aligned = GET_MODE_SIZE (mode) >= 16;
3773 if (aligned 3520 if (aligned
3774 && GET_CODE (x) == AND 3521 && GET_CODE (x) == AND
3782 3529
3783 case SYMBOL_REF: 3530 case SYMBOL_REF:
3784 case CONST: 3531 case CONST:
3785 /* Keep __ea references until reload so that spu_expand_mov can see them 3532 /* Keep __ea references until reload so that spu_expand_mov can see them
3786 in MEMs. */ 3533 in MEMs. */
3787 if (ea_symbol_ref (&x, 0)) 3534 if (ea_symbol_ref_p (x))
3788 return !reload_in_progress && !reload_completed; 3535 return !reload_in_progress && !reload_completed;
3789 return !TARGET_LARGE_MEM; 3536 return !TARGET_LARGE_MEM;
3790 3537
3791 case CONST_INT: 3538 case CONST_INT:
3792 return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff; 3539 return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff;
3793 3540
3794 case SUBREG: 3541 case SUBREG:
3795 x = XEXP (x, 0); 3542 x = XEXP (x, 0);
3796 if (REG_P (x)) 3543 if (!REG_P (x))
3797 return 0; 3544 return 0;
3545 /* FALLTHRU */
3798 3546
3799 case REG: 3547 case REG:
3800 return INT_REG_OK_FOR_BASE_P (x, reg_ok_strict); 3548 return INT_REG_OK_FOR_BASE_P (x, reg_ok_strict);
3801 3549
3802 case PLUS: 3550 case PLUS:
3809 if (GET_CODE (op1) == SUBREG) 3557 if (GET_CODE (op1) == SUBREG)
3810 op1 = XEXP (op1, 0); 3558 op1 = XEXP (op1, 0);
3811 if (GET_CODE (op0) == REG 3559 if (GET_CODE (op0) == REG
3812 && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) 3560 && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
3813 && GET_CODE (op1) == CONST_INT 3561 && GET_CODE (op1) == CONST_INT
3814 && INTVAL (op1) >= -0x2000 3562 && ((INTVAL (op1) >= -0x2000 && INTVAL (op1) <= 0x1fff)
3815 && INTVAL (op1) <= 0x1fff 3563 /* If virtual registers are involved, the displacement will
3564 change later on anyway, so checking would be premature.
3565 Reload will make sure the final displacement after
3566 register elimination is OK. */
3567 || op0 == arg_pointer_rtx
3568 || op0 == frame_pointer_rtx
3569 || op0 == virtual_stack_vars_rtx)
3816 && (!aligned || (INTVAL (op1) & 15) == 0)) 3570 && (!aligned || (INTVAL (op1) & 15) == 0))
3817 return TRUE; 3571 return TRUE;
3818 if (GET_CODE (op0) == REG 3572 if (GET_CODE (op0) == REG
3819 && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) 3573 && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
3820 && GET_CODE (op1) == REG 3574 && GET_CODE (op1) == REG
3829 return FALSE; 3583 return FALSE;
3830 } 3584 }
3831 3585
3832 /* Like spu_legitimate_address_p, except with named addresses. */ 3586 /* Like spu_legitimate_address_p, except with named addresses. */
3833 static bool 3587 static bool
3834 spu_addr_space_legitimate_address_p (enum machine_mode mode, rtx x, 3588 spu_addr_space_legitimate_address_p (machine_mode mode, rtx x,
3835 bool reg_ok_strict, addr_space_t as) 3589 bool reg_ok_strict, addr_space_t as)
3836 { 3590 {
3837 if (as == ADDR_SPACE_EA) 3591 if (as == ADDR_SPACE_EA)
3838 return (REG_P (x) && (GET_MODE (x) == EAmode)); 3592 return (REG_P (x) && (GET_MODE (x) == EAmode));
3839 3593
3843 return spu_legitimate_address_p (mode, x, reg_ok_strict); 3597 return spu_legitimate_address_p (mode, x, reg_ok_strict);
3844 } 3598 }
3845 3599
3846 /* When the address is reg + const_int, force the const_int into a 3600 /* When the address is reg + const_int, force the const_int into a
3847 register. */ 3601 register. */
3848 rtx 3602 static rtx
3849 spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, 3603 spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3850 enum machine_mode mode ATTRIBUTE_UNUSED) 3604 machine_mode mode ATTRIBUTE_UNUSED)
3851 { 3605 {
3852 rtx op0, op1; 3606 rtx op0, op1;
3853 /* Make sure both operands are registers. */ 3607 /* Make sure both operands are registers. */
3854 if (GET_CODE (x) == PLUS) 3608 if (GET_CODE (x) == PLUS)
3855 { 3609 {
3874 return x; 3628 return x;
3875 } 3629 }
3876 3630
3877 /* Like spu_legitimate_address, except with named address support. */ 3631 /* Like spu_legitimate_address, except with named address support. */
3878 static rtx 3632 static rtx
3879 spu_addr_space_legitimize_address (rtx x, rtx oldx, enum machine_mode mode, 3633 spu_addr_space_legitimize_address (rtx x, rtx oldx, machine_mode mode,
3880 addr_space_t as) 3634 addr_space_t as)
3881 { 3635 {
3882 if (as != ADDR_SPACE_GENERIC) 3636 if (as != ADDR_SPACE_GENERIC)
3883 return x; 3637 return x;
3884 3638
3885 return spu_legitimize_address (x, oldx, mode); 3639 return spu_legitimize_address (x, oldx, mode);
3640 }
3641
3642 /* Reload reg + const_int for out-of-range displacements. */
3643 rtx
3644 spu_legitimize_reload_address (rtx ad, machine_mode mode ATTRIBUTE_UNUSED,
3645 int opnum, int type)
3646 {
3647 bool removed_and = false;
3648
3649 if (GET_CODE (ad) == AND
3650 && CONST_INT_P (XEXP (ad, 1))
3651 && INTVAL (XEXP (ad, 1)) == (HOST_WIDE_INT) - 16)
3652 {
3653 ad = XEXP (ad, 0);
3654 removed_and = true;
3655 }
3656
3657 if (GET_CODE (ad) == PLUS
3658 && REG_P (XEXP (ad, 0))
3659 && CONST_INT_P (XEXP (ad, 1))
3660 && !(INTVAL (XEXP (ad, 1)) >= -0x2000
3661 && INTVAL (XEXP (ad, 1)) <= 0x1fff))
3662 {
3663 /* Unshare the sum. */
3664 ad = copy_rtx (ad);
3665
3666 /* Reload the displacement. */
3667 push_reload (XEXP (ad, 1), NULL_RTX, &XEXP (ad, 1), NULL,
3668 BASE_REG_CLASS, GET_MODE (ad), VOIDmode, 0, 0,
3669 opnum, (enum reload_type) type);
3670
3671 /* Add back AND for alignment if we stripped it. */
3672 if (removed_and)
3673 ad = gen_rtx_AND (GET_MODE (ad), ad, GEN_INT (-16));
3674
3675 return ad;
3676 }
3677
3678 return NULL_RTX;
3886 } 3679 }
3887 3680
3888 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in 3681 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3889 struct attribute_spec.handler. */ 3682 struct attribute_spec.handler. */
3890 static tree 3683 static tree
3908 spu_handle_vector_attribute (tree * node, tree name, 3701 spu_handle_vector_attribute (tree * node, tree name,
3909 tree args ATTRIBUTE_UNUSED, 3702 tree args ATTRIBUTE_UNUSED,
3910 int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) 3703 int flags ATTRIBUTE_UNUSED, bool * no_add_attrs)
3911 { 3704 {
3912 tree type = *node, result = NULL_TREE; 3705 tree type = *node, result = NULL_TREE;
3913 enum machine_mode mode; 3706 machine_mode mode;
3914 int unsigned_p; 3707 int unsigned_p;
3915 3708
3916 while (POINTER_TYPE_P (type) 3709 while (POINTER_TYPE_P (type)
3917 || TREE_CODE (type) == FUNCTION_TYPE 3710 || TREE_CODE (type) == FUNCTION_TYPE
3918 || TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == ARRAY_TYPE) 3711 || TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == ARRAY_TYPE)
3921 mode = TYPE_MODE (type); 3714 mode = TYPE_MODE (type);
3922 3715
3923 unsigned_p = TYPE_UNSIGNED (type); 3716 unsigned_p = TYPE_UNSIGNED (type);
3924 switch (mode) 3717 switch (mode)
3925 { 3718 {
3926 case DImode: 3719 case E_DImode:
3927 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); 3720 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
3928 break; 3721 break;
3929 case SImode: 3722 case E_SImode:
3930 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); 3723 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
3931 break; 3724 break;
3932 case HImode: 3725 case E_HImode:
3933 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node); 3726 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
3934 break; 3727 break;
3935 case QImode: 3728 case E_QImode:
3936 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); 3729 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
3937 break; 3730 break;
3938 case SFmode: 3731 case E_SFmode:
3939 result = V4SF_type_node; 3732 result = V4SF_type_node;
3940 break; 3733 break;
3941 case DFmode: 3734 case E_DFmode:
3942 result = V2DF_type_node; 3735 result = V2DF_type_node;
3943 break; 3736 break;
3944 default: 3737 default:
3945 break; 3738 break;
3946 } 3739 }
3976 int 3769 int
3977 spu_initial_elimination_offset (int from, int to) 3770 spu_initial_elimination_offset (int from, int to)
3978 { 3771 {
3979 int saved_regs_size = spu_saved_regs_size (); 3772 int saved_regs_size = spu_saved_regs_size ();
3980 int sp_offset = 0; 3773 int sp_offset = 0;
3981 if (!current_function_is_leaf || crtl->outgoing_args_size 3774 if (!crtl->is_leaf || crtl->outgoing_args_size
3982 || get_frame_size () || saved_regs_size) 3775 || get_frame_size () || saved_regs_size)
3983 sp_offset = STACK_POINTER_OFFSET; 3776 sp_offset = STACK_POINTER_OFFSET;
3984 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) 3777 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
3985 return get_frame_size () + crtl->outgoing_args_size + sp_offset; 3778 return get_frame_size () + crtl->outgoing_args_size + sp_offset;
3986 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) 3779 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
3995 } 3788 }
3996 3789
3997 rtx 3790 rtx
3998 spu_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED) 3791 spu_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED)
3999 { 3792 {
4000 enum machine_mode mode = TYPE_MODE (type); 3793 machine_mode mode = TYPE_MODE (type);
4001 int byte_size = ((mode == BLKmode) 3794 int byte_size = ((mode == BLKmode)
4002 ? int_size_in_bytes (type) : GET_MODE_SIZE (mode)); 3795 ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
4003 3796
4004 /* Make sure small structs are left justified in a register. */ 3797 /* Make sure small structs are left justified in a register. */
4005 if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type))) 3798 if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
4006 && byte_size <= UNITS_PER_WORD * MAX_REGISTER_RETURN && byte_size > 0) 3799 && byte_size <= UNITS_PER_WORD * MAX_REGISTER_RETURN && byte_size > 0)
4007 { 3800 {
4008 enum machine_mode smode; 3801 machine_mode smode;
4009 rtvec v; 3802 rtvec v;
4010 int i; 3803 int i;
4011 int nregs = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; 3804 int nregs = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4012 int n = byte_size / UNITS_PER_WORD; 3805 int n = byte_size / UNITS_PER_WORD;
4013 v = rtvec_alloc (nregs); 3806 v = rtvec_alloc (nregs);
4023 3816
4024 if (n < nregs) 3817 if (n < nregs)
4025 { 3818 {
4026 if (byte_size < 4) 3819 if (byte_size < 4)
4027 byte_size = 4; 3820 byte_size = 4;
4028 smode = 3821 smode = smallest_int_mode_for_size (byte_size * BITS_PER_UNIT);
4029 smallest_mode_for_size (byte_size * BITS_PER_UNIT, MODE_INT);
4030 RTVEC_ELT (v, n) = 3822 RTVEC_ELT (v, n) =
4031 gen_rtx_EXPR_LIST (VOIDmode, 3823 gen_rtx_EXPR_LIST (VOIDmode,
4032 gen_rtx_REG (smode, FIRST_RETURN_REGNUM + n), 3824 gen_rtx_REG (smode, FIRST_RETURN_REGNUM + n),
4033 GEN_INT (UNITS_PER_WORD * n)); 3825 GEN_INT (UNITS_PER_WORD * n));
4034 } 3826 }
4036 } 3828 }
4037 return gen_rtx_REG (mode, FIRST_RETURN_REGNUM); 3829 return gen_rtx_REG (mode, FIRST_RETURN_REGNUM);
4038 } 3830 }
4039 3831
4040 static rtx 3832 static rtx
4041 spu_function_arg (CUMULATIVE_ARGS *cum, 3833 spu_function_arg (cumulative_args_t cum_v,
4042 enum machine_mode mode, 3834 machine_mode mode,
4043 const_tree type, bool named ATTRIBUTE_UNUSED) 3835 const_tree type, bool named ATTRIBUTE_UNUSED)
4044 { 3836 {
3837 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4045 int byte_size; 3838 int byte_size;
4046 3839
4047 if (*cum >= MAX_REGISTER_ARGS) 3840 if (*cum >= MAX_REGISTER_ARGS)
4048 return 0; 3841 return 0;
4049 3842
4057 3850
4058 /* Make sure small structs are left justified in a register. */ 3851 /* Make sure small structs are left justified in a register. */
4059 if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type))) 3852 if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
4060 && byte_size < UNITS_PER_WORD && byte_size > 0) 3853 && byte_size < UNITS_PER_WORD && byte_size > 0)
4061 { 3854 {
4062 enum machine_mode smode; 3855 machine_mode smode;
4063 rtx gr_reg; 3856 rtx gr_reg;
4064 if (byte_size < 4) 3857 if (byte_size < 4)
4065 byte_size = 4; 3858 byte_size = 4;
4066 smode = smallest_mode_for_size (byte_size * BITS_PER_UNIT, MODE_INT); 3859 smode = smallest_int_mode_for_size (byte_size * BITS_PER_UNIT);
4067 gr_reg = gen_rtx_EXPR_LIST (VOIDmode, 3860 gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
4068 gen_rtx_REG (smode, FIRST_ARG_REGNUM + *cum), 3861 gen_rtx_REG (smode, FIRST_ARG_REGNUM + *cum),
4069 const0_rtx); 3862 const0_rtx);
4070 return gen_rtx_PARALLEL (mode, gen_rtvec (1, gr_reg)); 3863 return gen_rtx_PARALLEL (mode, gen_rtvec (1, gr_reg));
4071 } 3864 }
4072 else 3865 else
4073 return gen_rtx_REG (mode, FIRST_ARG_REGNUM + *cum); 3866 return gen_rtx_REG (mode, FIRST_ARG_REGNUM + *cum);
4074 } 3867 }
4075 3868
4076 static void 3869 static void
4077 spu_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, 3870 spu_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
4078 const_tree type, bool named ATTRIBUTE_UNUSED) 3871 const_tree type, bool named ATTRIBUTE_UNUSED)
4079 { 3872 {
3873 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3874
4080 *cum += (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST 3875 *cum += (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
4081 ? 1 3876 ? 1
4082 : mode == BLKmode 3877 : mode == BLKmode
4083 ? ((int_size_in_bytes (type) + 15) / 16) 3878 ? ((int_size_in_bytes (type) + 15) / 16)
4084 : mode == VOIDmode 3879 : mode == VOIDmode
4085 ? 1 3880 ? 1
4086 : HARD_REGNO_NREGS (cum, mode)); 3881 : spu_hard_regno_nregs (FIRST_ARG_REGNUM, mode));
3882 }
3883
3884 /* Implement TARGET_FUNCTION_ARG_OFFSET. The SPU ABI wants 32/64-bit
3885 types at offset 0 in the quad-word on the stack. 8/16-bit types
3886 should be at offsets 3/2 respectively. */
3887
3888 static HOST_WIDE_INT
3889 spu_function_arg_offset (machine_mode mode, const_tree type)
3890 {
3891 if (type && INTEGRAL_TYPE_P (type) && GET_MODE_SIZE (mode) < 4)
3892 return 4 - GET_MODE_SIZE (mode);
3893 return 0;
3894 }
3895
3896 /* Implement TARGET_FUNCTION_ARG_PADDING. */
3897
3898 static pad_direction
3899 spu_function_arg_padding (machine_mode, const_tree)
3900 {
3901 return PAD_UPWARD;
4087 } 3902 }
4088 3903
4089 /* Variable sized types are passed by reference. */ 3904 /* Variable sized types are passed by reference. */
4090 static bool 3905 static bool
4091 spu_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, 3906 spu_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
4092 enum machine_mode mode ATTRIBUTE_UNUSED, 3907 machine_mode mode ATTRIBUTE_UNUSED,
4093 const_tree type, bool named ATTRIBUTE_UNUSED) 3908 const_tree type, bool named ATTRIBUTE_UNUSED)
4094 { 3909 {
4095 return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; 3910 return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
4096 } 3911 }
4097 3912
4128 FIELD_DECL, get_identifier ("__args"), ptr_type_node); 3943 FIELD_DECL, get_identifier ("__args"), ptr_type_node);
4129 f_skip = build_decl (BUILTINS_LOCATION, 3944 f_skip = build_decl (BUILTINS_LOCATION,
4130 FIELD_DECL, get_identifier ("__skip"), ptr_type_node); 3945 FIELD_DECL, get_identifier ("__skip"), ptr_type_node);
4131 3946
4132 DECL_FIELD_CONTEXT (f_args) = record; 3947 DECL_FIELD_CONTEXT (f_args) = record;
4133 DECL_ALIGN (f_args) = 128; 3948 SET_DECL_ALIGN (f_args, 128);
4134 DECL_USER_ALIGN (f_args) = 1; 3949 DECL_USER_ALIGN (f_args) = 1;
4135 3950
4136 DECL_FIELD_CONTEXT (f_skip) = record; 3951 DECL_FIELD_CONTEXT (f_skip) = record;
4137 DECL_ALIGN (f_skip) = 128; 3952 SET_DECL_ALIGN (f_skip, 128);
4138 DECL_USER_ALIGN (f_skip) = 1; 3953 DECL_USER_ALIGN (f_skip) = 1;
4139 3954
4140 TYPE_STUB_DECL (record) = type_decl; 3955 TYPE_STUB_DECL (record) = type_decl;
4141 TYPE_NAME (record) = type_decl; 3956 TYPE_NAME (record) = type_decl;
4142 TYPE_FIELDS (record) = f_args; 3957 TYPE_FIELDS (record) = f_args;
4184 build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE); 3999 build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
4185 4000
4186 /* Find the __args area. */ 4001 /* Find the __args area. */
4187 t = make_tree (TREE_TYPE (args), nextarg); 4002 t = make_tree (TREE_TYPE (args), nextarg);
4188 if (crtl->args.pretend_args_size > 0) 4003 if (crtl->args.pretend_args_size > 0)
4189 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (args), t, 4004 t = fold_build_pointer_plus_hwi (t, -STACK_POINTER_OFFSET);
4190 size_int (-STACK_POINTER_OFFSET));
4191 t = build2 (MODIFY_EXPR, TREE_TYPE (args), args, t); 4005 t = build2 (MODIFY_EXPR, TREE_TYPE (args), args, t);
4192 TREE_SIDE_EFFECTS (t) = 1; 4006 TREE_SIDE_EFFECTS (t) = 1;
4193 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4007 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4194 4008
4195 /* Find the __skip area. */ 4009 /* Find the __skip area. */
4196 t = make_tree (TREE_TYPE (skip), virtual_incoming_args_rtx); 4010 t = make_tree (TREE_TYPE (skip), virtual_incoming_args_rtx);
4197 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (skip), t, 4011 t = fold_build_pointer_plus_hwi (t, (crtl->args.pretend_args_size
4198 size_int (crtl->args.pretend_args_size 4012 - STACK_POINTER_OFFSET));
4199 - STACK_POINTER_OFFSET));
4200 t = build2 (MODIFY_EXPR, TREE_TYPE (skip), skip, t); 4013 t = build2 (MODIFY_EXPR, TREE_TYPE (skip), skip, t);
4201 TREE_SIDE_EFFECTS (t) = 1; 4014 TREE_SIDE_EFFECTS (t) = 1;
4202 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 4015 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4203 } 4016 }
4204 4017
4224 gimple_seq * post_p ATTRIBUTE_UNUSED) 4037 gimple_seq * post_p ATTRIBUTE_UNUSED)
4225 { 4038 {
4226 tree f_args, f_skip; 4039 tree f_args, f_skip;
4227 tree args, skip; 4040 tree args, skip;
4228 HOST_WIDE_INT size, rsize; 4041 HOST_WIDE_INT size, rsize;
4229 tree paddedsize, addr, tmp; 4042 tree addr, tmp;
4230 bool pass_by_reference_p; 4043 bool pass_by_reference_p;
4231 4044
4232 f_args = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); 4045 f_args = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
4233 f_skip = DECL_CHAIN (f_args); 4046 f_skip = DECL_CHAIN (f_args);
4234 4047
4235 valist = build_simple_mem_ref (valist);
4236 args = 4048 args =
4237 build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE); 4049 build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE);
4238 skip = 4050 skip =
4239 build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE); 4051 build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
4240 4052
4241 addr = create_tmp_var (ptr_type_node, "va_arg"); 4053 addr = create_tmp_var (ptr_type_node, "va_arg");
4242 4054
4243 /* if an object is dynamically sized, a pointer to it is passed 4055 /* if an object is dynamically sized, a pointer to it is passed
4244 instead of the object itself. */ 4056 instead of the object itself. */
4245 pass_by_reference_p = spu_pass_by_reference (NULL, TYPE_MODE (type), type, 4057 pass_by_reference_p = pass_by_reference (NULL, TYPE_MODE (type), type,
4246 false); 4058 false);
4247 if (pass_by_reference_p) 4059 if (pass_by_reference_p)
4248 type = build_pointer_type (type); 4060 type = build_pointer_type (type);
4249 size = int_size_in_bytes (type); 4061 size = int_size_in_bytes (type);
4250 rsize = ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD) * UNITS_PER_WORD; 4062 rsize = ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD) * UNITS_PER_WORD;
4251 4063
4252 /* build conditional expression to calculate addr. The expression 4064 /* build conditional expression to calculate addr. The expression
4253 will be gimplified later. */ 4065 will be gimplified later. */
4254 paddedsize = size_int (rsize); 4066 tmp = fold_build_pointer_plus_hwi (unshare_expr (args), rsize);
4255 tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (args), paddedsize);
4256 tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, 4067 tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
4257 build2 (GT_EXPR, boolean_type_node, tmp, unshare_expr (skip)), 4068 build2 (GT_EXPR, boolean_type_node, tmp, unshare_expr (skip)),
4258 build2 (LE_EXPR, boolean_type_node, unshare_expr (args), 4069 build2 (LE_EXPR, boolean_type_node, unshare_expr (args),
4259 unshare_expr (skip))); 4070 unshare_expr (skip)));
4260 4071
4261 tmp = build3 (COND_EXPR, ptr_type_node, tmp, 4072 tmp = build3 (COND_EXPR, ptr_type_node, tmp,
4262 build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (skip), 4073 fold_build_pointer_plus_hwi (unshare_expr (skip), 32),
4263 size_int (32)), unshare_expr (args)); 4074 unshare_expr (args));
4264 4075
4265 gimplify_assign (addr, tmp, pre_p); 4076 gimplify_assign (addr, tmp, pre_p);
4266 4077
4267 /* update VALIST.__args */ 4078 /* update VALIST.__args */
4268 tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, paddedsize); 4079 tmp = fold_build_pointer_plus_hwi (addr, rsize);
4269 gimplify_assign (unshare_expr (args), tmp, pre_p); 4080 gimplify_assign (unshare_expr (args), tmp, pre_p);
4270 4081
4271 addr = fold_convert (build_pointer_type_for_mode (type, ptr_mode, true), 4082 addr = fold_convert (build_pointer_type_for_mode (type, ptr_mode, true),
4272 addr); 4083 addr);
4273 4084
4279 4090
4280 /* Save parameter registers starting with the register that corresponds 4091 /* Save parameter registers starting with the register that corresponds
4281 to the first unnamed parameters. If the first unnamed parameter is 4092 to the first unnamed parameters. If the first unnamed parameter is
4282 in the stack then save no registers. Set pretend_args_size to the 4093 in the stack then save no registers. Set pretend_args_size to the
4283 amount of space needed to save the registers. */ 4094 amount of space needed to save the registers. */
4284 void 4095 static void
4285 spu_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode, 4096 spu_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
4286 tree type, int *pretend_size, int no_rtl) 4097 tree type, int *pretend_size, int no_rtl)
4287 { 4098 {
4288 if (!no_rtl) 4099 if (!no_rtl)
4289 { 4100 {
4290 rtx tmp; 4101 rtx tmp;
4291 int regno; 4102 int regno;
4292 int offset; 4103 int offset;
4293 int ncum = *cum; 4104 int ncum = *get_cumulative_args (cum);
4294 4105
4295 /* cum currently points to the last named argument, we want to 4106 /* cum currently points to the last named argument, we want to
4296 start at the next argument. */ 4107 start at the next argument. */
4297 spu_function_arg_advance (&ncum, mode, type, true); 4108 spu_function_arg_advance (pack_cumulative_args (&ncum), mode, type, true);
4298 4109
4299 offset = -STACK_POINTER_OFFSET; 4110 offset = -STACK_POINTER_OFFSET;
4300 for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++) 4111 for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++)
4301 { 4112 {
4302 tmp = gen_frame_mem (V4SImode, 4113 tmp = gen_frame_mem (V4SImode,
4303 plus_constant (virtual_incoming_args_rtx, 4114 plus_constant (Pmode, virtual_incoming_args_rtx,
4304 offset)); 4115 offset));
4305 emit_move_insn (tmp, 4116 emit_move_insn (tmp,
4306 gen_rtx_REG (V4SImode, FIRST_ARG_REGNUM + regno)); 4117 gen_rtx_REG (V4SImode, FIRST_ARG_REGNUM + regno));
4307 offset += 16; 4118 offset += 16;
4308 } 4119 }
4346 4157
4347 /* Return TRUE if we are certain the mem refers to a complete object 4158 /* Return TRUE if we are certain the mem refers to a complete object
4348 which is both 16-byte aligned and padded to a 16-byte boundary. This 4159 which is both 16-byte aligned and padded to a 16-byte boundary. This
4349 would make it safe to store with a single instruction. 4160 would make it safe to store with a single instruction.
4350 We guarantee the alignment and padding for static objects by aligning 4161 We guarantee the alignment and padding for static objects by aligning
4351 all of them to 16-bytes. (DATA_ALIGNMENT and CONSTANT_ALIGNMENT.) 4162 all of them to 16-bytes. (DATA_ALIGNMENT and TARGET_CONSTANT_ALIGNMENT.)
4352 FIXME: We currently cannot guarantee this for objects on the stack 4163 FIXME: We currently cannot guarantee this for objects on the stack
4353 because assign_parm_setup_stack calls assign_stack_local with the 4164 because assign_parm_setup_stack calls assign_stack_local with the
4354 alignment of the parameter mode and in that case the alignment never 4165 alignment of the parameter mode and in that case the alignment never
4355 gets adjusted by LOCAL_ALIGNMENT. */ 4166 gets adjusted by LOCAL_ALIGNMENT. */
4356 static int 4167 static int
4357 store_with_one_insn_p (rtx mem) 4168 store_with_one_insn_p (rtx mem)
4358 { 4169 {
4359 enum machine_mode mode = GET_MODE (mem); 4170 machine_mode mode = GET_MODE (mem);
4360 rtx addr = XEXP (mem, 0); 4171 rtx addr = XEXP (mem, 0);
4361 if (mode == BLKmode) 4172 if (mode == BLKmode)
4362 return 0; 4173 return 0;
4363 if (GET_MODE_SIZE (mode) >= 16) 4174 if (GET_MODE_SIZE (mode) >= 16)
4364 return 1; 4175 return 1;
4365 /* Only static objects. */ 4176 /* Only static objects. */
4366 if (GET_CODE (addr) == SYMBOL_REF) 4177 if (GET_CODE (addr) == SYMBOL_REF)
4367 { 4178 {
4368 /* We use the associated declaration to make sure the access is 4179 /* We use the associated declaration to make sure the access is
4369 referring to the whole object. 4180 referring to the whole object.
4370 We check both MEM_EXPR and and SYMBOL_REF_DECL. I'm not sure 4181 We check both MEM_EXPR and SYMBOL_REF_DECL. I'm not sure
4371 if it is necessary. Will there be cases where one exists, and 4182 if it is necessary. Will there be cases where one exists, and
4372 the other does not? Will there be cases where both exist, but 4183 the other does not? Will there be cases where both exist, but
4373 have different types? */ 4184 have different types? */
4374 tree decl = MEM_EXPR (mem); 4185 tree decl = MEM_EXPR (mem);
4375 if (decl 4186 if (decl
4416 { 4227 {
4417 rtx ndirty = GEN_INT (GET_MODE_SIZE (GET_MODE (mem))); 4228 rtx ndirty = GEN_INT (GET_MODE_SIZE (GET_MODE (mem)));
4418 if (!cache_fetch_dirty) 4229 if (!cache_fetch_dirty)
4419 cache_fetch_dirty = init_one_libfunc ("__cache_fetch_dirty"); 4230 cache_fetch_dirty = init_one_libfunc ("__cache_fetch_dirty");
4420 emit_library_call_value (cache_fetch_dirty, data_addr, LCT_NORMAL, Pmode, 4231 emit_library_call_value (cache_fetch_dirty, data_addr, LCT_NORMAL, Pmode,
4421 2, ea_addr, EAmode, ndirty, SImode); 4232 ea_addr, EAmode, ndirty, SImode);
4422 } 4233 }
4423 else 4234 else
4424 { 4235 {
4425 if (!cache_fetch) 4236 if (!cache_fetch)
4426 cache_fetch = init_one_libfunc ("__cache_fetch"); 4237 cache_fetch = init_one_libfunc ("__cache_fetch");
4427 emit_library_call_value (cache_fetch, data_addr, LCT_NORMAL, Pmode, 4238 emit_library_call_value (cache_fetch, data_addr, LCT_NORMAL, Pmode,
4428 1, ea_addr, EAmode); 4239 ea_addr, EAmode);
4429 } 4240 }
4430 } 4241 }
4431 4242
4432 /* Like ea_load_store, but do the cache tag comparison and, for stores, 4243 /* Like ea_load_store, but do the cache tag comparison and, for stores,
4433 dirty bit marking, inline. 4244 dirty bit marking, inline.
4466 rtx tag_equal = gen_reg_rtx (V4SImode); 4277 rtx tag_equal = gen_reg_rtx (V4SImode);
4467 rtx tag_equal_hi = NULL_RTX; 4278 rtx tag_equal_hi = NULL_RTX;
4468 rtx tag_eq_pack = gen_reg_rtx (V4SImode); 4279 rtx tag_eq_pack = gen_reg_rtx (V4SImode);
4469 rtx tag_eq_pack_si = gen_reg_rtx (SImode); 4280 rtx tag_eq_pack_si = gen_reg_rtx (SImode);
4470 rtx eq_index = gen_reg_rtx (SImode); 4281 rtx eq_index = gen_reg_rtx (SImode);
4471 rtx bcomp, hit_label, hit_ref, cont_label, insn; 4282 rtx bcomp, hit_label, hit_ref, cont_label;
4283 rtx_insn *insn;
4472 4284
4473 if (spu_ea_model != 32) 4285 if (spu_ea_model != 32)
4474 { 4286 {
4475 splat_hi = gen_reg_rtx (V4SImode); 4287 splat_hi = gen_reg_rtx (V4SImode);
4476 cache_tag_hi = gen_reg_rtx (V4SImode); 4288 cache_tag_hi = gen_reg_rtx (V4SImode);
4477 tag_equal_hi = gen_reg_rtx (V4SImode); 4289 tag_equal_hi = gen_reg_rtx (V4SImode);
4478 } 4290 }
4479 4291
4480 emit_move_insn (index_mask, plus_constant (tag_size_sym, -128)); 4292 emit_move_insn (index_mask, plus_constant (Pmode, tag_size_sym, -128));
4481 emit_move_insn (tag_arr, tag_arr_sym); 4293 emit_move_insn (tag_arr, tag_arr_sym);
4482 v = 0x0001020300010203LL; 4294 v = 0x0001020300010203LL;
4483 emit_move_insn (splat_mask, immed_double_const (v, v, TImode)); 4295 emit_move_insn (splat_mask, immed_double_const (v, v, TImode));
4484 ea_addr_si = ea_addr; 4296 ea_addr_si = ea_addr;
4485 if (spu_ea_model != 32) 4297 if (spu_ea_model != 32)
4502 4314
4503 /* Read cache tags. */ 4315 /* Read cache tags. */
4504 emit_move_insn (cache_tag, gen_rtx_MEM (V4SImode, tag_addr)); 4316 emit_move_insn (cache_tag, gen_rtx_MEM (V4SImode, tag_addr));
4505 if (spu_ea_model != 32) 4317 if (spu_ea_model != 32)
4506 emit_move_insn (cache_tag_hi, gen_rtx_MEM (V4SImode, 4318 emit_move_insn (cache_tag_hi, gen_rtx_MEM (V4SImode,
4507 plus_constant (tag_addr, 16))); 4319 plus_constant (Pmode,
4320 tag_addr, 16)));
4508 4321
4509 /* tag = ea_addr & -128 */ 4322 /* tag = ea_addr & -128 */
4510 emit_insn (gen_andv4si3 (tag, splat, spu_const (V4SImode, -128))); 4323 emit_insn (gen_andv4si3 (tag, splat, spu_const (V4SImode, -128)));
4511 4324
4512 /* Read all four cache data pointers. */ 4325 /* Read all four cache data pointers. */
4513 emit_move_insn (cache_ptrs, gen_rtx_MEM (TImode, 4326 emit_move_insn (cache_ptrs, gen_rtx_MEM (TImode,
4514 plus_constant (tag_addr, 32))); 4327 plus_constant (Pmode,
4328 tag_addr, 32)));
4515 4329
4516 /* Compare tags. */ 4330 /* Compare tags. */
4517 emit_insn (gen_ceq_v4si (tag_equal, tag, cache_tag)); 4331 emit_insn (gen_ceq_v4si (tag_equal, tag, cache_tag));
4518 if (spu_ea_model != 32) 4332 if (spu_ea_model != 32)
4519 { 4333 {
4542 4356
4543 /* Check that we did hit. */ 4357 /* Check that we did hit. */
4544 hit_label = gen_label_rtx (); 4358 hit_label = gen_label_rtx ();
4545 hit_ref = gen_rtx_LABEL_REF (VOIDmode, hit_label); 4359 hit_ref = gen_rtx_LABEL_REF (VOIDmode, hit_label);
4546 bcomp = gen_rtx_NE (SImode, tag_eq_pack_si, const0_rtx); 4360 bcomp = gen_rtx_NE (SImode, tag_eq_pack_si, const0_rtx);
4547 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 4361 insn = emit_jump_insn (gen_rtx_SET (pc_rtx,
4548 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, 4362 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4549 hit_ref, pc_rtx))); 4363 hit_ref, pc_rtx)));
4550 /* Say that this branch is very likely to happen. */ 4364 /* Say that this branch is very likely to happen. */
4551 v = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100 - 1; 4365 add_reg_br_prob_note (insn, profile_probability::very_likely ());
4552 add_reg_note (insn, REG_BR_PROB, GEN_INT (v));
4553 4366
4554 ea_load_store (mem, is_store, ea_addr, data_addr); 4367 ea_load_store (mem, is_store, ea_addr, data_addr);
4555 cont_label = gen_label_rtx (); 4368 cont_label = gen_label_rtx ();
4556 emit_jump_insn (gen_jump (cont_label)); 4369 emit_jump_insn (gen_jump (cont_label));
4557 emit_barrier (); 4370 emit_barrier ();
4626 4439
4627 return new_mem; 4440 return new_mem;
4628 } 4441 }
4629 4442
4630 int 4443 int
4631 spu_expand_mov (rtx * ops, enum machine_mode mode) 4444 spu_expand_mov (rtx * ops, machine_mode mode)
4632 { 4445 {
4633 if (GET_CODE (ops[0]) == SUBREG && !valid_subreg (ops[0])) 4446 if (GET_CODE (ops[0]) == SUBREG && !valid_subreg (ops[0]))
4634 { 4447 {
4635 /* Perform the move in the destination SUBREG's inner mode. */ 4448 /* Perform the move in the destination SUBREG's inner mode. */
4636 ops[0] = SUBREG_REG (ops[0]); 4449 ops[0] = SUBREG_REG (ops[0]);
4640 } 4453 }
4641 4454
4642 if (GET_CODE (ops[1]) == SUBREG && !valid_subreg (ops[1])) 4455 if (GET_CODE (ops[1]) == SUBREG && !valid_subreg (ops[1]))
4643 { 4456 {
4644 rtx from = SUBREG_REG (ops[1]); 4457 rtx from = SUBREG_REG (ops[1]);
4645 enum machine_mode imode = int_mode_for_mode (GET_MODE (from)); 4458 scalar_int_mode imode = int_mode_for_mode (GET_MODE (from)).require ();
4646 4459
4647 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT 4460 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
4648 && GET_MODE_CLASS (imode) == MODE_INT 4461 && GET_MODE_CLASS (imode) == MODE_INT
4649 && subreg_lowpart_p (ops[1])); 4462 && subreg_lowpart_p (ops[1]));
4650 4463
4707 } 4520 }
4708 4521
4709 static void 4522 static void
4710 spu_convert_move (rtx dst, rtx src) 4523 spu_convert_move (rtx dst, rtx src)
4711 { 4524 {
4712 enum machine_mode mode = GET_MODE (dst); 4525 machine_mode mode = GET_MODE (dst);
4713 enum machine_mode int_mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0); 4526 machine_mode int_mode = int_mode_for_mode (mode).require ();
4714 rtx reg; 4527 rtx reg;
4715 gcc_assert (GET_MODE (src) == TImode); 4528 gcc_assert (GET_MODE (src) == TImode);
4716 reg = int_mode != mode ? gen_reg_rtx (int_mode) : dst; 4529 reg = int_mode != mode ? gen_reg_rtx (int_mode) : dst;
4717 emit_insn (gen_rtx_SET (VOIDmode, reg, 4530 emit_insn (gen_rtx_SET (reg,
4718 gen_rtx_TRUNCATE (int_mode, 4531 gen_rtx_TRUNCATE (int_mode,
4719 gen_rtx_LSHIFTRT (TImode, src, 4532 gen_rtx_LSHIFTRT (TImode, src,
4720 GEN_INT (int_mode == DImode ? 64 : 96))))); 4533 GEN_INT (int_mode == DImode ? 64 : 96)))));
4721 if (int_mode != mode) 4534 if (int_mode != mode)
4722 { 4535 {
4860 addr0 = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16)); 4673 addr0 = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16));
4861 emit_insn (gen__movti (dst0, change_address (src, TImode, addr0))); 4674 emit_insn (gen__movti (dst0, change_address (src, TImode, addr0)));
4862 4675
4863 if (dst1) 4676 if (dst1)
4864 { 4677 {
4865 addr1 = plus_constant (copy_rtx (addr), 16); 4678 addr1 = plus_constant (SImode, copy_rtx (addr), 16);
4866 addr1 = gen_rtx_AND (SImode, addr1, GEN_INT (-16)); 4679 addr1 = gen_rtx_AND (SImode, addr1, GEN_INT (-16));
4867 emit_insn (gen__movti (dst1, change_address (src, TImode, addr1))); 4680 emit_insn (gen__movti (dst1, change_address (src, TImode, addr1)));
4868 } 4681 }
4869 4682
4870 return rot; 4683 return rot;
4871 } 4684 }
4872 4685
4873 int 4686 int
4874 spu_split_load (rtx * ops) 4687 spu_split_load (rtx * ops)
4875 { 4688 {
4876 enum machine_mode mode = GET_MODE (ops[0]); 4689 machine_mode mode = GET_MODE (ops[0]);
4877 rtx addr, load, rot; 4690 rtx addr, load, rot;
4878 int rot_amt; 4691 int rot_amt;
4879 4692
4880 if (GET_MODE_SIZE (mode) >= 16) 4693 if (GET_MODE_SIZE (mode) >= 16)
4881 return 0; 4694 return 0;
4905 } 4718 }
4906 4719
4907 int 4720 int
4908 spu_split_store (rtx * ops) 4721 spu_split_store (rtx * ops)
4909 { 4722 {
4910 enum machine_mode mode = GET_MODE (ops[0]); 4723 machine_mode mode = GET_MODE (ops[0]);
4911 rtx reg; 4724 rtx reg;
4912 rtx addr, p0, p1, p1_lo, smem; 4725 rtx addr, p0, p1, p1_lo, smem;
4913 int aform; 4726 int aform;
4914 int scalar; 4727 int scalar;
4915 4728
5162 } 4975 }
5163 4976
5164 /* Return TRUE if x is a CONST_INT, CONST_DOUBLE or CONST_VECTOR that 4977 /* Return TRUE if x is a CONST_INT, CONST_DOUBLE or CONST_VECTOR that
5165 can be generated using the cbd, chd, cwd or cdd instruction. */ 4978 can be generated using the cbd, chd, cwd or cdd instruction. */
5166 int 4979 int
5167 cpat_const_p (rtx x, enum machine_mode mode) 4980 cpat_const_p (rtx x, machine_mode mode)
5168 { 4981 {
5169 if (CONSTANT_P (x)) 4982 if (CONSTANT_P (x))
5170 { 4983 {
5171 enum immediate_class c = classify_immediate (x, mode); 4984 enum immediate_class c = classify_immediate (x, mode);
5172 return c == IC_CPAT; 4985 return c == IC_CPAT;
5208 5021
5209 /* Convert a CONST_INT, CONST_DOUBLE, or CONST_VECTOR into a 16 byte 5022 /* Convert a CONST_INT, CONST_DOUBLE, or CONST_VECTOR into a 16 byte
5210 array. Use MODE for CONST_INT's. When the constant's mode is smaller 5023 array. Use MODE for CONST_INT's. When the constant's mode is smaller
5211 than 16 bytes, the value is repeated across the rest of the array. */ 5024 than 16 bytes, the value is repeated across the rest of the array. */
5212 void 5025 void
5213 constant_to_array (enum machine_mode mode, rtx x, unsigned char arr[16]) 5026 constant_to_array (machine_mode mode, rtx x, unsigned char arr[16])
5214 { 5027 {
5215 HOST_WIDE_INT val; 5028 HOST_WIDE_INT val;
5216 int i, j, first; 5029 int i, j, first;
5217 5030
5218 memset (arr, 0, 16); 5031 memset (arr, 0, 16);
5287 5100
5288 /* Convert a 16 byte array to a constant of mode MODE. When MODE is 5101 /* Convert a 16 byte array to a constant of mode MODE. When MODE is
5289 smaller than 16 bytes, use the bytes that would represent that value 5102 smaller than 16 bytes, use the bytes that would represent that value
5290 in a register, e.g., for QImode return the value of arr[3]. */ 5103 in a register, e.g., for QImode return the value of arr[3]. */
5291 rtx 5104 rtx
5292 array_to_constant (enum machine_mode mode, const unsigned char arr[16]) 5105 array_to_constant (machine_mode mode, const unsigned char arr[16])
5293 { 5106 {
5294 enum machine_mode inner_mode; 5107 machine_mode inner_mode;
5295 rtvec v; 5108 rtvec v;
5296 int units, size, i, j, k; 5109 int units, size, i, j, k;
5297 HOST_WIDE_INT val; 5110 HOST_WIDE_INT val;
5298 5111
5299 if (GET_MODE_CLASS (mode) == MODE_INT 5112 if (GET_MODE_CLASS (mode) == MODE_INT
5421 assemble_name (file, name); 5234 assemble_name (file, name);
5422 fputs ("\n", file); 5235 fputs ("\n", file);
5423 } 5236 }
5424 5237
5425 static bool 5238 static bool
5426 spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total, 5239 spu_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
5240 int opno ATTRIBUTE_UNUSED, int *total,
5427 bool speed ATTRIBUTE_UNUSED) 5241 bool speed ATTRIBUTE_UNUSED)
5428 { 5242 {
5429 enum machine_mode mode = GET_MODE (x); 5243 int code = GET_CODE (x);
5430 int cost = COSTS_N_INSNS (2); 5244 int cost = COSTS_N_INSNS (2);
5431 5245
5432 /* Folding to a CONST_VECTOR will use extra space but there might 5246 /* Folding to a CONST_VECTOR will use extra space but there might
5433 be only a small savings in cycles. We'd like to use a CONST_VECTOR 5247 be only a small savings in cycles. We'd like to use a CONST_VECTOR
5434 only if it allows us to fold away multiple insns. Changing the cost 5248 only if it allows us to fold away multiple insns. Changing the cost
5435 of a CONST_VECTOR here (or in CONST_COSTS) doesn't help though 5249 of a CONST_VECTOR here (or in CONST_COSTS) doesn't help though
5436 because this cost will only be compared against a single insn. 5250 because this cost will only be compared against a single insn.
5437 if (code == CONST_VECTOR) 5251 if (code == CONST_VECTOR)
5438 return (LEGITIMATE_CONSTANT_P(x)) ? cost : COSTS_N_INSNS(6); 5252 return spu_legitimate_constant_p (mode, x) ? cost : COSTS_N_INSNS (6);
5439 */ 5253 */
5440 5254
5441 /* Use defaults for float operations. Not accurate but good enough. */ 5255 /* Use defaults for float operations. Not accurate but good enough. */
5442 if (mode == DFmode) 5256 if (mode == DFmode)
5443 { 5257 {
5535 * (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); 5349 * (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
5536 *total = cost; 5350 *total = cost;
5537 return true; 5351 return true;
5538 } 5352 }
5539 5353
5540 static enum machine_mode 5354 static scalar_int_mode
5541 spu_unwind_word_mode (void) 5355 spu_unwind_word_mode (void)
5542 { 5356 {
5543 return SImode; 5357 return SImode;
5544 } 5358 }
5545 5359
5574 emit_insn (gen_shufb (splatted, op1, op1, pat)); 5388 emit_insn (gen_shufb (splatted, op1, op1, pat));
5575 5389
5576 emit_insn (gen_spu_convert (sp, stack_pointer_rtx)); 5390 emit_insn (gen_spu_convert (sp, stack_pointer_rtx));
5577 emit_insn (gen_subv4si3 (sp, sp, splatted)); 5391 emit_insn (gen_subv4si3 (sp, sp, splatted));
5578 5392
5579 if (flag_stack_check) 5393 if (flag_stack_check || flag_stack_clash_protection)
5580 { 5394 {
5581 rtx avail = gen_reg_rtx(SImode); 5395 rtx avail = gen_reg_rtx(SImode);
5582 rtx result = gen_reg_rtx(SImode); 5396 rtx result = gen_reg_rtx(SImode);
5583 emit_insn (gen_vec_extractv4si (avail, sp, GEN_INT (1))); 5397 emit_insn (gen_vec_extractv4sisi (avail, sp, GEN_INT (1)));
5584 emit_insn (gen_cgt_si(result, avail, GEN_INT (-1))); 5398 emit_insn (gen_cgt_si(result, avail, GEN_INT (-1)));
5585 emit_insn (gen_spu_heq (result, GEN_INT(0) )); 5399 emit_insn (gen_spu_heq (result, GEN_INT(0) ));
5586 } 5400 }
5587 5401
5588 emit_insn (gen_spu_convert (stack_pointer_rtx, sp)); 5402 emit_insn (gen_spu_convert (stack_pointer_rtx, sp));
5633 set_optab_libfunc (umod_optab, DImode, "__umoddi3"); 5447 set_optab_libfunc (umod_optab, DImode, "__umoddi3");
5634 set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4"); 5448 set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
5635 set_optab_libfunc (ffs_optab, DImode, "__ffsdi2"); 5449 set_optab_libfunc (ffs_optab, DImode, "__ffsdi2");
5636 set_optab_libfunc (clz_optab, DImode, "__clzdi2"); 5450 set_optab_libfunc (clz_optab, DImode, "__clzdi2");
5637 set_optab_libfunc (ctz_optab, DImode, "__ctzdi2"); 5451 set_optab_libfunc (ctz_optab, DImode, "__ctzdi2");
5452 set_optab_libfunc (clrsb_optab, DImode, "__clrsbdi2");
5638 set_optab_libfunc (popcount_optab, DImode, "__popcountdi2"); 5453 set_optab_libfunc (popcount_optab, DImode, "__popcountdi2");
5639 set_optab_libfunc (parity_optab, DImode, "__paritydi2"); 5454 set_optab_libfunc (parity_optab, DImode, "__paritydi2");
5640 5455
5641 set_conv_libfunc (ufloat_optab, DFmode, SImode, "__float_unssidf"); 5456 set_conv_libfunc (ufloat_optab, DFmode, SImode, "__float_unssidf");
5642 set_conv_libfunc (ufloat_optab, DFmode, DImode, "__float_unsdidf"); 5457 set_conv_libfunc (ufloat_optab, DFmode, DImode, "__float_unsdidf");
5663 } 5478 }
5664 5479
5665 /* Make a subreg, stripping any existing subreg. We could possibly just 5480 /* Make a subreg, stripping any existing subreg. We could possibly just
5666 call simplify_subreg, but in this case we know what we want. */ 5481 call simplify_subreg, but in this case we know what we want. */
5667 rtx 5482 rtx
5668 spu_gen_subreg (enum machine_mode mode, rtx x) 5483 spu_gen_subreg (machine_mode mode, rtx x)
5669 { 5484 {
5670 if (GET_CODE (x) == SUBREG) 5485 if (GET_CODE (x) == SUBREG)
5671 x = SUBREG_REG (x); 5486 x = SUBREG_REG (x);
5672 if (GET_MODE (x) == mode) 5487 if (GET_MODE (x) == mode)
5673 return x; 5488 return x;
5834 } 5649 }
5835 5650
5836 void 5651 void
5837 spu_builtin_splats (rtx ops[]) 5652 spu_builtin_splats (rtx ops[])
5838 { 5653 {
5839 enum machine_mode mode = GET_MODE (ops[0]); 5654 machine_mode mode = GET_MODE (ops[0]);
5840 if (GET_CODE (ops[1]) == CONST_INT || GET_CODE (ops[1]) == CONST_DOUBLE) 5655 if (GET_CODE (ops[1]) == CONST_INT || GET_CODE (ops[1]) == CONST_DOUBLE)
5841 { 5656 {
5842 unsigned char arr[16]; 5657 unsigned char arr[16];
5843 constant_to_array (GET_MODE_INNER (mode), ops[1], arr); 5658 constant_to_array (GET_MODE_INNER (mode), ops[1], arr);
5844 emit_move_insn (ops[0], array_to_constant (mode, arr)); 5659 emit_move_insn (ops[0], array_to_constant (mode, arr));
5850 if (GET_CODE (ops[1]) != REG 5665 if (GET_CODE (ops[1]) != REG
5851 && GET_CODE (ops[1]) != SUBREG) 5666 && GET_CODE (ops[1]) != SUBREG)
5852 ops[1] = force_reg (GET_MODE_INNER (mode), ops[1]); 5667 ops[1] = force_reg (GET_MODE_INNER (mode), ops[1]);
5853 switch (mode) 5668 switch (mode)
5854 { 5669 {
5855 case V2DImode: 5670 case E_V2DImode:
5856 case V2DFmode: 5671 case E_V2DFmode:
5857 shuf = 5672 shuf =
5858 immed_double_const (0x0001020304050607ll, 0x1011121314151617ll, 5673 immed_double_const (0x0001020304050607ll, 0x1011121314151617ll,
5859 TImode); 5674 TImode);
5860 break; 5675 break;
5861 case V4SImode: 5676 case E_V4SImode:
5862 case V4SFmode: 5677 case E_V4SFmode:
5863 shuf = 5678 shuf =
5864 immed_double_const (0x0001020300010203ll, 0x0001020300010203ll, 5679 immed_double_const (0x0001020300010203ll, 0x0001020300010203ll,
5865 TImode); 5680 TImode);
5866 break; 5681 break;
5867 case V8HImode: 5682 case E_V8HImode:
5868 shuf = 5683 shuf =
5869 immed_double_const (0x0203020302030203ll, 0x0203020302030203ll, 5684 immed_double_const (0x0203020302030203ll, 0x0203020302030203ll,
5870 TImode); 5685 TImode);
5871 break; 5686 break;
5872 case V16QImode: 5687 case E_V16QImode:
5873 shuf = 5688 shuf =
5874 immed_double_const (0x0303030303030303ll, 0x0303030303030303ll, 5689 immed_double_const (0x0303030303030303ll, 0x0303030303030303ll,
5875 TImode); 5690 TImode);
5876 break; 5691 break;
5877 default: 5692 default:
5883 } 5698 }
5884 5699
5885 void 5700 void
5886 spu_builtin_extract (rtx ops[]) 5701 spu_builtin_extract (rtx ops[])
5887 { 5702 {
5888 enum machine_mode mode; 5703 machine_mode mode;
5889 rtx rot, from, tmp; 5704 rtx rot, from, tmp;
5890 5705
5891 mode = GET_MODE (ops[1]); 5706 mode = GET_MODE (ops[1]);
5892 5707
5893 if (GET_CODE (ops[2]) == CONST_INT) 5708 if (GET_CODE (ops[2]) == CONST_INT)
5894 { 5709 {
5895 switch (mode) 5710 switch (mode)
5896 { 5711 {
5897 case V16QImode: 5712 case E_V16QImode:
5898 emit_insn (gen_vec_extractv16qi (ops[0], ops[1], ops[2])); 5713 emit_insn (gen_vec_extractv16qiqi (ops[0], ops[1], ops[2]));
5899 break; 5714 break;
5900 case V8HImode: 5715 case E_V8HImode:
5901 emit_insn (gen_vec_extractv8hi (ops[0], ops[1], ops[2])); 5716 emit_insn (gen_vec_extractv8hihi (ops[0], ops[1], ops[2]));
5902 break; 5717 break;
5903 case V4SFmode: 5718 case E_V4SFmode:
5904 emit_insn (gen_vec_extractv4sf (ops[0], ops[1], ops[2])); 5719 emit_insn (gen_vec_extractv4sfsf (ops[0], ops[1], ops[2]));
5905 break; 5720 break;
5906 case V4SImode: 5721 case E_V4SImode:
5907 emit_insn (gen_vec_extractv4si (ops[0], ops[1], ops[2])); 5722 emit_insn (gen_vec_extractv4sisi (ops[0], ops[1], ops[2]));
5908 break; 5723 break;
5909 case V2DImode: 5724 case E_V2DImode:
5910 emit_insn (gen_vec_extractv2di (ops[0], ops[1], ops[2])); 5725 emit_insn (gen_vec_extractv2didi (ops[0], ops[1], ops[2]));
5911 break; 5726 break;
5912 case V2DFmode: 5727 case E_V2DFmode:
5913 emit_insn (gen_vec_extractv2df (ops[0], ops[1], ops[2])); 5728 emit_insn (gen_vec_extractv2dfdf (ops[0], ops[1], ops[2]));
5914 break; 5729 break;
5915 default: 5730 default:
5916 abort (); 5731 abort ();
5917 } 5732 }
5918 return; 5733 return;
5922 rot = gen_reg_rtx (TImode); 5737 rot = gen_reg_rtx (TImode);
5923 tmp = gen_reg_rtx (SImode); 5738 tmp = gen_reg_rtx (SImode);
5924 5739
5925 switch (mode) 5740 switch (mode)
5926 { 5741 {
5927 case V16QImode: 5742 case E_V16QImode:
5928 emit_insn (gen_addsi3 (tmp, ops[2], GEN_INT (-3))); 5743 emit_insn (gen_addsi3 (tmp, ops[2], GEN_INT (-3)));
5929 break; 5744 break;
5930 case V8HImode: 5745 case E_V8HImode:
5931 emit_insn (gen_addsi3 (tmp, ops[2], ops[2])); 5746 emit_insn (gen_addsi3 (tmp, ops[2], ops[2]));
5932 emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (-2))); 5747 emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (-2)));
5933 break; 5748 break;
5934 case V4SFmode: 5749 case E_V4SFmode:
5935 case V4SImode: 5750 case E_V4SImode:
5936 emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (2))); 5751 emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (2)));
5937 break; 5752 break;
5938 case V2DImode: 5753 case E_V2DImode:
5939 case V2DFmode: 5754 case E_V2DFmode:
5940 emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (3))); 5755 emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (3)));
5941 break; 5756 break;
5942 default: 5757 default:
5943 abort (); 5758 abort ();
5944 } 5759 }
5948 } 5763 }
5949 5764
5950 void 5765 void
5951 spu_builtin_insert (rtx ops[]) 5766 spu_builtin_insert (rtx ops[])
5952 { 5767 {
5953 enum machine_mode mode = GET_MODE (ops[0]); 5768 machine_mode mode = GET_MODE (ops[0]);
5954 enum machine_mode imode = GET_MODE_INNER (mode); 5769 machine_mode imode = GET_MODE_INNER (mode);
5955 rtx mask = gen_reg_rtx (TImode); 5770 rtx mask = gen_reg_rtx (TImode);
5956 rtx offset; 5771 rtx offset;
5957 5772
5958 if (GET_CODE (ops[3]) == CONST_INT) 5773 if (GET_CODE (ops[3]) == CONST_INT)
5959 offset = GEN_INT (INTVAL (ops[3]) * GET_MODE_SIZE (imode)); 5774 offset = GEN_INT (INTVAL (ops[3]) * GET_MODE_SIZE (imode));
5970 } 5785 }
5971 5786
5972 void 5787 void
5973 spu_builtin_promote (rtx ops[]) 5788 spu_builtin_promote (rtx ops[])
5974 { 5789 {
5975 enum machine_mode mode, imode; 5790 machine_mode mode, imode;
5976 rtx rot, from, offset; 5791 rtx rot, from, offset;
5977 HOST_WIDE_INT pos; 5792 HOST_WIDE_INT pos;
5978 5793
5979 mode = GET_MODE (ops[0]); 5794 mode = GET_MODE (ops[0]);
5980 imode = GET_MODE_INNER (mode); 5795 imode = GET_MODE_INNER (mode);
5994 else 5809 else
5995 { 5810 {
5996 offset = gen_reg_rtx (SImode); 5811 offset = gen_reg_rtx (SImode);
5997 switch (mode) 5812 switch (mode)
5998 { 5813 {
5999 case V16QImode: 5814 case E_V16QImode:
6000 emit_insn (gen_subsi3 (offset, GEN_INT (3), ops[2])); 5815 emit_insn (gen_subsi3 (offset, GEN_INT (3), ops[2]));
6001 break; 5816 break;
6002 case V8HImode: 5817 case E_V8HImode:
6003 emit_insn (gen_subsi3 (offset, GEN_INT (1), ops[2])); 5818 emit_insn (gen_subsi3 (offset, GEN_INT (1), ops[2]));
6004 emit_insn (gen_addsi3 (offset, offset, offset)); 5819 emit_insn (gen_addsi3 (offset, offset, offset));
6005 break; 5820 break;
6006 case V4SFmode: 5821 case E_V4SFmode:
6007 case V4SImode: 5822 case E_V4SImode:
6008 emit_insn (gen_subsi3 (offset, GEN_INT (0), ops[2])); 5823 emit_insn (gen_subsi3 (offset, GEN_INT (0), ops[2]));
6009 emit_insn (gen_ashlsi3 (offset, offset, GEN_INT (2))); 5824 emit_insn (gen_ashlsi3 (offset, offset, GEN_INT (2)));
6010 break; 5825 break;
6011 case V2DImode: 5826 case E_V2DImode:
6012 case V2DFmode: 5827 case E_V2DFmode:
6013 emit_insn (gen_ashlsi3 (offset, ops[2], GEN_INT (3))); 5828 emit_insn (gen_ashlsi3 (offset, ops[2], GEN_INT (3)));
6014 break; 5829 break;
6015 default: 5830 default:
6016 abort (); 5831 abort ();
6017 } 5832 }
6093 emit_move_insn (mem, insn); 5908 emit_move_insn (mem, insn);
6094 } 5909 }
6095 emit_insn (gen_sync ()); 5910 emit_insn (gen_sync ());
6096 } 5911 }
6097 5912
5913 static bool
5914 spu_warn_func_return (tree decl)
5915 {
5916 /* Naked functions are implemented entirely in assembly, including the
5917 return sequence, so suppress warnings about this. */
5918 return !spu_naked_function_p (decl);
5919 }
5920
6098 void 5921 void
6099 spu_expand_sign_extend (rtx ops[]) 5922 spu_expand_sign_extend (rtx ops[])
6100 { 5923 {
6101 unsigned char arr[16]; 5924 unsigned char arr[16];
6102 rtx pat = gen_reg_rtx (TImode); 5925 rtx pat = gen_reg_rtx (TImode);
6115 { 5938 {
6116 for (i = 0; i < 16; i++) 5939 for (i = 0; i < 16; i++)
6117 arr[i] = 0x10; 5940 arr[i] = 0x10;
6118 switch (GET_MODE (ops[1])) 5941 switch (GET_MODE (ops[1]))
6119 { 5942 {
6120 case HImode: 5943 case E_HImode:
6121 sign = gen_reg_rtx (SImode); 5944 sign = gen_reg_rtx (SImode);
6122 emit_insn (gen_extendhisi2 (sign, ops[1])); 5945 emit_insn (gen_extendhisi2 (sign, ops[1]));
6123 arr[last] = 0x03; 5946 arr[last] = 0x03;
6124 arr[last - 1] = 0x02; 5947 arr[last - 1] = 0x02;
6125 break; 5948 break;
6126 case SImode: 5949 case E_SImode:
6127 sign = gen_reg_rtx (SImode); 5950 sign = gen_reg_rtx (SImode);
6128 emit_insn (gen_ashrsi3 (sign, ops[1], GEN_INT (31))); 5951 emit_insn (gen_ashrsi3 (sign, ops[1], GEN_INT (31)));
6129 for (i = 0; i < 4; i++) 5952 for (i = 0; i < 4; i++)
6130 arr[last - i] = 3 - i; 5953 arr[last - i] = 3 - i;
6131 break; 5954 break;
6132 case DImode: 5955 case E_DImode:
6133 sign = gen_reg_rtx (SImode); 5956 sign = gen_reg_rtx (SImode);
6134 c = gen_reg_rtx (SImode); 5957 c = gen_reg_rtx (SImode);
6135 emit_insn (gen_spu_convert (c, ops[1])); 5958 emit_insn (gen_spu_convert (c, ops[1]));
6136 emit_insn (gen_ashrsi3 (sign, c, GEN_INT (31))); 5959 emit_insn (gen_ashrsi3 (sign, c, GEN_INT (31)));
6137 for (i = 0; i < 8; i++) 5960 for (i = 0; i < 8; i++)
6148 /* expand vector initialization. If there are any constant parts, 5971 /* expand vector initialization. If there are any constant parts,
6149 load constant parts first. Then load any non-constant parts. */ 5972 load constant parts first. Then load any non-constant parts. */
6150 void 5973 void
6151 spu_expand_vector_init (rtx target, rtx vals) 5974 spu_expand_vector_init (rtx target, rtx vals)
6152 { 5975 {
6153 enum machine_mode mode = GET_MODE (target); 5976 machine_mode mode = GET_MODE (target);
6154 int n_elts = GET_MODE_NUNITS (mode); 5977 int n_elts = GET_MODE_NUNITS (mode);
6155 int n_var = 0; 5978 int n_var = 0;
6156 bool all_same = true; 5979 bool all_same = true;
6157 rtx first, x = NULL_RTX, first_constant = NULL_RTX; 5980 rtx first, x = NULL_RTX, first_constant = NULL_RTX;
6158 int i; 5981 int i;
6239 /* Return insn index for the vector compare instruction for given CODE, 6062 /* Return insn index for the vector compare instruction for given CODE,
6240 and DEST_MODE, OP_MODE. Return -1 if valid insn is not available. */ 6063 and DEST_MODE, OP_MODE. Return -1 if valid insn is not available. */
6241 6064
6242 static int 6065 static int
6243 get_vec_cmp_insn (enum rtx_code code, 6066 get_vec_cmp_insn (enum rtx_code code,
6244 enum machine_mode dest_mode, 6067 machine_mode dest_mode,
6245 enum machine_mode op_mode) 6068 machine_mode op_mode)
6246 6069
6247 { 6070 {
6248 switch (code) 6071 switch (code)
6249 { 6072 {
6250 case EQ: 6073 case EQ:
6289 DMODE is expected destination mode. This is a recursive function. */ 6112 DMODE is expected destination mode. This is a recursive function. */
6290 6113
6291 static rtx 6114 static rtx
6292 spu_emit_vector_compare (enum rtx_code rcode, 6115 spu_emit_vector_compare (enum rtx_code rcode,
6293 rtx op0, rtx op1, 6116 rtx op0, rtx op1,
6294 enum machine_mode dmode) 6117 machine_mode dmode)
6295 { 6118 {
6296 int vec_cmp_insn; 6119 int vec_cmp_insn;
6297 rtx mask; 6120 rtx mask;
6298 enum machine_mode dest_mode; 6121 machine_mode dest_mode;
6299 enum machine_mode op_mode = GET_MODE (op1); 6122 machine_mode op_mode = GET_MODE (op1);
6300 6123
6301 gcc_assert (GET_MODE (op0) == GET_MODE (op1)); 6124 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
6302 6125
6303 /* Floating point vector compare instructions uses destination V4SImode. 6126 /* Floating point vector compare instructions uses destination V4SImode.
6304 Double floating point vector compare instructions uses destination V2DImode. 6127 Double floating point vector compare instructions uses destination V2DImode.
6328 rcode = GTU; 6151 rcode = GTU;
6329 swap_operands = true; 6152 swap_operands = true;
6330 try_again = true; 6153 try_again = true;
6331 break; 6154 break;
6332 case NE: 6155 case NE:
6156 case UNEQ:
6157 case UNLE:
6158 case UNLT:
6159 case UNGE:
6160 case UNGT:
6161 case UNORDERED:
6333 /* Treat A != B as ~(A==B). */ 6162 /* Treat A != B as ~(A==B). */
6334 { 6163 {
6164 enum rtx_code rev_code;
6335 enum insn_code nor_code; 6165 enum insn_code nor_code;
6336 rtx eq_rtx = spu_emit_vector_compare (EQ, op0, op1, dest_mode); 6166 rtx rev_mask;
6167
6168 rev_code = reverse_condition_maybe_unordered (rcode);
6169 rev_mask = spu_emit_vector_compare (rev_code, op0, op1, dest_mode);
6170
6337 nor_code = optab_handler (one_cmpl_optab, dest_mode); 6171 nor_code = optab_handler (one_cmpl_optab, dest_mode);
6338 gcc_assert (nor_code != CODE_FOR_nothing); 6172 gcc_assert (nor_code != CODE_FOR_nothing);
6339 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx)); 6173 emit_insn (GEN_FCN (nor_code) (mask, rev_mask));
6340 if (dmode != dest_mode) 6174 if (dmode != dest_mode)
6341 { 6175 {
6342 rtx temp = gen_reg_rtx (dest_mode); 6176 rtx temp = gen_reg_rtx (dest_mode);
6343 convert_move (temp, mask, 0); 6177 convert_move (temp, mask, 0);
6344 return temp; 6178 return temp;
6379 return temp; 6213 return temp;
6380 } 6214 }
6381 return mask; 6215 return mask;
6382 } 6216 }
6383 break; 6217 break;
6218 case LTGT:
6219 /* Try LT OR GT */
6220 {
6221 rtx lt_rtx, gt_rtx;
6222 enum insn_code ior_code;
6223
6224 lt_rtx = spu_emit_vector_compare (LT, op0, op1, dest_mode);
6225 gt_rtx = spu_emit_vector_compare (GT, op0, op1, dest_mode);
6226
6227 ior_code = optab_handler (ior_optab, dest_mode);
6228 gcc_assert (ior_code != CODE_FOR_nothing);
6229 emit_insn (GEN_FCN (ior_code) (mask, lt_rtx, gt_rtx));
6230 if (dmode != dest_mode)
6231 {
6232 rtx temp = gen_reg_rtx (dest_mode);
6233 convert_move (temp, mask, 0);
6234 return temp;
6235 }
6236 return mask;
6237 }
6238 break;
6239 case ORDERED:
6240 /* Implement as (A==A) & (B==B) */
6241 {
6242 rtx a_rtx, b_rtx;
6243 enum insn_code and_code;
6244
6245 a_rtx = spu_emit_vector_compare (EQ, op0, op0, dest_mode);
6246 b_rtx = spu_emit_vector_compare (EQ, op1, op1, dest_mode);
6247
6248 and_code = optab_handler (and_optab, dest_mode);
6249 gcc_assert (and_code != CODE_FOR_nothing);
6250 emit_insn (GEN_FCN (and_code) (mask, a_rtx, b_rtx));
6251 if (dmode != dest_mode)
6252 {
6253 rtx temp = gen_reg_rtx (dest_mode);
6254 convert_move (temp, mask, 0);
6255 return temp;
6256 }
6257 return mask;
6258 }
6259 break;
6384 default: 6260 default:
6385 gcc_unreachable (); 6261 gcc_unreachable ();
6386 } 6262 }
6387 6263
6388 /* You only get two chances. */ 6264 /* You only get two chances. */
6417 6293
6418 int 6294 int
6419 spu_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2, 6295 spu_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
6420 rtx cond, rtx cc_op0, rtx cc_op1) 6296 rtx cond, rtx cc_op0, rtx cc_op1)
6421 { 6297 {
6422 enum machine_mode dest_mode = GET_MODE (dest); 6298 machine_mode dest_mode = GET_MODE (dest);
6423 enum rtx_code rcode = GET_CODE (cond); 6299 enum rtx_code rcode = GET_CODE (cond);
6424 rtx mask; 6300 rtx mask;
6425 6301
6426 /* Get the vector mask for the given relational operations. */ 6302 /* Get the vector mask for the given relational operations. */
6427 mask = spu_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode); 6303 mask = spu_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
6430 6306
6431 return 1; 6307 return 1;
6432 } 6308 }
6433 6309
6434 static rtx 6310 static rtx
6435 spu_force_reg (enum machine_mode mode, rtx op) 6311 spu_force_reg (machine_mode mode, rtx op)
6436 { 6312 {
6437 rtx x, r; 6313 rtx x, r;
6438 if (GET_MODE (op) == VOIDmode || GET_MODE (op) == BLKmode) 6314 if (GET_MODE (op) == VOIDmode || GET_MODE (op) == BLKmode)
6439 { 6315 {
6440 if ((SCALAR_INT_MODE_P (mode) && GET_CODE (op) == CONST_INT) 6316 if ((SCALAR_INT_MODE_P (mode) && GET_CODE (op) == CONST_INT)
6540 if (arg == 0) 6416 if (arg == 0)
6541 abort (); 6417 abort ();
6542 ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); 6418 ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6543 } 6419 }
6544 6420
6545 /* The insn pattern may have additional operands (SCRATCH). 6421 gcc_assert (i == insn_data[icode].n_generator_args);
6546 Return the number of actual non-SCRATCH operands. */
6547 gcc_assert (i <= insn_data[icode].n_operands);
6548 return i; 6422 return i;
6549 } 6423 }
6550 6424
6551 static rtx 6425 static rtx
6552 spu_expand_builtin_1 (struct spu_builtin_description *d, 6426 spu_expand_builtin_1 (struct spu_builtin_description *d,
6553 tree exp, rtx target) 6427 tree exp, rtx target)
6554 { 6428 {
6555 rtx pat; 6429 rtx pat;
6556 rtx ops[8]; 6430 rtx ops[8];
6557 enum insn_code icode = (enum insn_code) d->icode; 6431 enum insn_code icode = (enum insn_code) d->icode;
6558 enum machine_mode mode, tmode; 6432 machine_mode mode, tmode;
6559 int i, p; 6433 int i, p;
6560 int n_operands; 6434 int n_operands;
6561 tree return_type; 6435 tree return_type;
6562 6436
6563 /* Set up ops[] with values from arglist. */ 6437 /* Set up ops[] with values from arglist. */
6588 i++; 6462 i++;
6589 } 6463 }
6590 6464
6591 if (d->fcode == SPU_MASK_FOR_LOAD) 6465 if (d->fcode == SPU_MASK_FOR_LOAD)
6592 { 6466 {
6593 enum machine_mode mode = insn_data[icode].operand[1].mode; 6467 machine_mode mode = insn_data[icode].operand[1].mode;
6594 tree arg; 6468 tree arg;
6595 rtx addr, op, pat; 6469 rtx addr, op, pat;
6596 6470
6597 /* get addr */ 6471 /* get addr */
6598 arg = CALL_EXPR_ARG (exp, 0); 6472 arg = CALL_EXPR_ARG (exp, 0);
6600 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); 6474 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
6601 addr = memory_address (mode, op); 6475 addr = memory_address (mode, op);
6602 6476
6603 /* negate addr */ 6477 /* negate addr */
6604 op = gen_reg_rtx (GET_MODE (addr)); 6478 op = gen_reg_rtx (GET_MODE (addr));
6605 emit_insn (gen_rtx_SET (VOIDmode, op, 6479 emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr)));
6606 gen_rtx_NEG (GET_MODE (addr), addr)));
6607 op = gen_rtx_MEM (mode, op); 6480 op = gen_rtx_MEM (mode, op);
6608 6481
6609 pat = GEN_FCN (icode) (target, op); 6482 pat = GEN_FCN (icode) (target, op);
6610 if (!pat) 6483 if (!pat)
6611 return 0; 6484 return 0;
6639 if (GET_CODE (ops[i]) == CONST_INT) 6512 if (GET_CODE (ops[i]) == CONST_INT)
6640 ops[i] = spu_const (mode, INTVAL (ops[i])); 6513 ops[i] = spu_const (mode, INTVAL (ops[i]));
6641 else 6514 else
6642 { 6515 {
6643 rtx reg = gen_reg_rtx (mode); 6516 rtx reg = gen_reg_rtx (mode);
6644 enum machine_mode imode = GET_MODE_INNER (mode); 6517 machine_mode imode = GET_MODE_INNER (mode);
6645 if (!spu_nonmem_operand (ops[i], GET_MODE (ops[i]))) 6518 if (!spu_nonmem_operand (ops[i], GET_MODE (ops[i])))
6646 ops[i] = force_reg (GET_MODE (ops[i]), ops[i]); 6519 ops[i] = force_reg (GET_MODE (ops[i]), ops[i]);
6647 if (imode != GET_MODE (ops[i])) 6520 if (imode != GET_MODE (ops[i]))
6648 ops[i] = convert_to_mode (imode, ops[i], 6521 ops[i] = convert_to_mode (imode, ops[i],
6649 TYPE_UNSIGNED (spu_builtin_types 6522 TYPE_UNSIGNED (spu_builtin_types
6713 6586
6714 rtx 6587 rtx
6715 spu_expand_builtin (tree exp, 6588 spu_expand_builtin (tree exp,
6716 rtx target, 6589 rtx target,
6717 rtx subtarget ATTRIBUTE_UNUSED, 6590 rtx subtarget ATTRIBUTE_UNUSED,
6718 enum machine_mode mode ATTRIBUTE_UNUSED, 6591 machine_mode mode ATTRIBUTE_UNUSED,
6719 int ignore ATTRIBUTE_UNUSED) 6592 int ignore ATTRIBUTE_UNUSED)
6720 { 6593 {
6721 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 6594 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6722 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 6595 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6723 struct spu_builtin_description *d; 6596 struct spu_builtin_description *d;
6729 return spu_expand_builtin_1 (d, exp, target); 6602 return spu_expand_builtin_1 (d, exp, target);
6730 } 6603 }
6731 abort (); 6604 abort ();
6732 } 6605 }
6733 6606
6734 /* Implement targetm.vectorize.builtin_mul_widen_even. */
6735 static tree
6736 spu_builtin_mul_widen_even (tree type)
6737 {
6738 switch (TYPE_MODE (type))
6739 {
6740 case V8HImode:
6741 if (TYPE_UNSIGNED (type))
6742 return spu_builtin_decls[SPU_MULE_0];
6743 else
6744 return spu_builtin_decls[SPU_MULE_1];
6745 break;
6746 default:
6747 return NULL_TREE;
6748 }
6749 }
6750
6751 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
6752 static tree
6753 spu_builtin_mul_widen_odd (tree type)
6754 {
6755 switch (TYPE_MODE (type))
6756 {
6757 case V8HImode:
6758 if (TYPE_UNSIGNED (type))
6759 return spu_builtin_decls[SPU_MULO_1];
6760 else
6761 return spu_builtin_decls[SPU_MULO_0];
6762 break;
6763 default:
6764 return NULL_TREE;
6765 }
6766 }
6767
6768 /* Implement targetm.vectorize.builtin_mask_for_load. */ 6607 /* Implement targetm.vectorize.builtin_mask_for_load. */
6769 static tree 6608 static tree
6770 spu_builtin_mask_for_load (void) 6609 spu_builtin_mask_for_load (void)
6771 { 6610 {
6772 return spu_builtin_decls[SPU_MASK_FOR_LOAD]; 6611 return spu_builtin_decls[SPU_MASK_FOR_LOAD];
6773 } 6612 }
6774 6613
6775 /* Implement targetm.vectorize.builtin_vectorization_cost. */ 6614 /* Implement targetm.vectorize.builtin_vectorization_cost. */
6776 static int 6615 static int
6777 spu_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, 6616 spu_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
6778 tree vectype ATTRIBUTE_UNUSED, 6617 tree vectype,
6779 int misalign ATTRIBUTE_UNUSED) 6618 int misalign ATTRIBUTE_UNUSED)
6780 { 6619 {
6620 unsigned elements;
6621
6781 switch (type_of_cost) 6622 switch (type_of_cost)
6782 { 6623 {
6783 case scalar_stmt: 6624 case scalar_stmt:
6784 case vector_stmt: 6625 case vector_stmt:
6785 case vector_load: 6626 case vector_load:
6786 case vector_store: 6627 case vector_store:
6787 case vec_to_scalar: 6628 case vec_to_scalar:
6788 case scalar_to_vec: 6629 case scalar_to_vec:
6789 case cond_branch_not_taken: 6630 case cond_branch_not_taken:
6790 case vec_perm: 6631 case vec_perm:
6632 case vec_promote_demote:
6791 return 1; 6633 return 1;
6792 6634
6793 case scalar_store: 6635 case scalar_store:
6794 return 10; 6636 return 10;
6795 6637
6796 case scalar_load: 6638 case scalar_load:
6797 /* Load + rotate. */ 6639 /* Load + rotate. */
6798 return 2; 6640 return 2;
6799 6641
6800 case unaligned_load: 6642 case unaligned_load:
6643 case vector_gather_load:
6644 case vector_scatter_store:
6801 return 2; 6645 return 2;
6802 6646
6803 case cond_branch_taken: 6647 case cond_branch_taken:
6804 return 6; 6648 return 6;
6805 6649
6650 case vec_construct:
6651 elements = TYPE_VECTOR_SUBPARTS (vectype);
6652 return elements / 2 + 1;
6653
6806 default: 6654 default:
6807 gcc_unreachable (); 6655 gcc_unreachable ();
6808 } 6656 }
6657 }
6658
6659 /* Implement targetm.vectorize.init_cost. */
6660
6661 static void *
6662 spu_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED)
6663 {
6664 unsigned *cost = XNEWVEC (unsigned, 3);
6665 cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0;
6666 return cost;
6667 }
6668
6669 /* Implement targetm.vectorize.add_stmt_cost. */
6670
6671 static unsigned
6672 spu_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
6673 struct _stmt_vec_info *stmt_info, int misalign,
6674 enum vect_cost_model_location where)
6675 {
6676 unsigned *cost = (unsigned *) data;
6677 unsigned retval = 0;
6678
6679 if (flag_vect_cost_model)
6680 {
6681 tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
6682 int stmt_cost = spu_builtin_vectorization_cost (kind, vectype, misalign);
6683
6684 /* Statements in an inner loop relative to the loop being
6685 vectorized are weighted more heavily. The value here is
6686 arbitrary and could potentially be improved with analysis. */
6687 if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info))
6688 count *= 50; /* FIXME. */
6689
6690 retval = (unsigned) (count * stmt_cost);
6691 cost[where] += retval;
6692 }
6693
6694 return retval;
6695 }
6696
6697 /* Implement targetm.vectorize.finish_cost. */
6698
6699 static void
6700 spu_finish_cost (void *data, unsigned *prologue_cost,
6701 unsigned *body_cost, unsigned *epilogue_cost)
6702 {
6703 unsigned *cost = (unsigned *) data;
6704 *prologue_cost = cost[vect_prologue];
6705 *body_cost = cost[vect_body];
6706 *epilogue_cost = cost[vect_epilogue];
6707 }
6708
6709 /* Implement targetm.vectorize.destroy_cost_data. */
6710
6711 static void
6712 spu_destroy_cost_data (void *data)
6713 {
6714 free (data);
6809 } 6715 }
6810 6716
6811 /* Return true iff, data reference of TYPE can reach vector alignment (16) 6717 /* Return true iff, data reference of TYPE can reach vector alignment (16)
6812 after applying N number of iterations. This routine does not determine 6718 after applying N number of iterations. This routine does not determine
6813 how may iterations are required to reach desired alignment. */ 6719 how may iterations are required to reach desired alignment. */
6820 6726
6821 /* All other types are naturally aligned. */ 6727 /* All other types are naturally aligned. */
6822 return true; 6728 return true;
6823 } 6729 }
6824 6730
6825 /* Implement targetm.vectorize.builtin_vec_perm. */
6826 tree
6827 spu_builtin_vec_perm (tree type, tree *mask_element_type)
6828 {
6829 *mask_element_type = unsigned_char_type_node;
6830
6831 switch (TYPE_MODE (type))
6832 {
6833 case V16QImode:
6834 if (TYPE_UNSIGNED (type))
6835 return spu_builtin_decls[SPU_SHUFFLE_0];
6836 else
6837 return spu_builtin_decls[SPU_SHUFFLE_1];
6838
6839 case V8HImode:
6840 if (TYPE_UNSIGNED (type))
6841 return spu_builtin_decls[SPU_SHUFFLE_2];
6842 else
6843 return spu_builtin_decls[SPU_SHUFFLE_3];
6844
6845 case V4SImode:
6846 if (TYPE_UNSIGNED (type))
6847 return spu_builtin_decls[SPU_SHUFFLE_4];
6848 else
6849 return spu_builtin_decls[SPU_SHUFFLE_5];
6850
6851 case V2DImode:
6852 if (TYPE_UNSIGNED (type))
6853 return spu_builtin_decls[SPU_SHUFFLE_6];
6854 else
6855 return spu_builtin_decls[SPU_SHUFFLE_7];
6856
6857 case V4SFmode:
6858 return spu_builtin_decls[SPU_SHUFFLE_8];
6859
6860 case V2DFmode:
6861 return spu_builtin_decls[SPU_SHUFFLE_9];
6862
6863 default:
6864 return NULL_TREE;
6865 }
6866 }
6867
6868 /* Return the appropriate mode for a named address pointer. */ 6731 /* Return the appropriate mode for a named address pointer. */
6869 static enum machine_mode 6732 static scalar_int_mode
6870 spu_addr_space_pointer_mode (addr_space_t addrspace) 6733 spu_addr_space_pointer_mode (addr_space_t addrspace)
6871 { 6734 {
6872 switch (addrspace) 6735 switch (addrspace)
6873 { 6736 {
6874 case ADDR_SPACE_GENERIC: 6737 case ADDR_SPACE_GENERIC:
6879 gcc_unreachable (); 6742 gcc_unreachable ();
6880 } 6743 }
6881 } 6744 }
6882 6745
6883 /* Return the appropriate mode for a named address address. */ 6746 /* Return the appropriate mode for a named address address. */
6884 static enum machine_mode 6747 static scalar_int_mode
6885 spu_addr_space_address_mode (addr_space_t addrspace) 6748 spu_addr_space_address_mode (addr_space_t addrspace)
6886 { 6749 {
6887 switch (addrspace) 6750 switch (addrspace)
6888 { 6751 {
6889 case ADDR_SPACE_GENERIC: 6752 case ADDR_SPACE_GENERIC:
6982 int i; 6845 int i;
6983 unsigned t[4] = {0, 0, 0, 0}; 6846 unsigned t[4] = {0, 0, 0, 0};
6984 6847
6985 for (i = 0; i < g->num_nodes; i++) 6848 for (i = 0; i < g->num_nodes; i++)
6986 { 6849 {
6987 rtx insn = g->nodes[i].insn; 6850 rtx_insn *insn = g->nodes[i].insn;
6988 int p = get_pipe (insn) + 2; 6851 int p = get_pipe (insn) + 2;
6989 6852
6990 gcc_assert (p >= 0); 6853 gcc_assert (p >= 0);
6991 gcc_assert (p < 4); 6854 gcc_assert (p < 4);
6992 6855
7025 gcc_assert (REGNO (r0) == LAST_VIRTUAL_REGISTER + 1 6888 gcc_assert (REGNO (r0) == LAST_VIRTUAL_REGISTER + 1
7026 && REGNO (r1) == LAST_VIRTUAL_REGISTER + 2); 6889 && REGNO (r1) == LAST_VIRTUAL_REGISTER + 2);
7027 } 6890 }
7028 } 6891 }
7029 6892
7030 static enum machine_mode 6893 static scalar_int_mode
7031 spu_libgcc_cmp_return_mode (void) 6894 spu_libgcc_cmp_return_mode (void)
7032 { 6895 {
7033 6896
7034 /* For SPU word mode is TI mode so it is better to use SImode 6897 /* For SPU word mode is TI mode so it is better to use SImode
7035 for compare returns. */ 6898 for compare returns. */
7036 return SImode; 6899 return SImode;
7037 } 6900 }
7038 6901
7039 static enum machine_mode 6902 static scalar_int_mode
7040 spu_libgcc_shift_count_mode (void) 6903 spu_libgcc_shift_count_mode (void)
7041 { 6904 {
7042 /* For SPU word mode is TI mode so it is better to use SImode 6905 /* For SPU word mode is TI mode so it is better to use SImode
7043 for shift counts. */ 6906 for shift counts. */
7044 return SImode; 6907 return SImode;
7045 }
7046
7047 /* An early place to adjust some flags after GCC has finished processing
7048 * them. */
7049 static void
7050 asm_file_start (void)
7051 {
7052 /* Variable tracking should be run after all optimizations which
7053 change order of insns. It also needs a valid CFG. Therefore,
7054 *if* we make nontrivial changes in machine-dependent reorg,
7055 run variable tracking after those. However, if we do not run
7056 our machine-dependent reorg pass, we must still run the normal
7057 variable tracking pass (or else we will ICE in final since
7058 debug insns have not been removed). */
7059 if (TARGET_BRANCH_HINTS && optimize)
7060 {
7061 spu_flag_var_tracking = flag_var_tracking;
7062 flag_var_tracking = 0;
7063 }
7064
7065 default_file_start ();
7066 } 6908 }
7067 6909
7068 /* Implement targetm.section_type_flags. */ 6910 /* Implement targetm.section_type_flags. */
7069 static unsigned int 6911 static unsigned int
7070 spu_section_type_flags (tree decl, const char *name, int reloc) 6912 spu_section_type_flags (tree decl, const char *name, int reloc)
7114 6956
7115 /* Generate a constant or register which contains 2^SCALE. We assume 6957 /* Generate a constant or register which contains 2^SCALE. We assume
7116 the result is valid for MODE. Currently, MODE must be V4SFmode and 6958 the result is valid for MODE. Currently, MODE must be V4SFmode and
7117 SCALE must be SImode. */ 6959 SCALE must be SImode. */
7118 rtx 6960 rtx
7119 spu_gen_exp2 (enum machine_mode mode, rtx scale) 6961 spu_gen_exp2 (machine_mode mode, rtx scale)
7120 { 6962 {
7121 gcc_assert (mode == V4SFmode); 6963 gcc_assert (mode == V4SFmode);
7122 gcc_assert (GET_MODE (scale) == SImode || GET_CODE (scale) == CONST_INT); 6964 gcc_assert (GET_MODE (scale) == SImode || GET_CODE (scale) == CONST_INT);
7123 if (GET_CODE (scale) != CONST_INT) 6965 if (GET_CODE (scale) != CONST_INT)
7124 { 6966 {
7189 return true; 7031 return true;
7190 7032
7191 return default_ref_may_alias_errno (ref); 7033 return default_ref_may_alias_errno (ref);
7192 } 7034 }
7193 7035
7036 /* Output thunk to FILE that implements a C++ virtual function call (with
7037 multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
7038 by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
7039 stored at VCALL_OFFSET in the vtable whose address is located at offset 0
7040 relative to the resulting this pointer. */
7041
7042 static void
7043 spu_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7044 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7045 tree function)
7046 {
7047 rtx op[8];
7048
7049 /* Make sure unwind info is emitted for the thunk if needed. */
7050 final_start_function (emit_barrier (), file, 1);
7051
7052 /* Operand 0 is the target function. */
7053 op[0] = XEXP (DECL_RTL (function), 0);
7054
7055 /* Operand 1 is the 'this' pointer. */
7056 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7057 op[1] = gen_rtx_REG (Pmode, FIRST_ARG_REGNUM + 1);
7058 else
7059 op[1] = gen_rtx_REG (Pmode, FIRST_ARG_REGNUM);
7060
7061 /* Operands 2/3 are the low/high halfwords of delta. */
7062 op[2] = GEN_INT (trunc_int_for_mode (delta, HImode));
7063 op[3] = GEN_INT (trunc_int_for_mode (delta >> 16, HImode));
7064
7065 /* Operands 4/5 are the low/high halfwords of vcall_offset. */
7066 op[4] = GEN_INT (trunc_int_for_mode (vcall_offset, HImode));
7067 op[5] = GEN_INT (trunc_int_for_mode (vcall_offset >> 16, HImode));
7068
7069 /* Operands 6/7 are temporary registers. */
7070 op[6] = gen_rtx_REG (Pmode, 79);
7071 op[7] = gen_rtx_REG (Pmode, 78);
7072
7073 /* Add DELTA to this pointer. */
7074 if (delta)
7075 {
7076 if (delta >= -0x200 && delta < 0x200)
7077 output_asm_insn ("ai\t%1,%1,%2", op);
7078 else if (delta >= -0x8000 && delta < 0x8000)
7079 {
7080 output_asm_insn ("il\t%6,%2", op);
7081 output_asm_insn ("a\t%1,%1,%6", op);
7082 }
7083 else
7084 {
7085 output_asm_insn ("ilhu\t%6,%3", op);
7086 output_asm_insn ("iohl\t%6,%2", op);
7087 output_asm_insn ("a\t%1,%1,%6", op);
7088 }
7089 }
7090
7091 /* Perform vcall adjustment. */
7092 if (vcall_offset)
7093 {
7094 output_asm_insn ("lqd\t%7,0(%1)", op);
7095 output_asm_insn ("rotqby\t%7,%7,%1", op);
7096
7097 if (vcall_offset >= -0x200 && vcall_offset < 0x200)
7098 output_asm_insn ("ai\t%7,%7,%4", op);
7099 else if (vcall_offset >= -0x8000 && vcall_offset < 0x8000)
7100 {
7101 output_asm_insn ("il\t%6,%4", op);
7102 output_asm_insn ("a\t%7,%7,%6", op);
7103 }
7104 else
7105 {
7106 output_asm_insn ("ilhu\t%6,%5", op);
7107 output_asm_insn ("iohl\t%6,%4", op);
7108 output_asm_insn ("a\t%7,%7,%6", op);
7109 }
7110
7111 output_asm_insn ("lqd\t%6,0(%7)", op);
7112 output_asm_insn ("rotqby\t%6,%6,%7", op);
7113 output_asm_insn ("a\t%1,%1,%6", op);
7114 }
7115
7116 /* Jump to target. */
7117 output_asm_insn ("br\t%0", op);
7118
7119 final_end_function ();
7120 }
7121
7122 /* Canonicalize a comparison from one we don't have to one we do have. */
7123 static void
7124 spu_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
7125 bool op0_preserve_value)
7126 {
7127 if (!op0_preserve_value
7128 && (*code == LE || *code == LT || *code == LEU || *code == LTU))
7129 {
7130 rtx tem = *op0;
7131 *op0 = *op1;
7132 *op1 = tem;
7133 *code = (int)swap_condition ((enum rtx_code)*code);
7134 }
7135 }
7136
7137 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
7138 to perform. MEM is the memory on which to operate. VAL is the second
7139 operand of the binary operator. BEFORE and AFTER are optional locations to
7140 return the value of MEM either before of after the operation. */
7141 void
7142 spu_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
7143 rtx orig_before, rtx orig_after)
7144 {
7145 machine_mode mode = GET_MODE (mem);
7146 rtx before = orig_before, after = orig_after;
7147
7148 if (before == NULL_RTX)
7149 before = gen_reg_rtx (mode);
7150
7151 emit_move_insn (before, mem);
7152
7153 if (code == MULT) /* NAND operation */
7154 {
7155 rtx x = expand_simple_binop (mode, AND, before, val,
7156 NULL_RTX, 1, OPTAB_LIB_WIDEN);
7157 after = expand_simple_unop (mode, NOT, x, after, 1);
7158 }
7159 else
7160 {
7161 after = expand_simple_binop (mode, code, before, val,
7162 after, 1, OPTAB_LIB_WIDEN);
7163 }
7164
7165 emit_move_insn (mem, after);
7166
7167 if (orig_after && after != orig_after)
7168 emit_move_insn (orig_after, after);
7169 }
7170
7171 /* Implement TARGET_MODES_TIEABLE_P. */
7172
7173 static bool
7174 spu_modes_tieable_p (machine_mode mode1, machine_mode mode2)
7175 {
7176 return (GET_MODE_BITSIZE (mode1) <= MAX_FIXED_MODE_SIZE
7177 && GET_MODE_BITSIZE (mode2) <= MAX_FIXED_MODE_SIZE);
7178 }
7179
7180 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. GCC assumes that modes are
7181 in the lowpart of a register, which is only true for SPU. */
7182
7183 static bool
7184 spu_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t)
7185 {
7186 return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
7187 || (GET_MODE_SIZE (from) <= 4 && GET_MODE_SIZE (to) <= 4)
7188 || (GET_MODE_SIZE (from) >= 16 && GET_MODE_SIZE (to) >= 16));
7189 }
7190
7191 /* Implement TARGET_TRULY_NOOP_TRUNCATION. */
7192
7193 static bool
7194 spu_truly_noop_truncation (unsigned int outprec, unsigned int inprec)
7195 {
7196 return inprec <= 32 && outprec <= inprec;
7197 }
7198
7199 /* Implement TARGET_STATIC_RTX_ALIGNMENT.
7200
7201 Make all static objects 16-byte aligned. This allows us to assume
7202 they are also padded to 16 bytes, which means we can use a single
7203 load or store instruction to access them. */
7204
7205 static HOST_WIDE_INT
7206 spu_static_rtx_alignment (machine_mode mode)
7207 {
7208 return MAX (GET_MODE_ALIGNMENT (mode), 128);
7209 }
7210
7211 /* Implement TARGET_CONSTANT_ALIGNMENT.
7212
7213 Make all static objects 16-byte aligned. This allows us to assume
7214 they are also padded to 16 bytes, which means we can use a single
7215 load or store instruction to access them. */
7216
7217 static HOST_WIDE_INT
7218 spu_constant_alignment (const_tree, HOST_WIDE_INT align)
7219 {
7220 return MAX (align, 128);
7221 }
7222
7223 /* Table of machine attributes. */
7224 static const struct attribute_spec spu_attribute_table[] =
7225 {
7226 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
7227 affects_type_identity } */
7228 { "naked", 0, 0, true, false, false, spu_handle_fndecl_attribute,
7229 false },
7230 { "spu_vector", 0, 0, false, true, false, spu_handle_vector_attribute,
7231 false },
7232 { NULL, 0, 0, false, false, false, NULL, false }
7233 };
7234
7235 /* TARGET overrides. */
7236
7237 #undef TARGET_LRA_P
7238 #define TARGET_LRA_P hook_bool_void_false
7239
7240 #undef TARGET_ADDR_SPACE_POINTER_MODE
7241 #define TARGET_ADDR_SPACE_POINTER_MODE spu_addr_space_pointer_mode
7242
7243 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
7244 #define TARGET_ADDR_SPACE_ADDRESS_MODE spu_addr_space_address_mode
7245
7246 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
7247 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
7248 spu_addr_space_legitimate_address_p
7249
7250 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
7251 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS spu_addr_space_legitimize_address
7252
7253 #undef TARGET_ADDR_SPACE_SUBSET_P
7254 #define TARGET_ADDR_SPACE_SUBSET_P spu_addr_space_subset_p
7255
7256 #undef TARGET_ADDR_SPACE_CONVERT
7257 #define TARGET_ADDR_SPACE_CONVERT spu_addr_space_convert
7258
7259 #undef TARGET_INIT_BUILTINS
7260 #define TARGET_INIT_BUILTINS spu_init_builtins
7261 #undef TARGET_BUILTIN_DECL
7262 #define TARGET_BUILTIN_DECL spu_builtin_decl
7263
7264 #undef TARGET_EXPAND_BUILTIN
7265 #define TARGET_EXPAND_BUILTIN spu_expand_builtin
7266
7267 #undef TARGET_UNWIND_WORD_MODE
7268 #define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode
7269
7270 #undef TARGET_LEGITIMIZE_ADDRESS
7271 #define TARGET_LEGITIMIZE_ADDRESS spu_legitimize_address
7272
7273 /* The current assembler doesn't like .4byte foo@ppu, so use the normal .long
7274 and .quad for the debugger. When it is known that the assembler is fixed,
7275 these can be removed. */
7276 #undef TARGET_ASM_UNALIGNED_SI_OP
7277 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
7278
7279 #undef TARGET_ASM_ALIGNED_DI_OP
7280 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
7281
7282 /* The .8byte directive doesn't seem to work well for a 32 bit
7283 architecture. */
7284 #undef TARGET_ASM_UNALIGNED_DI_OP
7285 #define TARGET_ASM_UNALIGNED_DI_OP NULL
7286
7287 #undef TARGET_RTX_COSTS
7288 #define TARGET_RTX_COSTS spu_rtx_costs
7289
7290 #undef TARGET_ADDRESS_COST
7291 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
7292
7293 #undef TARGET_SCHED_ISSUE_RATE
7294 #define TARGET_SCHED_ISSUE_RATE spu_sched_issue_rate
7295
7296 #undef TARGET_SCHED_INIT_GLOBAL
7297 #define TARGET_SCHED_INIT_GLOBAL spu_sched_init_global
7298
7299 #undef TARGET_SCHED_INIT
7300 #define TARGET_SCHED_INIT spu_sched_init
7301
7302 #undef TARGET_SCHED_VARIABLE_ISSUE
7303 #define TARGET_SCHED_VARIABLE_ISSUE spu_sched_variable_issue
7304
7305 #undef TARGET_SCHED_REORDER
7306 #define TARGET_SCHED_REORDER spu_sched_reorder
7307
7308 #undef TARGET_SCHED_REORDER2
7309 #define TARGET_SCHED_REORDER2 spu_sched_reorder
7310
7311 #undef TARGET_SCHED_ADJUST_COST
7312 #define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost
7313
7314 #undef TARGET_ATTRIBUTE_TABLE
7315 #define TARGET_ATTRIBUTE_TABLE spu_attribute_table
7316
7317 #undef TARGET_ASM_INTEGER
7318 #define TARGET_ASM_INTEGER spu_assemble_integer
7319
7320 #undef TARGET_SCALAR_MODE_SUPPORTED_P
7321 #define TARGET_SCALAR_MODE_SUPPORTED_P spu_scalar_mode_supported_p
7322
7323 #undef TARGET_VECTOR_MODE_SUPPORTED_P
7324 #define TARGET_VECTOR_MODE_SUPPORTED_P spu_vector_mode_supported_p
7325
7326 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
7327 #define TARGET_FUNCTION_OK_FOR_SIBCALL spu_function_ok_for_sibcall
7328
7329 #undef TARGET_ASM_GLOBALIZE_LABEL
7330 #define TARGET_ASM_GLOBALIZE_LABEL spu_asm_globalize_label
7331
7332 #undef TARGET_PASS_BY_REFERENCE
7333 #define TARGET_PASS_BY_REFERENCE spu_pass_by_reference
7334
7335 #undef TARGET_FUNCTION_ARG
7336 #define TARGET_FUNCTION_ARG spu_function_arg
7337
7338 #undef TARGET_FUNCTION_ARG_ADVANCE
7339 #define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance
7340
7341 #undef TARGET_FUNCTION_ARG_OFFSET
7342 #define TARGET_FUNCTION_ARG_OFFSET spu_function_arg_offset
7343
7344 #undef TARGET_FUNCTION_ARG_PADDING
7345 #define TARGET_FUNCTION_ARG_PADDING spu_function_arg_padding
7346
7347 #undef TARGET_MUST_PASS_IN_STACK
7348 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
7349
7350 #undef TARGET_BUILD_BUILTIN_VA_LIST
7351 #define TARGET_BUILD_BUILTIN_VA_LIST spu_build_builtin_va_list
7352
7353 #undef TARGET_EXPAND_BUILTIN_VA_START
7354 #define TARGET_EXPAND_BUILTIN_VA_START spu_va_start
7355
7356 #undef TARGET_SETUP_INCOMING_VARARGS
7357 #define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs
7358
7359 #undef TARGET_MACHINE_DEPENDENT_REORG
7360 #define TARGET_MACHINE_DEPENDENT_REORG spu_machine_dependent_reorg
7361
7362 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
7363 #define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr
7364
7365 #undef TARGET_INIT_LIBFUNCS
7366 #define TARGET_INIT_LIBFUNCS spu_init_libfuncs
7367
7368 #undef TARGET_RETURN_IN_MEMORY
7369 #define TARGET_RETURN_IN_MEMORY spu_return_in_memory
7370
7371 #undef TARGET_ENCODE_SECTION_INFO
7372 #define TARGET_ENCODE_SECTION_INFO spu_encode_section_info
7373
7374 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
7375 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD spu_builtin_mask_for_load
7376
7377 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
7378 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST spu_builtin_vectorization_cost
7379
7380 #undef TARGET_VECTORIZE_INIT_COST
7381 #define TARGET_VECTORIZE_INIT_COST spu_init_cost
7382
7383 #undef TARGET_VECTORIZE_ADD_STMT_COST
7384 #define TARGET_VECTORIZE_ADD_STMT_COST spu_add_stmt_cost
7385
7386 #undef TARGET_VECTORIZE_FINISH_COST
7387 #define TARGET_VECTORIZE_FINISH_COST spu_finish_cost
7388
7389 #undef TARGET_VECTORIZE_DESTROY_COST_DATA
7390 #define TARGET_VECTORIZE_DESTROY_COST_DATA spu_destroy_cost_data
7391
7392 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
7393 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable
7394
7395 #undef TARGET_LIBGCC_CMP_RETURN_MODE
7396 #define TARGET_LIBGCC_CMP_RETURN_MODE spu_libgcc_cmp_return_mode
7397
7398 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
7399 #define TARGET_LIBGCC_SHIFT_COUNT_MODE spu_libgcc_shift_count_mode
7400
7401 #undef TARGET_SCHED_SMS_RES_MII
7402 #define TARGET_SCHED_SMS_RES_MII spu_sms_res_mii
7403
7404 #undef TARGET_SECTION_TYPE_FLAGS
7405 #define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags
7406
7407 #undef TARGET_ASM_SELECT_SECTION
7408 #define TARGET_ASM_SELECT_SECTION spu_select_section
7409
7410 #undef TARGET_ASM_UNIQUE_SECTION
7411 #define TARGET_ASM_UNIQUE_SECTION spu_unique_section
7412
7413 #undef TARGET_LEGITIMATE_ADDRESS_P
7414 #define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p
7415
7416 #undef TARGET_LEGITIMATE_CONSTANT_P
7417 #define TARGET_LEGITIMATE_CONSTANT_P spu_legitimate_constant_p
7418
7419 #undef TARGET_TRAMPOLINE_INIT
7420 #define TARGET_TRAMPOLINE_INIT spu_trampoline_init
7421
7422 #undef TARGET_WARN_FUNC_RETURN
7423 #define TARGET_WARN_FUNC_RETURN spu_warn_func_return
7424
7425 #undef TARGET_OPTION_OVERRIDE
7426 #define TARGET_OPTION_OVERRIDE spu_option_override
7427
7428 #undef TARGET_CONDITIONAL_REGISTER_USAGE
7429 #define TARGET_CONDITIONAL_REGISTER_USAGE spu_conditional_register_usage
7430
7431 #undef TARGET_REF_MAY_ALIAS_ERRNO
7432 #define TARGET_REF_MAY_ALIAS_ERRNO spu_ref_may_alias_errno
7433
7434 #undef TARGET_ASM_OUTPUT_MI_THUNK
7435 #define TARGET_ASM_OUTPUT_MI_THUNK spu_output_mi_thunk
7436 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
7437 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
7438
7439 /* Variable tracking should be run after all optimizations which
7440 change order of insns. It also needs a valid CFG. */
7441 #undef TARGET_DELAY_VARTRACK
7442 #define TARGET_DELAY_VARTRACK true
7443
7444 #undef TARGET_CANONICALIZE_COMPARISON
7445 #define TARGET_CANONICALIZE_COMPARISON spu_canonicalize_comparison
7446
7447 #undef TARGET_CAN_USE_DOLOOP_P
7448 #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
7449
7450 #undef TARGET_MODES_TIEABLE_P
7451 #define TARGET_MODES_TIEABLE_P spu_modes_tieable_p
7452
7453 #undef TARGET_HARD_REGNO_NREGS
7454 #define TARGET_HARD_REGNO_NREGS spu_hard_regno_nregs
7455
7456 #undef TARGET_CAN_CHANGE_MODE_CLASS
7457 #define TARGET_CAN_CHANGE_MODE_CLASS spu_can_change_mode_class
7458
7459 #undef TARGET_TRULY_NOOP_TRUNCATION
7460 #define TARGET_TRULY_NOOP_TRUNCATION spu_truly_noop_truncation
7461
7462 #undef TARGET_STATIC_RTX_ALIGNMENT
7463 #define TARGET_STATIC_RTX_ALIGNMENT spu_static_rtx_alignment
7464 #undef TARGET_CONSTANT_ALIGNMENT
7465 #define TARGET_CONSTANT_ALIGNMENT spu_constant_alignment
7466
7467 struct gcc_target targetm = TARGET_INITIALIZER;
7468
7194 #include "gt-spu.h" 7469 #include "gt-spu.h"