OSDN Git Service

* config/mcore/mcore.c Don't include assert.h.
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / spu.c
1 /* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
2
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
5    Software Foundation; either version 3 of the License, or (at your option) 
6    any later version.
7
8    This file is distributed in the hope that it will be useful, but WITHOUT
9    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11    for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with GCC; see the file COPYING3.  If not see
15    <http://www.gnu.org/licenses/>.  */
16
17 #include "config.h"
18 #include "system.h"
19 #include "coretypes.h"
20 #include "tm.h"
21 #include "rtl.h"
22 #include "regs.h"
23 #include "hard-reg-set.h"
24 #include "insn-config.h"
25 #include "conditions.h"
26 #include "insn-attr.h"
27 #include "flags.h"
28 #include "recog.h"
29 #include "obstack.h"
30 #include "tree.h"
31 #include "expr.h"
32 #include "optabs.h"
33 #include "except.h"
34 #include "function.h"
35 #include "output.h"
36 #include "basic-block.h"
37 #include "integrate.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"
45 #include "reload.h"
46 #include "cfglayout.h"
47 #include "sched-int.h"
48 #include "params.h"
49 #include "machmode.h"
50 #include "gimple.h"
51 #include "tm-constrs.h"
52 #include "ddg.h"
53 #include "sbitmap.h"
54 #include "timevar.h"
55 #include "df.h"
56
57 /* Builtin types, data and prototypes. */
58
59 enum spu_builtin_type_index
60 {
61   SPU_BTI_END_OF_PARAMS,
62
63   /* We create new type nodes for these. */
64   SPU_BTI_V16QI,
65   SPU_BTI_V8HI,
66   SPU_BTI_V4SI,
67   SPU_BTI_V2DI,
68   SPU_BTI_V4SF,
69   SPU_BTI_V2DF,
70   SPU_BTI_UV16QI,
71   SPU_BTI_UV8HI,
72   SPU_BTI_UV4SI,
73   SPU_BTI_UV2DI,
74
75   /* A 16-byte type. (Implemented with V16QI_type_node) */
76   SPU_BTI_QUADWORD,
77
78   /* These all correspond to intSI_type_node */
79   SPU_BTI_7,
80   SPU_BTI_S7,
81   SPU_BTI_U7,
82   SPU_BTI_S10,
83   SPU_BTI_S10_4,
84   SPU_BTI_U14,
85   SPU_BTI_16,
86   SPU_BTI_S16,
87   SPU_BTI_S16_2,
88   SPU_BTI_U16,
89   SPU_BTI_U16_2,
90   SPU_BTI_U18,
91
92   /* These correspond to the standard types */
93   SPU_BTI_INTQI, 
94   SPU_BTI_INTHI, 
95   SPU_BTI_INTSI, 
96   SPU_BTI_INTDI, 
97
98   SPU_BTI_UINTQI,
99   SPU_BTI_UINTHI,
100   SPU_BTI_UINTSI,
101   SPU_BTI_UINTDI,
102
103   SPU_BTI_FLOAT, 
104   SPU_BTI_DOUBLE,
105
106   SPU_BTI_VOID,   
107   SPU_BTI_PTR,   
108
109   SPU_BTI_MAX
110 };
111
112 #define V16QI_type_node               (spu_builtin_types[SPU_BTI_V16QI])
113 #define V8HI_type_node                (spu_builtin_types[SPU_BTI_V8HI])
114 #define V4SI_type_node                (spu_builtin_types[SPU_BTI_V4SI])
115 #define V2DI_type_node                (spu_builtin_types[SPU_BTI_V2DI])
116 #define V4SF_type_node                (spu_builtin_types[SPU_BTI_V4SF])
117 #define V2DF_type_node                (spu_builtin_types[SPU_BTI_V2DF])
118 #define unsigned_V16QI_type_node      (spu_builtin_types[SPU_BTI_UV16QI])
119 #define unsigned_V8HI_type_node       (spu_builtin_types[SPU_BTI_UV8HI])
120 #define unsigned_V4SI_type_node       (spu_builtin_types[SPU_BTI_UV4SI])
121 #define unsigned_V2DI_type_node       (spu_builtin_types[SPU_BTI_UV2DI])
122
123 static GTY(()) tree spu_builtin_types[SPU_BTI_MAX];
124
125 struct spu_builtin_range
126 {
127   int low, high;
128 };
129
130 static struct spu_builtin_range spu_builtin_range[] = {
131   {-0x40ll, 0x7fll},            /* SPU_BTI_7     */
132   {-0x40ll, 0x3fll},            /* SPU_BTI_S7    */
133   {0ll, 0x7fll},                /* SPU_BTI_U7    */
134   {-0x200ll, 0x1ffll},          /* SPU_BTI_S10   */
135   {-0x2000ll, 0x1fffll},        /* SPU_BTI_S10_4 */
136   {0ll, 0x3fffll},              /* SPU_BTI_U14   */
137   {-0x8000ll, 0xffffll},        /* SPU_BTI_16    */
138   {-0x8000ll, 0x7fffll},        /* SPU_BTI_S16   */
139   {-0x20000ll, 0x1ffffll},      /* SPU_BTI_S16_2 */
140   {0ll, 0xffffll},              /* SPU_BTI_U16   */
141   {0ll, 0x3ffffll},             /* SPU_BTI_U16_2 */
142   {0ll, 0x3ffffll},             /* SPU_BTI_U18   */
143 };
144
145 \f
146 /*  Target specific attribute specifications.  */
147 char regs_ever_allocated[FIRST_PSEUDO_REGISTER];
148
149 /*  Prototypes and external defs.  */
150 static void spu_option_override (void);
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);
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);
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 *);
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);
231 static void spu_trampoline_init (rtx, tree, rtx);
232 static void spu_conditional_register_usage (void);
233
234 /* Which instruction set architecture to use.  */
235 int spu_arch;
236 /* Which cpu are we tuning for.  */
237 int spu_tune;
238
239 /* The hardware requires 8 insns between a hint and the branch it
240    effects.  This variable describes how many rtl instructions the
241    compiler needs to see before inserting a hint, and then the compiler
242    will insert enough nops to make it at least 8 insns.  The default is
243    for the compiler to allow up to 2 nops be emitted.  The nops are
244    inserted in pairs, so we round down. */
245 int spu_hint_dist = (8*4) - (2*4);
246
247 /* Determines whether we run variable tracking in machine dependent
248    reorganization.  */
249 static int spu_flag_var_tracking;
250
251 enum spu_immediate {
252   SPU_NONE,
253   SPU_IL,
254   SPU_ILA,
255   SPU_ILH,
256   SPU_ILHU,
257   SPU_ORI,
258   SPU_ORHI,
259   SPU_ORBI,
260   SPU_IOHL
261 };
262 enum immediate_class
263 {
264   IC_POOL,                      /* constant pool */
265   IC_IL1,                       /* one il* instruction */
266   IC_IL2,                       /* both ilhu and iohl instructions */
267   IC_IL1s,                      /* one il* instruction */
268   IC_IL2s,                      /* both ilhu and iohl instructions */
269   IC_FSMBI,                     /* the fsmbi instruction */
270   IC_CPAT,                      /* one of the c*d instructions */
271   IC_FSMBI2                     /* fsmbi plus 1 other instruction */
272 };
273
274 static enum spu_immediate which_immediate_load (HOST_WIDE_INT val);
275 static enum spu_immediate which_logical_immediate (HOST_WIDE_INT val);
276 static int cpat_info(unsigned char *arr, int size, int *prun, int *pstart);
277 static enum immediate_class classify_immediate (rtx op,
278                                                 enum machine_mode mode);
279
280 static enum machine_mode spu_unwind_word_mode (void);
281
282 static enum machine_mode
283 spu_libgcc_cmp_return_mode (void);
284
285 static enum machine_mode
286 spu_libgcc_shift_count_mode (void);
287
288 /* Pointer mode for __ea references.  */
289 #define EAmode (spu_ea_model != 32 ? DImode : SImode)
290
291 \f
292 /*  Table of machine attributes.  */
293 static const struct attribute_spec spu_attribute_table[] =
294 {
295   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
296   { "naked",          0, 0, true,  false, false, spu_handle_fndecl_attribute },
297   { "spu_vector",     0, 0, false, true,  false, spu_handle_vector_attribute },
298   { NULL,             0, 0, false, false, false, NULL }
299 };
300 \f
301 /*  TARGET overrides.  */
302
303 #undef TARGET_ADDR_SPACE_POINTER_MODE
304 #define TARGET_ADDR_SPACE_POINTER_MODE spu_addr_space_pointer_mode
305
306 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
307 #define TARGET_ADDR_SPACE_ADDRESS_MODE spu_addr_space_address_mode
308
309 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
310 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
311   spu_addr_space_legitimate_address_p
312
313 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
314 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS spu_addr_space_legitimize_address
315
316 #undef TARGET_ADDR_SPACE_SUBSET_P
317 #define TARGET_ADDR_SPACE_SUBSET_P spu_addr_space_subset_p
318
319 #undef TARGET_ADDR_SPACE_CONVERT
320 #define TARGET_ADDR_SPACE_CONVERT spu_addr_space_convert
321
322 #undef TARGET_INIT_BUILTINS
323 #define TARGET_INIT_BUILTINS spu_init_builtins
324 #undef TARGET_BUILTIN_DECL
325 #define TARGET_BUILTIN_DECL spu_builtin_decl
326
327 #undef TARGET_EXPAND_BUILTIN
328 #define TARGET_EXPAND_BUILTIN spu_expand_builtin
329
330 #undef TARGET_UNWIND_WORD_MODE
331 #define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode
332
333 #undef TARGET_LEGITIMIZE_ADDRESS
334 #define TARGET_LEGITIMIZE_ADDRESS spu_legitimize_address
335
336 /* The current assembler doesn't like .4byte foo@ppu, so use the normal .long
337    and .quad for the debugger.  When it is known that the assembler is fixed,
338    these can be removed.  */
339 #undef TARGET_ASM_UNALIGNED_SI_OP
340 #define TARGET_ASM_UNALIGNED_SI_OP      "\t.long\t"
341
342 #undef TARGET_ASM_ALIGNED_DI_OP
343 #define TARGET_ASM_ALIGNED_DI_OP        "\t.quad\t"
344
345 /* The .8byte directive doesn't seem to work well for a 32 bit
346    architecture. */
347 #undef TARGET_ASM_UNALIGNED_DI_OP
348 #define TARGET_ASM_UNALIGNED_DI_OP NULL
349
350 #undef TARGET_RTX_COSTS
351 #define TARGET_RTX_COSTS spu_rtx_costs
352
353 #undef TARGET_ADDRESS_COST
354 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
355
356 #undef TARGET_SCHED_ISSUE_RATE
357 #define TARGET_SCHED_ISSUE_RATE spu_sched_issue_rate
358
359 #undef TARGET_SCHED_INIT_GLOBAL
360 #define TARGET_SCHED_INIT_GLOBAL spu_sched_init_global
361
362 #undef TARGET_SCHED_INIT
363 #define TARGET_SCHED_INIT spu_sched_init
364
365 #undef TARGET_SCHED_VARIABLE_ISSUE
366 #define TARGET_SCHED_VARIABLE_ISSUE spu_sched_variable_issue
367
368 #undef TARGET_SCHED_REORDER
369 #define TARGET_SCHED_REORDER spu_sched_reorder
370
371 #undef TARGET_SCHED_REORDER2
372 #define TARGET_SCHED_REORDER2 spu_sched_reorder
373
374 #undef TARGET_SCHED_ADJUST_COST
375 #define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost
376
377 #undef  TARGET_ATTRIBUTE_TABLE
378 #define TARGET_ATTRIBUTE_TABLE spu_attribute_table
379
380 #undef TARGET_ASM_INTEGER
381 #define TARGET_ASM_INTEGER spu_assemble_integer
382
383 #undef TARGET_SCALAR_MODE_SUPPORTED_P
384 #define TARGET_SCALAR_MODE_SUPPORTED_P  spu_scalar_mode_supported_p
385
386 #undef TARGET_VECTOR_MODE_SUPPORTED_P
387 #define TARGET_VECTOR_MODE_SUPPORTED_P  spu_vector_mode_supported_p
388
389 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
390 #define TARGET_FUNCTION_OK_FOR_SIBCALL spu_function_ok_for_sibcall
391
392 #undef TARGET_ASM_GLOBALIZE_LABEL
393 #define TARGET_ASM_GLOBALIZE_LABEL spu_asm_globalize_label
394
395 #undef TARGET_PASS_BY_REFERENCE
396 #define TARGET_PASS_BY_REFERENCE spu_pass_by_reference
397
398 #undef TARGET_FUNCTION_ARG
399 #define TARGET_FUNCTION_ARG spu_function_arg
400
401 #undef TARGET_FUNCTION_ARG_ADVANCE
402 #define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance
403
404 #undef TARGET_MUST_PASS_IN_STACK
405 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
406
407 #undef TARGET_BUILD_BUILTIN_VA_LIST
408 #define TARGET_BUILD_BUILTIN_VA_LIST spu_build_builtin_va_list
409
410 #undef TARGET_EXPAND_BUILTIN_VA_START
411 #define TARGET_EXPAND_BUILTIN_VA_START spu_va_start
412
413 #undef TARGET_SETUP_INCOMING_VARARGS
414 #define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs
415
416 #undef TARGET_MACHINE_DEPENDENT_REORG
417 #define TARGET_MACHINE_DEPENDENT_REORG spu_machine_dependent_reorg
418
419 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
420 #define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr
421
422 #undef TARGET_DEFAULT_TARGET_FLAGS
423 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT)
424
425 #undef TARGET_INIT_LIBFUNCS
426 #define TARGET_INIT_LIBFUNCS spu_init_libfuncs
427
428 #undef TARGET_RETURN_IN_MEMORY
429 #define TARGET_RETURN_IN_MEMORY spu_return_in_memory
430
431 #undef  TARGET_ENCODE_SECTION_INFO
432 #define TARGET_ENCODE_SECTION_INFO spu_encode_section_info
433
434 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
435 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN spu_builtin_mul_widen_even
436
437 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
438 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD spu_builtin_mul_widen_odd
439
440 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
441 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD spu_builtin_mask_for_load
442
443 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
444 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST spu_builtin_vectorization_cost
445
446 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
447 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable
448
449 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
450 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM spu_builtin_vec_perm
451
452 #undef TARGET_LIBGCC_CMP_RETURN_MODE
453 #define TARGET_LIBGCC_CMP_RETURN_MODE spu_libgcc_cmp_return_mode
454
455 #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
456 #define TARGET_LIBGCC_SHIFT_COUNT_MODE spu_libgcc_shift_count_mode
457
458 #undef TARGET_SCHED_SMS_RES_MII
459 #define TARGET_SCHED_SMS_RES_MII spu_sms_res_mii
460
461 #undef TARGET_ASM_FILE_START
462 #define TARGET_ASM_FILE_START asm_file_start
463
464 #undef TARGET_SECTION_TYPE_FLAGS
465 #define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags
466
467 #undef TARGET_ASM_SELECT_SECTION
468 #define TARGET_ASM_SELECT_SECTION  spu_select_section
469
470 #undef TARGET_ASM_UNIQUE_SECTION
471 #define TARGET_ASM_UNIQUE_SECTION  spu_unique_section
472
473 #undef TARGET_LEGITIMATE_ADDRESS_P
474 #define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p
475
476 #undef TARGET_TRAMPOLINE_INIT
477 #define TARGET_TRAMPOLINE_INIT spu_trampoline_init
478
479 #undef TARGET_OPTION_OVERRIDE
480 #define TARGET_OPTION_OVERRIDE spu_option_override
481
482 #undef TARGET_OPTION_INIT_STRUCT
483 #define TARGET_OPTION_INIT_STRUCT spu_option_init_struct
484
485 #undef TARGET_OPTION_DEFAULT_PARAMS
486 #define TARGET_OPTION_DEFAULT_PARAMS spu_option_default_params
487
488 #undef TARGET_EXCEPT_UNWIND_INFO
489 #define TARGET_EXCEPT_UNWIND_INFO  sjlj_except_unwind_info
490
491 #undef TARGET_CONDITIONAL_REGISTER_USAGE
492 #define TARGET_CONDITIONAL_REGISTER_USAGE spu_conditional_register_usage
493
494 struct gcc_target targetm = TARGET_INITIALIZER;
495
496 static void
497 spu_option_init_struct (struct gcc_options *opts)
498 {
499   /* With so many registers this is better on by default. */
500   opts->x_flag_rename_registers = 1;
501 }
502
503 /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
504 static void
505 spu_option_default_params (void)
506 {
507   /* Override some of the default param values.  With so many registers
508      larger values are better for these params.  */
509   set_default_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 128);
510 }
511
512 /* Implement TARGET_OPTION_OVERRIDE.  */
513 static void
514 spu_option_override (void)
515 {
516   /* Small loops will be unpeeled at -O3.  For SPU it is more important
517      to keep code small by default.  */
518   if (!flag_unroll_loops && !flag_peel_loops)
519     maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 1,
520                            global_options.x_param_values,
521                            global_options_set.x_param_values);
522
523   flag_omit_frame_pointer = 1;
524
525   /* Functions must be 8 byte aligned so we correctly handle dual issue */
526   if (align_functions < 8)
527     align_functions = 8;
528
529   spu_hint_dist = 8*4 - spu_max_nops*4;
530   if (spu_hint_dist < 0) 
531     spu_hint_dist = 0;
532
533   if (spu_fixed_range_string)
534     fix_range (spu_fixed_range_string);
535
536   /* Determine processor architectural level.  */
537   if (spu_arch_string)
538     {
539       if (strcmp (&spu_arch_string[0], "cell") == 0)
540         spu_arch = PROCESSOR_CELL;
541       else if (strcmp (&spu_arch_string[0], "celledp") == 0)
542         spu_arch = PROCESSOR_CELLEDP;
543       else
544         error ("unknown architecture %qs", &spu_arch_string[0]);
545     }
546
547   /* Determine processor to tune for.  */
548   if (spu_tune_string)
549     {
550       if (strcmp (&spu_tune_string[0], "cell") == 0)
551         spu_tune = PROCESSOR_CELL;
552       else if (strcmp (&spu_tune_string[0], "celledp") == 0)
553         spu_tune = PROCESSOR_CELLEDP;
554       else
555         error ("unknown architecture %qs", &spu_tune_string[0]);
556     }
557
558   /* Change defaults according to the processor architecture.  */
559   if (spu_arch == PROCESSOR_CELLEDP)
560     {
561       /* If no command line option has been otherwise specified, change
562          the default to -mno-safe-hints on celledp -- only the original
563          Cell/B.E. processors require this workaround.  */
564       if (!(target_flags_explicit & MASK_SAFE_HINTS))
565         target_flags &= ~MASK_SAFE_HINTS;
566     }
567
568   REAL_MODE_FORMAT (SFmode) = &spu_single_format;
569 }
570 \f
571 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
572    struct attribute_spec.handler.  */
573
574 /* True if MODE is valid for the target.  By "valid", we mean able to
575    be manipulated in non-trivial ways.  In particular, this means all
576    the arithmetic is supported.  */
577 static bool
578 spu_scalar_mode_supported_p (enum machine_mode mode)
579 {
580   switch (mode)
581     {
582     case QImode:
583     case HImode:
584     case SImode:
585     case SFmode:
586     case DImode:
587     case TImode:
588     case DFmode:
589       return true;
590
591     default:
592       return false;
593     }
594 }
595
596 /* Similarly for vector modes.  "Supported" here is less strict.  At
597    least some operations are supported; need to check optabs or builtins
598    for further details.  */
599 static bool
600 spu_vector_mode_supported_p (enum machine_mode mode)
601 {
602   switch (mode)
603     {
604     case V16QImode:
605     case V8HImode:
606     case V4SImode:
607     case V2DImode:
608     case V4SFmode:
609     case V2DFmode:
610       return true;
611
612     default:
613       return false;
614     }
615 }
616
617 /* GCC assumes that in a paradoxical SUBREG the inner mode occupies the
618    least significant bytes of the outer mode.  This function returns
619    TRUE for the SUBREG's where this is correct.  */
620 int
621 valid_subreg (rtx op)
622 {
623   enum machine_mode om = GET_MODE (op);
624   enum machine_mode im = GET_MODE (SUBREG_REG (op));
625   return om != VOIDmode && im != VOIDmode
626     && (GET_MODE_SIZE (im) == GET_MODE_SIZE (om)
627         || (GET_MODE_SIZE (im) <= 4 && GET_MODE_SIZE (om) <= 4)
628         || (GET_MODE_SIZE (im) >= 16 && GET_MODE_SIZE (om) >= 16));
629 }
630
631 /* When insv and ext[sz]v ar passed a TI SUBREG, we want to strip it off
632    and adjust the start offset.  */
633 static rtx
634 adjust_operand (rtx op, HOST_WIDE_INT * start)
635 {
636   enum machine_mode mode;
637   int op_size;
638   /* Strip any paradoxical SUBREG.  */
639   if (GET_CODE (op) == SUBREG
640       && (GET_MODE_BITSIZE (GET_MODE (op))
641           > GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op)))))
642     {
643       if (start)
644         *start -=
645           GET_MODE_BITSIZE (GET_MODE (op)) -
646           GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op)));
647       op = SUBREG_REG (op);
648     }
649   /* If it is smaller than SI, assure a SUBREG */
650   op_size = GET_MODE_BITSIZE (GET_MODE (op));
651   if (op_size < 32)
652     {
653       if (start)
654         *start += 32 - op_size;
655       op_size = 32;
656     }
657   /* If it is not a MODE_INT (and/or it is smaller than SI) add a SUBREG. */
658   mode = mode_for_size (op_size, MODE_INT, 0);
659   if (mode != GET_MODE (op))
660     op = gen_rtx_SUBREG (mode, op, 0);
661   return op;
662 }
663
664 void
665 spu_expand_extv (rtx ops[], int unsignedp)
666 {
667   rtx dst = ops[0], src = ops[1];
668   HOST_WIDE_INT width = INTVAL (ops[2]);
669   HOST_WIDE_INT start = INTVAL (ops[3]);
670   HOST_WIDE_INT align_mask;
671   rtx s0, s1, mask, r0;
672
673   gcc_assert (REG_P (dst) && GET_MODE (dst) == TImode);
674
675   if (MEM_P (src))
676     {
677       /* First, determine if we need 1 TImode load or 2.  We need only 1
678          if the bits being extracted do not cross the alignment boundary
679          as determined by the MEM and its address. */
680
681       align_mask = -MEM_ALIGN (src);
682       if ((start & align_mask) == ((start + width - 1) & align_mask))
683         {
684           /* Alignment is sufficient for 1 load. */
685           s0 = gen_reg_rtx (TImode);
686           r0 = spu_expand_load (s0, 0, src, start / 8);
687           start &= 7;
688           if (r0)
689             emit_insn (gen_rotqby_ti (s0, s0, r0));
690         }
691       else
692         {
693           /* Need 2 loads. */
694           s0 = gen_reg_rtx (TImode);
695           s1 = gen_reg_rtx (TImode);
696           r0 = spu_expand_load (s0, s1, src, start / 8);
697           start &= 7;
698
699           gcc_assert (start + width <= 128);
700           if (r0)
701             {
702               rtx r1 = gen_reg_rtx (SImode);
703               mask = gen_reg_rtx (TImode);
704               emit_move_insn (mask, GEN_INT (-1));
705               emit_insn (gen_rotqby_ti (s0, s0, r0));
706               emit_insn (gen_rotqby_ti (s1, s1, r0));
707               if (GET_CODE (r0) == CONST_INT)
708                 r1 = GEN_INT (INTVAL (r0) & 15);
709               else
710                 emit_insn (gen_andsi3 (r1, r0, GEN_INT (15)));
711               emit_insn (gen_shlqby_ti (mask, mask, r1));
712               emit_insn (gen_selb (s0, s1, s0, mask));
713             }
714         }
715
716     }
717   else if (GET_CODE (src) == SUBREG)
718     {
719       rtx r = SUBREG_REG (src);
720       gcc_assert (REG_P (r) && SCALAR_INT_MODE_P (GET_MODE (r)));
721       s0 = gen_reg_rtx (TImode);
722       if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode))
723         emit_insn (gen_rtx_SET (VOIDmode, s0, gen_rtx_ZERO_EXTEND (TImode, r)));
724       else
725         emit_move_insn (s0, src);
726     }
727   else 
728     {
729       gcc_assert (REG_P (src) && GET_MODE (src) == TImode);
730       s0 = gen_reg_rtx (TImode);
731       emit_move_insn (s0, src);
732     }
733
734   /* Now s0 is TImode and contains the bits to extract at start. */
735
736   if (start)
737     emit_insn (gen_rotlti3 (s0, s0, GEN_INT (start)));
738
739   if (128 - width)
740     {
741       tree c = build_int_cst (NULL_TREE, 128 - width);
742       s0 = expand_shift (RSHIFT_EXPR, TImode, s0, c, s0, unsignedp);
743     }
744
745   emit_move_insn (dst, s0);
746 }
747
748 void
749 spu_expand_insv (rtx ops[])
750 {
751   HOST_WIDE_INT width = INTVAL (ops[1]);
752   HOST_WIDE_INT start = INTVAL (ops[2]);
753   HOST_WIDE_INT maskbits;
754   enum machine_mode dst_mode;
755   rtx dst = ops[0], src = ops[3];
756   int dst_size;
757   rtx mask;
758   rtx shift_reg;
759   int shift;
760
761
762   if (GET_CODE (ops[0]) == MEM)
763     dst = gen_reg_rtx (TImode);
764   else
765     dst = adjust_operand (dst, &start);
766   dst_mode = GET_MODE (dst);
767   dst_size = GET_MODE_BITSIZE (GET_MODE (dst));
768
769   if (CONSTANT_P (src))
770     {
771       enum machine_mode m =
772         (width <= 32 ? SImode : width <= 64 ? DImode : TImode);
773       src = force_reg (m, convert_to_mode (m, src, 0));
774     }
775   src = adjust_operand (src, 0);
776
777   mask = gen_reg_rtx (dst_mode);
778   shift_reg = gen_reg_rtx (dst_mode);
779   shift = dst_size - start - width;
780
781   /* It's not safe to use subreg here because the compiler assumes
782      that the SUBREG_REG is right justified in the SUBREG. */
783   convert_move (shift_reg, src, 1);
784
785   if (shift > 0)
786     {
787       switch (dst_mode)
788         {
789         case SImode:
790           emit_insn (gen_ashlsi3 (shift_reg, shift_reg, GEN_INT (shift)));
791           break;
792         case DImode:
793           emit_insn (gen_ashldi3 (shift_reg, shift_reg, GEN_INT (shift)));
794           break;
795         case TImode:
796           emit_insn (gen_ashlti3 (shift_reg, shift_reg, GEN_INT (shift)));
797           break;
798         default:
799           abort ();
800         }
801     }
802   else if (shift < 0)
803     abort ();
804
805   switch (dst_size)
806     {
807     case 32:
808       maskbits = (-1ll << (32 - width - start));
809       if (start)
810         maskbits += (1ll << (32 - start));
811       emit_move_insn (mask, GEN_INT (maskbits));
812       break;
813     case 64:
814       maskbits = (-1ll << (64 - width - start));
815       if (start)
816         maskbits += (1ll << (64 - start));
817       emit_move_insn (mask, GEN_INT (maskbits));
818       break;
819     case 128:
820       {
821         unsigned char arr[16];
822         int i = start / 8;
823         memset (arr, 0, sizeof (arr));
824         arr[i] = 0xff >> (start & 7);
825         for (i++; i <= (start + width - 1) / 8; i++)
826           arr[i] = 0xff;
827         arr[i - 1] &= 0xff << (7 - ((start + width - 1) & 7));
828         emit_move_insn (mask, array_to_constant (TImode, arr));
829       }
830       break;
831     default:
832       abort ();
833     }
834   if (GET_CODE (ops[0]) == MEM)
835     {
836       rtx low = gen_reg_rtx (SImode);
837       rtx rotl = gen_reg_rtx (SImode);
838       rtx mask0 = gen_reg_rtx (TImode);
839       rtx addr;
840       rtx addr0;
841       rtx addr1;
842       rtx mem;
843
844       addr = force_reg (Pmode, XEXP (ops[0], 0));
845       addr0 = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
846       emit_insn (gen_andsi3 (low, addr, GEN_INT (15)));
847       emit_insn (gen_negsi2 (rotl, low));
848       emit_insn (gen_rotqby_ti (shift_reg, shift_reg, rotl));
849       emit_insn (gen_rotqmby_ti (mask0, mask, rotl));
850       mem = change_address (ops[0], TImode, addr0);
851       set_mem_alias_set (mem, 0);
852       emit_move_insn (dst, mem);
853       emit_insn (gen_selb (dst, dst, shift_reg, mask0));
854       if (start + width > MEM_ALIGN (ops[0]))
855         {
856           rtx shl = gen_reg_rtx (SImode);
857           rtx mask1 = gen_reg_rtx (TImode);
858           rtx dst1 = gen_reg_rtx (TImode);
859           rtx mem1;
860           addr1 = plus_constant (addr, 16);
861           addr1 = gen_rtx_AND (Pmode, addr1, GEN_INT (-16));
862           emit_insn (gen_subsi3 (shl, GEN_INT (16), low));
863           emit_insn (gen_shlqby_ti (mask1, mask, shl));
864           mem1 = change_address (ops[0], TImode, addr1);
865           set_mem_alias_set (mem1, 0);
866           emit_move_insn (dst1, mem1);
867           emit_insn (gen_selb (dst1, dst1, shift_reg, mask1));
868           emit_move_insn (mem1, dst1);
869         }
870       emit_move_insn (mem, dst);
871     }
872   else
873     emit_insn (gen_selb (dst, copy_rtx (dst), shift_reg, mask));
874 }
875
876
877 int
878 spu_expand_block_move (rtx ops[])
879 {
880   HOST_WIDE_INT bytes, align, offset;
881   rtx src, dst, sreg, dreg, target;
882   int i;
883   if (GET_CODE (ops[2]) != CONST_INT
884       || GET_CODE (ops[3]) != CONST_INT
885       || INTVAL (ops[2]) > (HOST_WIDE_INT) (MOVE_RATIO (optimize_insn_for_speed_p ()) * 8))
886     return 0;
887
888   bytes = INTVAL (ops[2]);
889   align = INTVAL (ops[3]);
890
891   if (bytes <= 0)
892     return 1;
893
894   dst = ops[0];
895   src = ops[1];
896
897   if (align == 16)
898     {
899       for (offset = 0; offset + 16 <= bytes; offset += 16)
900         {
901           dst = adjust_address (ops[0], V16QImode, offset);
902           src = adjust_address (ops[1], V16QImode, offset);
903           emit_move_insn (dst, src);
904         }
905       if (offset < bytes)
906         {
907           rtx mask;
908           unsigned char arr[16] = { 0 };
909           for (i = 0; i < bytes - offset; i++)
910             arr[i] = 0xff;
911           dst = adjust_address (ops[0], V16QImode, offset);
912           src = adjust_address (ops[1], V16QImode, offset);
913           mask = gen_reg_rtx (V16QImode);
914           sreg = gen_reg_rtx (V16QImode);
915           dreg = gen_reg_rtx (V16QImode);
916           target = gen_reg_rtx (V16QImode);
917           emit_move_insn (mask, array_to_constant (V16QImode, arr));
918           emit_move_insn (dreg, dst);
919           emit_move_insn (sreg, src);
920           emit_insn (gen_selb (target, dreg, sreg, mask));
921           emit_move_insn (dst, target);
922         }
923       return 1;
924     }
925   return 0;
926 }
927
928 enum spu_comp_code
929 { SPU_EQ, SPU_GT, SPU_GTU };
930
931 int spu_comp_icode[12][3] = {
932  {CODE_FOR_ceq_qi, CODE_FOR_cgt_qi, CODE_FOR_clgt_qi},
933  {CODE_FOR_ceq_hi, CODE_FOR_cgt_hi, CODE_FOR_clgt_hi},
934  {CODE_FOR_ceq_si, CODE_FOR_cgt_si, CODE_FOR_clgt_si},
935  {CODE_FOR_ceq_di, CODE_FOR_cgt_di, CODE_FOR_clgt_di},
936  {CODE_FOR_ceq_ti, CODE_FOR_cgt_ti, CODE_FOR_clgt_ti},
937  {CODE_FOR_ceq_sf, CODE_FOR_cgt_sf, 0},
938  {CODE_FOR_ceq_df, CODE_FOR_cgt_df, 0},
939  {CODE_FOR_ceq_v16qi, CODE_FOR_cgt_v16qi, CODE_FOR_clgt_v16qi},
940  {CODE_FOR_ceq_v8hi,  CODE_FOR_cgt_v8hi,  CODE_FOR_clgt_v8hi},
941  {CODE_FOR_ceq_v4si,  CODE_FOR_cgt_v4si,  CODE_FOR_clgt_v4si},
942  {CODE_FOR_ceq_v4sf,  CODE_FOR_cgt_v4sf, 0},
943  {CODE_FOR_ceq_v2df,  CODE_FOR_cgt_v2df, 0},
944 };
945
946 /* Generate a compare for CODE.  Return a brand-new rtx that represents
947    the result of the compare.   GCC can figure this out too if we don't
948    provide all variations of compares, but GCC always wants to use
949    WORD_MODE, we can generate better code in most cases if we do it
950    ourselves.  */
951 void
952 spu_emit_branch_or_set (int is_set, rtx cmp, rtx operands[])
953 {
954   int reverse_compare = 0;
955   int reverse_test = 0;
956   rtx compare_result, eq_result;
957   rtx comp_rtx, eq_rtx;
958   enum machine_mode comp_mode;
959   enum machine_mode op_mode;
960   enum spu_comp_code scode, eq_code;
961   enum insn_code ior_code;
962   enum rtx_code code = GET_CODE (cmp);
963   rtx op0 = XEXP (cmp, 0);
964   rtx op1 = XEXP (cmp, 1);
965   int index;
966   int eq_test = 0;
967
968   /* When op1 is a CONST_INT change (X >= C) to (X > C-1),
969      and so on, to keep the constant in operand 1. */
970   if (GET_CODE (op1) == CONST_INT)
971     {
972       HOST_WIDE_INT val = INTVAL (op1) - 1;
973       if (trunc_int_for_mode (val, GET_MODE (op0)) == val)
974         switch (code)
975           {
976           case GE:
977             op1 = GEN_INT (val);
978             code = GT;
979             break;
980           case LT:
981             op1 = GEN_INT (val);
982             code = LE;
983             break;
984           case GEU:
985             op1 = GEN_INT (val);
986             code = GTU;
987             break;
988           case LTU:
989             op1 = GEN_INT (val);
990             code = LEU;
991             break;
992           default:
993             break;
994           }
995     }
996
997   comp_mode = SImode;
998   op_mode = GET_MODE (op0);
999
1000   switch (code)
1001     {
1002     case GE:
1003       scode = SPU_GT;
1004       if (HONOR_NANS (op_mode))
1005         {
1006           reverse_compare = 0;
1007           reverse_test = 0;
1008           eq_test = 1;
1009           eq_code = SPU_EQ;
1010         }
1011       else
1012         {
1013           reverse_compare = 1;
1014           reverse_test = 1;
1015         }
1016       break;
1017     case LE:
1018       scode = SPU_GT;
1019       if (HONOR_NANS (op_mode))
1020         {
1021           reverse_compare = 1;
1022           reverse_test = 0;
1023           eq_test = 1;
1024           eq_code = SPU_EQ;
1025         }
1026       else
1027         {
1028           reverse_compare = 0;
1029           reverse_test = 1;
1030         }
1031       break;
1032     case LT:
1033       reverse_compare = 1;
1034       reverse_test = 0;
1035       scode = SPU_GT;
1036       break;
1037     case GEU:
1038       reverse_compare = 1;
1039       reverse_test = 1;
1040       scode = SPU_GTU;
1041       break;
1042     case LEU:
1043       reverse_compare = 0;
1044       reverse_test = 1;
1045       scode = SPU_GTU;
1046       break;
1047     case LTU:
1048       reverse_compare = 1;
1049       reverse_test = 0;
1050       scode = SPU_GTU;
1051       break;
1052     case NE:
1053       reverse_compare = 0;
1054       reverse_test = 1;
1055       scode = SPU_EQ;
1056       break;
1057
1058     case EQ:
1059       scode = SPU_EQ;
1060       break;
1061     case GT:
1062       scode = SPU_GT;
1063       break;
1064     case GTU:
1065       scode = SPU_GTU;
1066       break;
1067     default:
1068       scode = SPU_EQ;
1069       break;
1070     }
1071
1072   switch (op_mode)
1073     {
1074     case QImode:
1075       index = 0;
1076       comp_mode = QImode;
1077       break;
1078     case HImode:
1079       index = 1;
1080       comp_mode = HImode;
1081       break;
1082     case SImode:
1083       index = 2;
1084       break;
1085     case DImode:
1086       index = 3;
1087       break;
1088     case TImode:
1089       index = 4;
1090       break;
1091     case SFmode:
1092       index = 5;
1093       break;
1094     case DFmode:
1095       index = 6;
1096       break;
1097     case V16QImode:
1098       index = 7;
1099       comp_mode = op_mode;
1100       break;
1101     case V8HImode:
1102       index = 8;
1103       comp_mode = op_mode;
1104       break;
1105     case V4SImode:
1106       index = 9;
1107       comp_mode = op_mode;
1108       break;
1109     case V4SFmode:
1110       index = 10;
1111       comp_mode = V4SImode;
1112       break;
1113     case V2DFmode:
1114       index = 11;
1115       comp_mode = V2DImode;
1116       break;
1117     case V2DImode:
1118     default:
1119       abort ();
1120     }
1121
1122   if (GET_MODE (op1) == DFmode
1123       && (scode != SPU_GT && scode != SPU_EQ))
1124     abort ();
1125
1126   if (is_set == 0 && op1 == const0_rtx
1127       && (GET_MODE (op0) == SImode
1128           || GET_MODE (op0) == HImode) && scode == SPU_EQ)
1129     {
1130       /* Don't need to set a register with the result when we are 
1131          comparing against zero and branching. */
1132       reverse_test = !reverse_test;
1133       compare_result = op0;
1134     }
1135   else
1136     {
1137       compare_result = gen_reg_rtx (comp_mode);
1138
1139       if (reverse_compare)
1140         {
1141           rtx t = op1;
1142           op1 = op0;
1143           op0 = t;
1144         }
1145
1146       if (spu_comp_icode[index][scode] == 0)
1147         abort ();
1148
1149       if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate)
1150           (op0, op_mode))
1151         op0 = force_reg (op_mode, op0);
1152       if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate)
1153           (op1, op_mode))
1154         op1 = force_reg (op_mode, op1);
1155       comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result,
1156                                                          op0, op1);
1157       if (comp_rtx == 0)
1158         abort ();
1159       emit_insn (comp_rtx);
1160
1161       if (eq_test)
1162         {
1163           eq_result = gen_reg_rtx (comp_mode);
1164           eq_rtx = GEN_FCN (spu_comp_icode[index][eq_code]) (eq_result,
1165                                                              op0, op1);
1166           if (eq_rtx == 0)
1167             abort ();
1168           emit_insn (eq_rtx);
1169           ior_code = optab_handler (ior_optab, comp_mode);
1170           gcc_assert (ior_code != CODE_FOR_nothing);
1171           emit_insn (GEN_FCN (ior_code)
1172                      (compare_result, compare_result, eq_result));
1173         }
1174     }
1175
1176   if (is_set == 0)
1177     {
1178       rtx bcomp;
1179       rtx loc_ref;
1180
1181       /* We don't have branch on QI compare insns, so we convert the
1182          QI compare result to a HI result. */
1183       if (comp_mode == QImode)
1184         {
1185           rtx old_res = compare_result;
1186           compare_result = gen_reg_rtx (HImode);
1187           comp_mode = HImode;
1188           emit_insn (gen_extendqihi2 (compare_result, old_res));
1189         }
1190
1191       if (reverse_test)
1192         bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx);
1193       else
1194         bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx);
1195
1196       loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1197       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1198                                    gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1199                                                          loc_ref, pc_rtx)));
1200     }
1201   else if (is_set == 2)
1202     {
1203       rtx target = operands[0];
1204       int compare_size = GET_MODE_BITSIZE (comp_mode);
1205       int target_size = GET_MODE_BITSIZE (GET_MODE (target));
1206       enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0);
1207       rtx select_mask;
1208       rtx op_t = operands[2];
1209       rtx op_f = operands[3];
1210
1211       /* The result of the comparison can be SI, HI or QI mode.  Create a
1212          mask based on that result. */
1213       if (target_size > compare_size)
1214         {
1215           select_mask = gen_reg_rtx (mode);
1216           emit_insn (gen_extend_compare (select_mask, compare_result));
1217         }
1218       else if (target_size < compare_size)
1219         select_mask =
1220           gen_rtx_SUBREG (mode, compare_result,
1221                           (compare_size - target_size) / BITS_PER_UNIT);
1222       else if (comp_mode != mode)
1223         select_mask = gen_rtx_SUBREG (mode, compare_result, 0);
1224       else
1225         select_mask = compare_result;
1226
1227       if (GET_MODE (target) != GET_MODE (op_t)
1228           || GET_MODE (target) != GET_MODE (op_f))
1229         abort ();
1230
1231       if (reverse_test)
1232         emit_insn (gen_selb (target, op_t, op_f, select_mask));
1233       else
1234         emit_insn (gen_selb (target, op_f, op_t, select_mask));
1235     }
1236   else
1237     {
1238       rtx target = operands[0];
1239       if (reverse_test)
1240         emit_insn (gen_rtx_SET (VOIDmode, compare_result,
1241                                 gen_rtx_NOT (comp_mode, compare_result)));
1242       if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode)
1243         emit_insn (gen_extendhisi2 (target, compare_result));
1244       else if (GET_MODE (target) == SImode
1245                && GET_MODE (compare_result) == QImode)
1246         emit_insn (gen_extend_compare (target, compare_result));
1247       else
1248         emit_move_insn (target, compare_result);
1249     }
1250 }
1251
1252 HOST_WIDE_INT
1253 const_double_to_hwint (rtx x)
1254 {
1255   HOST_WIDE_INT val;
1256   REAL_VALUE_TYPE rv;
1257   if (GET_MODE (x) == SFmode)
1258     {
1259       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1260       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1261     }
1262   else if (GET_MODE (x) == DFmode)
1263     {
1264       long l[2];
1265       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1266       REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1267       val = l[0];
1268       val = (val << 32) | (l[1] & 0xffffffff);
1269     }
1270   else
1271     abort ();
1272   return val;
1273 }
1274
1275 rtx
1276 hwint_to_const_double (enum machine_mode mode, HOST_WIDE_INT v)
1277 {
1278   long tv[2];
1279   REAL_VALUE_TYPE rv;
1280   gcc_assert (mode == SFmode || mode == DFmode);
1281
1282   if (mode == SFmode)
1283     tv[0] = (v << 32) >> 32;
1284   else if (mode == DFmode)
1285     {
1286       tv[1] = (v << 32) >> 32;
1287       tv[0] = v >> 32;
1288     }
1289   real_from_target (&rv, tv, mode);
1290   return CONST_DOUBLE_FROM_REAL_VALUE (rv, mode);
1291 }
1292
1293 void
1294 print_operand_address (FILE * file, register rtx addr)
1295 {
1296   rtx reg;
1297   rtx offset;
1298
1299   if (GET_CODE (addr) == AND
1300       && GET_CODE (XEXP (addr, 1)) == CONST_INT
1301       && INTVAL (XEXP (addr, 1)) == -16)
1302     addr = XEXP (addr, 0);
1303
1304   switch (GET_CODE (addr))
1305     {
1306     case REG:
1307       fprintf (file, "0(%s)", reg_names[REGNO (addr)]);
1308       break;
1309
1310     case PLUS:
1311       reg = XEXP (addr, 0);
1312       offset = XEXP (addr, 1);
1313       if (GET_CODE (offset) == REG)
1314         {
1315           fprintf (file, "%s,%s", reg_names[REGNO (reg)],
1316                    reg_names[REGNO (offset)]);
1317         }
1318       else if (GET_CODE (offset) == CONST_INT)
1319         {
1320           fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
1321                    INTVAL (offset), reg_names[REGNO (reg)]);
1322         }
1323       else
1324         abort ();
1325       break;
1326
1327     case CONST:
1328     case LABEL_REF:
1329     case SYMBOL_REF:
1330     case CONST_INT:
1331       output_addr_const (file, addr);
1332       break;
1333
1334     default:
1335       debug_rtx (addr);
1336       abort ();
1337     }
1338 }
1339
1340 void
1341 print_operand (FILE * file, rtx x, int code)
1342 {
1343   enum machine_mode mode = GET_MODE (x);
1344   HOST_WIDE_INT val;
1345   unsigned char arr[16];
1346   int xcode = GET_CODE (x);
1347   int i, info;
1348   if (GET_MODE (x) == VOIDmode)
1349     switch (code)
1350       {
1351       case 'L':                 /* 128 bits, signed */
1352       case 'm':                 /* 128 bits, signed */
1353       case 'T':                 /* 128 bits, signed */
1354       case 't':                 /* 128 bits, signed */
1355         mode = TImode;
1356         break;
1357       case 'K':                 /* 64 bits, signed */
1358       case 'k':                 /* 64 bits, signed */
1359       case 'D':                 /* 64 bits, signed */
1360       case 'd':                 /* 64 bits, signed */
1361         mode = DImode;
1362         break;
1363       case 'J':                 /* 32 bits, signed */
1364       case 'j':                 /* 32 bits, signed */
1365       case 's':                 /* 32 bits, signed */
1366       case 'S':                 /* 32 bits, signed */
1367         mode = SImode;
1368         break;
1369       }
1370   switch (code)
1371     {
1372
1373     case 'j':                   /* 32 bits, signed */
1374     case 'k':                   /* 64 bits, signed */
1375     case 'm':                   /* 128 bits, signed */
1376       if (xcode == CONST_INT
1377           || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
1378         {
1379           gcc_assert (logical_immediate_p (x, mode));
1380           constant_to_array (mode, x, arr);
1381           val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
1382           val = trunc_int_for_mode (val, SImode);
1383           switch (which_logical_immediate (val))
1384           {
1385           case SPU_ORI:
1386             break;
1387           case SPU_ORHI:
1388             fprintf (file, "h");
1389             break;
1390           case SPU_ORBI:
1391             fprintf (file, "b");
1392             break;
1393           default:
1394             gcc_unreachable();
1395           }
1396         }
1397       else
1398         gcc_unreachable();
1399       return;
1400
1401     case 'J':                   /* 32 bits, signed */
1402     case 'K':                   /* 64 bits, signed */
1403     case 'L':                   /* 128 bits, signed */
1404       if (xcode == CONST_INT
1405           || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
1406         {
1407           gcc_assert (logical_immediate_p (x, mode)
1408                       || iohl_immediate_p (x, mode));
1409           constant_to_array (mode, x, arr);
1410           val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
1411           val = trunc_int_for_mode (val, SImode);
1412           switch (which_logical_immediate (val))
1413           {
1414           case SPU_ORI:
1415           case SPU_IOHL:
1416             break;
1417           case SPU_ORHI:
1418             val = trunc_int_for_mode (val, HImode);
1419             break;
1420           case SPU_ORBI:
1421             val = trunc_int_for_mode (val, QImode);
1422             break;
1423           default:
1424             gcc_unreachable();
1425           }
1426           fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
1427         }
1428       else
1429         gcc_unreachable();
1430       return;
1431
1432     case 't':                   /* 128 bits, signed */
1433     case 'd':                   /* 64 bits, signed */
1434     case 's':                   /* 32 bits, signed */
1435       if (CONSTANT_P (x))
1436         {
1437           enum immediate_class c = classify_immediate (x, mode);
1438           switch (c)
1439             {
1440             case IC_IL1:
1441               constant_to_array (mode, x, arr);
1442               val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
1443               val = trunc_int_for_mode (val, SImode);
1444               switch (which_immediate_load (val))
1445                 {
1446                 case SPU_IL:
1447                   break;
1448                 case SPU_ILA:
1449                   fprintf (file, "a");
1450                   break;
1451                 case SPU_ILH:
1452                   fprintf (file, "h");
1453                   break;
1454                 case SPU_ILHU:
1455                   fprintf (file, "hu");
1456                   break;
1457                 default:
1458                   gcc_unreachable ();
1459                 }
1460               break;
1461             case IC_CPAT:
1462               constant_to_array (mode, x, arr);
1463               cpat_info (arr, GET_MODE_SIZE (mode), &info, 0);
1464               if (info == 1)
1465                 fprintf (file, "b");
1466               else if (info == 2)
1467                 fprintf (file, "h");
1468               else if (info == 4)
1469                 fprintf (file, "w");
1470               else if (info == 8)
1471                 fprintf (file, "d");
1472               break;
1473             case IC_IL1s:
1474               if (xcode == CONST_VECTOR)
1475                 {
1476                   x = CONST_VECTOR_ELT (x, 0);
1477                   xcode = GET_CODE (x);
1478                 }
1479               if (xcode == SYMBOL_REF || xcode == LABEL_REF || xcode == CONST)
1480                 fprintf (file, "a");
1481               else if (xcode == HIGH)
1482                 fprintf (file, "hu");
1483               break;
1484             case IC_FSMBI:
1485             case IC_FSMBI2:
1486             case IC_IL2:
1487             case IC_IL2s:
1488             case IC_POOL:
1489               abort ();
1490             }
1491         }
1492       else
1493         gcc_unreachable ();
1494       return;
1495
1496     case 'T':                   /* 128 bits, signed */
1497     case 'D':                   /* 64 bits, signed */
1498     case 'S':                   /* 32 bits, signed */
1499       if (CONSTANT_P (x))
1500         {
1501           enum immediate_class c = classify_immediate (x, mode);
1502           switch (c)
1503             {
1504             case IC_IL1:
1505               constant_to_array (mode, x, arr);
1506               val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
1507               val = trunc_int_for_mode (val, SImode);
1508               switch (which_immediate_load (val))
1509                 {
1510                 case SPU_IL:
1511                 case SPU_ILA:
1512                   break;
1513                 case SPU_ILH:
1514                 case SPU_ILHU:
1515                   val = trunc_int_for_mode (((arr[0] << 8) | arr[1]), HImode);
1516                   break;
1517                 default:
1518                   gcc_unreachable ();
1519                 }
1520               fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
1521               break;
1522             case IC_FSMBI:
1523               constant_to_array (mode, x, arr);
1524               val = 0;
1525               for (i = 0; i < 16; i++)
1526                 {
1527                   val <<= 1;
1528                   val |= arr[i] & 1;
1529                 }
1530               print_operand (file, GEN_INT (val), 0);
1531               break;
1532             case IC_CPAT:
1533               constant_to_array (mode, x, arr);
1534               cpat_info (arr, GET_MODE_SIZE (mode), 0, &info);
1535               fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)info);
1536               break;
1537             case IC_IL1s:
1538               if (xcode == HIGH)
1539                 x = XEXP (x, 0);
1540               if (GET_CODE (x) == CONST_VECTOR)
1541                 x = CONST_VECTOR_ELT (x, 0);
1542               output_addr_const (file, x);
1543               if (xcode == HIGH)
1544                 fprintf (file, "@h");
1545               break;
1546             case IC_IL2:
1547             case IC_IL2s:
1548             case IC_FSMBI2:
1549             case IC_POOL:
1550               abort ();
1551             }
1552         }
1553       else
1554         gcc_unreachable ();
1555       return;
1556
1557     case 'C':
1558       if (xcode == CONST_INT)
1559         {
1560           /* Only 4 least significant bits are relevant for generate
1561              control word instructions. */
1562           fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 15);
1563           return;
1564         }
1565       break;
1566
1567     case 'M':                   /* print code for c*d */
1568       if (GET_CODE (x) == CONST_INT)
1569         switch (INTVAL (x))
1570           {
1571           case 1:
1572             fprintf (file, "b");
1573             break;
1574           case 2:
1575             fprintf (file, "h");
1576             break;
1577           case 4:
1578             fprintf (file, "w");
1579             break;
1580           case 8:
1581             fprintf (file, "d");
1582             break;
1583           default:
1584             gcc_unreachable();
1585           }
1586       else
1587         gcc_unreachable();
1588       return;
1589
1590     case 'N':                   /* Negate the operand */
1591       if (xcode == CONST_INT)
1592         fprintf (file, HOST_WIDE_INT_PRINT_DEC, -INTVAL (x));
1593       else if (xcode == CONST_VECTOR)
1594         fprintf (file, HOST_WIDE_INT_PRINT_DEC,
1595                  -INTVAL (CONST_VECTOR_ELT (x, 0)));
1596       return;
1597
1598     case 'I':                   /* enable/disable interrupts */
1599       if (xcode == CONST_INT)
1600         fprintf (file, "%s",  INTVAL (x) == 0 ? "d" : "e");
1601       return;
1602
1603     case 'b':                   /* branch modifiers */
1604       if (xcode == REG)
1605         fprintf (file, "%s", GET_MODE (x) == HImode ? "h" : "");
1606       else if (COMPARISON_P (x))
1607         fprintf (file, "%s", xcode == NE ? "n" : "");
1608       return;
1609
1610     case 'i':                   /* indirect call */
1611       if (xcode == MEM)
1612         {
1613           if (GET_CODE (XEXP (x, 0)) == REG)
1614             /* Used in indirect function calls. */
1615             fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]);
1616           else
1617             output_address (XEXP (x, 0));
1618         }
1619       return;
1620
1621     case 'p':                   /* load/store */
1622       if (xcode == MEM)
1623         {
1624           x = XEXP (x, 0);
1625           xcode = GET_CODE (x);
1626         }
1627       if (xcode == AND)
1628         {
1629           x = XEXP (x, 0);
1630           xcode = GET_CODE (x);
1631         }
1632       if (xcode == REG)
1633         fprintf (file, "d");
1634       else if (xcode == CONST_INT)
1635         fprintf (file, "a");
1636       else if (xcode == CONST || xcode == SYMBOL_REF || xcode == LABEL_REF)
1637         fprintf (file, "r");
1638       else if (xcode == PLUS || xcode == LO_SUM)
1639         {
1640           if (GET_CODE (XEXP (x, 1)) == REG)
1641             fprintf (file, "x");
1642           else
1643             fprintf (file, "d");
1644         }
1645       return;
1646
1647     case 'e':
1648       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1649       val &= 0x7;
1650       output_addr_const (file, GEN_INT (val));
1651       return;
1652
1653     case 'f':
1654       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1655       val &= 0x1f;
1656       output_addr_const (file, GEN_INT (val));
1657       return;
1658
1659     case 'g':
1660       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1661       val &= 0x3f;
1662       output_addr_const (file, GEN_INT (val));
1663       return;
1664
1665     case 'h':
1666       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1667       val = (val >> 3) & 0x1f;
1668       output_addr_const (file, GEN_INT (val));
1669       return;
1670
1671     case 'E':
1672       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1673       val = -val;
1674       val &= 0x7;
1675       output_addr_const (file, GEN_INT (val));
1676       return;
1677
1678     case 'F':
1679       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1680       val = -val;
1681       val &= 0x1f;
1682       output_addr_const (file, GEN_INT (val));
1683       return;
1684
1685     case 'G':
1686       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1687       val = -val;
1688       val &= 0x3f;
1689       output_addr_const (file, GEN_INT (val));
1690       return;
1691
1692     case 'H':
1693       val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0));
1694       val = -(val & -8ll);
1695       val = (val >> 3) & 0x1f;
1696       output_addr_const (file, GEN_INT (val));
1697       return;
1698
1699     case 'v':
1700     case 'w':
1701       constant_to_array (mode, x, arr);
1702       val = (((arr[0] << 1) + (arr[1] >> 7)) & 0xff) - 127;
1703       output_addr_const (file, GEN_INT (code == 'w' ? -val : val));
1704       return;
1705
1706     case 0:
1707       if (xcode == REG)
1708         fprintf (file, "%s", reg_names[REGNO (x)]);
1709       else if (xcode == MEM)
1710         output_address (XEXP (x, 0));
1711       else if (xcode == CONST_VECTOR)
1712         print_operand (file, CONST_VECTOR_ELT (x, 0), 0);
1713       else
1714         output_addr_const (file, x);
1715       return;
1716
1717       /* unused letters
1718                       o qr  u   yz
1719         AB            OPQR  UVWXYZ */
1720     default:
1721       output_operand_lossage ("invalid %%xn code");
1722     }
1723   gcc_unreachable ();
1724 }
1725
1726 /* For PIC mode we've reserved PIC_OFFSET_TABLE_REGNUM, which is a
1727    caller saved register.  For leaf functions it is more efficient to
1728    use a volatile register because we won't need to save and restore the
1729    pic register.  This routine is only valid after register allocation
1730    is completed, so we can pick an unused register.  */
1731 static rtx
1732 get_pic_reg (void)
1733 {
1734   rtx pic_reg = pic_offset_table_rtx;
1735   if (!reload_completed && !reload_in_progress)
1736     abort ();
1737   if (current_function_is_leaf && !df_regs_ever_live_p (LAST_ARG_REGNUM))
1738     pic_reg = gen_rtx_REG (SImode, LAST_ARG_REGNUM);
1739   return pic_reg;
1740 }
1741
1742 /* Split constant addresses to handle cases that are too large. 
1743    Add in the pic register when in PIC mode.
1744    Split immediates that require more than 1 instruction. */
1745 int
1746 spu_split_immediate (rtx * ops)
1747 {
1748   enum machine_mode mode = GET_MODE (ops[0]);
1749   enum immediate_class c = classify_immediate (ops[1], mode);
1750
1751   switch (c)
1752     {
1753     case IC_IL2:
1754       {
1755         unsigned char arrhi[16];
1756         unsigned char arrlo[16];
1757         rtx to, temp, hi, lo;
1758         int i;
1759         enum machine_mode imode = mode;
1760         /* We need to do reals as ints because the constant used in the
1761            IOR might not be a legitimate real constant. */
1762         imode = int_mode_for_mode (mode);
1763         constant_to_array (mode, ops[1], arrhi);
1764         if (imode != mode)
1765           to = simplify_gen_subreg (imode, ops[0], mode, 0);
1766         else
1767           to = ops[0];
1768         temp = !can_create_pseudo_p () ? to : gen_reg_rtx (imode);
1769         for (i = 0; i < 16; i += 4)
1770           {
1771             arrlo[i + 2] = arrhi[i + 2];
1772             arrlo[i + 3] = arrhi[i + 3];
1773             arrlo[i + 0] = arrlo[i + 1] = 0;
1774             arrhi[i + 2] = arrhi[i + 3] = 0;
1775           }
1776         hi = array_to_constant (imode, arrhi);
1777         lo = array_to_constant (imode, arrlo);
1778         emit_move_insn (temp, hi);
1779         emit_insn (gen_rtx_SET
1780                    (VOIDmode, to, gen_rtx_IOR (imode, temp, lo)));
1781         return 1;
1782       }
1783     case IC_FSMBI2:
1784       {
1785         unsigned char arr_fsmbi[16];
1786         unsigned char arr_andbi[16];
1787         rtx to, reg_fsmbi, reg_and;
1788         int i;
1789         enum machine_mode imode = mode;
1790         /* We need to do reals as ints because the constant used in the
1791          * AND might not be a legitimate real constant. */
1792         imode = int_mode_for_mode (mode);
1793         constant_to_array (mode, ops[1], arr_fsmbi);
1794         if (imode != mode)
1795           to = simplify_gen_subreg(imode, ops[0], GET_MODE (ops[0]), 0);
1796         else
1797           to = ops[0];
1798         for (i = 0; i < 16; i++)
1799           if (arr_fsmbi[i] != 0)
1800             {
1801               arr_andbi[0] = arr_fsmbi[i];
1802               arr_fsmbi[i] = 0xff;
1803             }
1804         for (i = 1; i < 16; i++)
1805           arr_andbi[i] = arr_andbi[0];
1806         reg_fsmbi = array_to_constant (imode, arr_fsmbi);
1807         reg_and = array_to_constant (imode, arr_andbi);
1808         emit_move_insn (to, reg_fsmbi);
1809         emit_insn (gen_rtx_SET
1810                    (VOIDmode, to, gen_rtx_AND (imode, to, reg_and)));
1811         return 1;
1812       }
1813     case IC_POOL:
1814       if (reload_in_progress || reload_completed)
1815         {
1816           rtx mem = force_const_mem (mode, ops[1]);
1817           if (TARGET_LARGE_MEM)
1818             {
1819               rtx addr = gen_rtx_REG (Pmode, REGNO (ops[0]));
1820               emit_move_insn (addr, XEXP (mem, 0));
1821               mem = replace_equiv_address (mem, addr);
1822             }
1823           emit_move_insn (ops[0], mem);
1824           return 1;
1825         }
1826       break;
1827     case IC_IL1s:
1828     case IC_IL2s:
1829       if (reload_completed && GET_CODE (ops[1]) != HIGH)
1830         {
1831           if (c == IC_IL2s)
1832             {
1833               emit_move_insn (ops[0], gen_rtx_HIGH (mode, ops[1]));
1834               emit_move_insn (ops[0], gen_rtx_LO_SUM (mode, ops[0], ops[1]));
1835             }
1836           else if (flag_pic)
1837             emit_insn (gen_pic (ops[0], ops[1]));
1838           if (flag_pic)
1839             {
1840               rtx pic_reg = get_pic_reg ();
1841               emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
1842               crtl->uses_pic_offset_table = 1;
1843             }
1844           return flag_pic || c == IC_IL2s;
1845         }
1846       break;
1847     case IC_IL1:
1848     case IC_FSMBI:
1849     case IC_CPAT:
1850       break;
1851     }
1852   return 0;
1853 }
1854
1855 /* SAVING is TRUE when we are generating the actual load and store
1856    instructions for REGNO.  When determining the size of the stack
1857    needed for saving register we must allocate enough space for the
1858    worst case, because we don't always have the information early enough
1859    to not allocate it.  But we can at least eliminate the actual loads
1860    and stores during the prologue/epilogue.  */
1861 static int
1862 need_to_save_reg (int regno, int saving)
1863 {
1864   if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
1865     return 1;
1866   if (flag_pic
1867       && regno == PIC_OFFSET_TABLE_REGNUM
1868       && (!saving || crtl->uses_pic_offset_table)
1869       && (!saving
1870           || !current_function_is_leaf || df_regs_ever_live_p (LAST_ARG_REGNUM)))
1871     return 1;
1872   return 0;
1873 }
1874
1875 /* This function is only correct starting with local register
1876    allocation */
1877 int
1878 spu_saved_regs_size (void)
1879 {
1880   int reg_save_size = 0;
1881   int regno;
1882
1883   for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
1884     if (need_to_save_reg (regno, 0))
1885       reg_save_size += 0x10;
1886   return reg_save_size;
1887 }
1888
1889 static rtx
1890 frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset)
1891 {
1892   rtx reg = gen_rtx_REG (V4SImode, regno);
1893   rtx mem =
1894     gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset)));
1895   return emit_insn (gen_movv4si (mem, reg));
1896 }
1897
1898 static rtx
1899 frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset)
1900 {
1901   rtx reg = gen_rtx_REG (V4SImode, regno);
1902   rtx mem =
1903     gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset)));
1904   return emit_insn (gen_movv4si (reg, mem));
1905 }
1906
1907 /* This happens after reload, so we need to expand it.  */
1908 static rtx
1909 frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm, rtx scratch)
1910 {
1911   rtx insn;
1912   if (satisfies_constraint_K (GEN_INT (imm)))
1913     {
1914       insn = emit_insn (gen_addsi3 (dst, src, GEN_INT (imm)));
1915     }
1916   else
1917     {
1918       emit_insn (gen_movsi (scratch, gen_int_mode (imm, SImode)));
1919       insn = emit_insn (gen_addsi3 (dst, src, scratch));
1920       if (REGNO (src) == REGNO (scratch))
1921         abort ();
1922     }
1923   return insn;
1924 }
1925
1926 /* Return nonzero if this function is known to have a null epilogue.  */
1927
1928 int
1929 direct_return (void)
1930 {
1931   if (reload_completed)
1932     {
1933       if (cfun->static_chain_decl == 0
1934           && (spu_saved_regs_size ()
1935               + get_frame_size ()
1936               + crtl->outgoing_args_size
1937               + crtl->args.pretend_args_size == 0)
1938           && current_function_is_leaf)
1939         return 1;
1940     }
1941   return 0;
1942 }
1943
1944 /*
1945    The stack frame looks like this:
1946          +-------------+
1947          |  incoming   | 
1948          |    args     | 
1949    AP -> +-------------+
1950          | $lr save    |
1951          +-------------+
1952  prev SP | back chain  | 
1953          +-------------+
1954          |  var args   | 
1955          |  reg save   | crtl->args.pretend_args_size bytes
1956          +-------------+
1957          |    ...      | 
1958          | saved regs  | spu_saved_regs_size() bytes
1959    FP -> +-------------+
1960          |    ...      | 
1961          |   vars      | get_frame_size()  bytes
1962   HFP -> +-------------+
1963          |    ...      | 
1964          |  outgoing   | 
1965          |    args     | crtl->outgoing_args_size bytes
1966          +-------------+
1967          | $lr of next |
1968          |   frame     | 
1969          +-------------+
1970          | back chain  | 
1971    SP -> +-------------+
1972
1973 */
1974 void
1975 spu_expand_prologue (void)
1976 {
1977   HOST_WIDE_INT size = get_frame_size (), offset, regno;
1978   HOST_WIDE_INT total_size;
1979   HOST_WIDE_INT saved_regs_size;
1980   rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
1981   rtx scratch_reg_0, scratch_reg_1;
1982   rtx insn, real;
1983
1984   if (flag_pic && optimize == 0)
1985     crtl->uses_pic_offset_table = 1;
1986
1987   if (spu_naked_function_p (current_function_decl))
1988     return;
1989
1990   scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1);
1991   scratch_reg_1 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 2);
1992
1993   saved_regs_size = spu_saved_regs_size ();
1994   total_size = size + saved_regs_size
1995     + crtl->outgoing_args_size
1996     + crtl->args.pretend_args_size;
1997
1998   if (!current_function_is_leaf
1999       || cfun->calls_alloca || total_size > 0)
2000     total_size += STACK_POINTER_OFFSET;
2001
2002   /* Save this first because code after this might use the link
2003      register as a scratch register. */
2004   if (!current_function_is_leaf)
2005     {
2006       insn = frame_emit_store (LINK_REGISTER_REGNUM, sp_reg, 16);
2007       RTX_FRAME_RELATED_P (insn) = 1;
2008     }
2009
2010   if (total_size > 0)
2011     {
2012       offset = -crtl->args.pretend_args_size;
2013       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2014         if (need_to_save_reg (regno, 1))
2015           {
2016             offset -= 16;
2017             insn = frame_emit_store (regno, sp_reg, offset);
2018             RTX_FRAME_RELATED_P (insn) = 1;
2019           }
2020     }
2021
2022   if (flag_pic && crtl->uses_pic_offset_table)
2023     {
2024       rtx pic_reg = get_pic_reg ();
2025       insn = emit_insn (gen_load_pic_offset (pic_reg, scratch_reg_0));
2026       insn = emit_insn (gen_subsi3 (pic_reg, pic_reg, scratch_reg_0));
2027     }
2028
2029   if (total_size > 0)
2030     {
2031       if (flag_stack_check)
2032         {
2033           /* We compare against total_size-1 because
2034              ($sp >= total_size) <=> ($sp > total_size-1) */
2035           rtx scratch_v4si = gen_rtx_REG (V4SImode, REGNO (scratch_reg_0));
2036           rtx sp_v4si = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM);
2037           rtx size_v4si = spu_const (V4SImode, total_size - 1);
2038           if (!satisfies_constraint_K (GEN_INT (total_size - 1)))
2039             {
2040               emit_move_insn (scratch_v4si, size_v4si);
2041               size_v4si = scratch_v4si;
2042             }
2043           emit_insn (gen_cgt_v4si (scratch_v4si, sp_v4si, size_v4si));
2044           emit_insn (gen_vec_extractv4si
2045                      (scratch_reg_0, scratch_v4si, GEN_INT (1)));
2046           emit_insn (gen_spu_heq (scratch_reg_0, GEN_INT (0)));
2047         }
2048
2049       /* Adjust the stack pointer, and make sure scratch_reg_0 contains
2050          the value of the previous $sp because we save it as the back
2051          chain. */
2052       if (total_size <= 2000)
2053         {
2054           /* In this case we save the back chain first. */
2055           insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size);
2056           insn =
2057             frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0);
2058         }
2059       else
2060         {
2061           insn = emit_move_insn (scratch_reg_0, sp_reg);
2062           insn =
2063             frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1);
2064         }
2065       RTX_FRAME_RELATED_P (insn) = 1;
2066       real = gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size));
2067       add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
2068
2069       if (total_size > 2000)
2070         {
2071           /* Save the back chain ptr */
2072           insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0);
2073         }
2074
2075       if (frame_pointer_needed)
2076         {
2077           rtx fp_reg = gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM);
2078           HOST_WIDE_INT fp_offset = STACK_POINTER_OFFSET
2079             + crtl->outgoing_args_size;
2080           /* Set the new frame_pointer */
2081           insn = frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
2082           RTX_FRAME_RELATED_P (insn) = 1;
2083           real = gen_addsi3 (fp_reg, sp_reg, GEN_INT (fp_offset));
2084           add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
2085           REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
2086         }
2087     }
2088
2089 }
2090
2091 void
2092 spu_expand_epilogue (bool sibcall_p)
2093 {
2094   int size = get_frame_size (), offset, regno;
2095   HOST_WIDE_INT saved_regs_size, total_size;
2096   rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
2097   rtx jump, scratch_reg_0;
2098
2099   if (spu_naked_function_p (current_function_decl))
2100     return;
2101
2102   scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1);
2103
2104   saved_regs_size = spu_saved_regs_size ();
2105   total_size = size + saved_regs_size
2106     + crtl->outgoing_args_size
2107     + crtl->args.pretend_args_size;
2108
2109   if (!current_function_is_leaf
2110       || cfun->calls_alloca || total_size > 0)
2111     total_size += STACK_POINTER_OFFSET;
2112
2113   if (total_size > 0)
2114     {
2115       if (cfun->calls_alloca)
2116         frame_emit_load (STACK_POINTER_REGNUM, sp_reg, 0);
2117       else
2118         frame_emit_add_imm (sp_reg, sp_reg, total_size, scratch_reg_0);
2119
2120
2121       if (saved_regs_size > 0)
2122         {
2123           offset = -crtl->args.pretend_args_size;
2124           for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2125             if (need_to_save_reg (regno, 1))
2126               {
2127                 offset -= 0x10;
2128                 frame_emit_load (regno, sp_reg, offset);
2129               }
2130         }
2131     }
2132
2133   if (!current_function_is_leaf)
2134     frame_emit_load (LINK_REGISTER_REGNUM, sp_reg, 16);
2135
2136   if (!sibcall_p)
2137     {
2138       emit_use (gen_rtx_REG (SImode, LINK_REGISTER_REGNUM));
2139       jump = emit_jump_insn (gen__return ());
2140       emit_barrier_after (jump);
2141     }
2142
2143 }
2144
2145 rtx
2146 spu_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
2147 {
2148   if (count != 0)
2149     return 0;
2150   /* This is inefficient because it ends up copying to a save-register
2151      which then gets saved even though $lr has already been saved.  But
2152      it does generate better code for leaf functions and we don't need
2153      to use RETURN_ADDRESS_POINTER_REGNUM to get it working.  It's only
2154      used for __builtin_return_address anyway, so maybe we don't care if
2155      it's inefficient. */
2156   return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
2157 }
2158 \f
2159
2160 /* Given VAL, generate a constant appropriate for MODE.
2161    If MODE is a vector mode, every element will be VAL.
2162    For TImode, VAL will be zero extended to 128 bits. */
2163 rtx
2164 spu_const (enum machine_mode mode, HOST_WIDE_INT val)
2165 {
2166   rtx inner;
2167   rtvec v;
2168   int units, i;
2169
2170   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
2171               || GET_MODE_CLASS (mode) == MODE_FLOAT
2172               || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
2173               || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT);
2174
2175   if (GET_MODE_CLASS (mode) == MODE_INT)
2176     return immed_double_const (val, 0, mode);
2177
2178   /* val is the bit representation of the float */
2179   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2180     return hwint_to_const_double (mode, val);
2181
2182   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2183     inner = immed_double_const (val, 0, GET_MODE_INNER (mode));
2184   else 
2185     inner = hwint_to_const_double (GET_MODE_INNER (mode), val);
2186
2187   units = GET_MODE_NUNITS (mode);
2188
2189   v = rtvec_alloc (units);
2190
2191   for (i = 0; i < units; ++i)
2192     RTVEC_ELT (v, i) = inner;
2193
2194   return gen_rtx_CONST_VECTOR (mode, v);
2195 }
2196
2197 /* Create a MODE vector constant from 4 ints. */
2198 rtx
2199 spu_const_from_ints(enum machine_mode mode, int a, int b, int c, int d)
2200 {
2201   unsigned char arr[16];
2202   arr[0] = (a >> 24) & 0xff;
2203   arr[1] = (a >> 16) & 0xff;
2204   arr[2] = (a >> 8) & 0xff;
2205   arr[3] = (a >> 0) & 0xff;
2206   arr[4] = (b >> 24) & 0xff;
2207   arr[5] = (b >> 16) & 0xff;
2208   arr[6] = (b >> 8) & 0xff;
2209   arr[7] = (b >> 0) & 0xff;
2210   arr[8] = (c >> 24) & 0xff;
2211   arr[9] = (c >> 16) & 0xff;
2212   arr[10] = (c >> 8) & 0xff;
2213   arr[11] = (c >> 0) & 0xff;
2214   arr[12] = (d >> 24) & 0xff;
2215   arr[13] = (d >> 16) & 0xff;
2216   arr[14] = (d >> 8) & 0xff;
2217   arr[15] = (d >> 0) & 0xff;
2218   return array_to_constant(mode, arr);
2219 }
2220 \f
2221 /* branch hint stuff */
2222
2223 /* An array of these is used to propagate hints to predecessor blocks. */
2224 struct spu_bb_info
2225 {
2226   rtx prop_jump; /* propagated from another block */
2227   int bb_index;  /* the original block. */
2228 };
2229 static struct spu_bb_info *spu_bb_info;
2230
2231 #define STOP_HINT_P(INSN) \
2232                 (GET_CODE(INSN) == CALL_INSN \
2233                  || INSN_CODE(INSN) == CODE_FOR_divmodsi4 \
2234                  || INSN_CODE(INSN) == CODE_FOR_udivmodsi4)
2235
2236 /* 1 when RTX is a hinted branch or its target.  We keep track of
2237    what has been hinted so the safe-hint code can test it easily.  */
2238 #define HINTED_P(RTX)                                           \
2239   (RTL_FLAG_CHECK3("HINTED_P", (RTX), CODE_LABEL, JUMP_INSN, CALL_INSN)->unchanging)
2240
2241 /* 1 when RTX is an insn that must be scheduled on an even boundary. */
2242 #define SCHED_ON_EVEN_P(RTX)                                            \
2243   (RTL_FLAG_CHECK2("SCHED_ON_EVEN_P", (RTX), JUMP_INSN, CALL_INSN)->in_struct)
2244
2245 /* Emit a nop for INSN such that the two will dual issue.  This assumes
2246    INSN is 8-byte aligned.  When INSN is inline asm we emit an lnop.
2247    We check for TImode to handle a MULTI1 insn which has dual issued its
2248    first instruction.  get_pipe returns -1 for MULTI0, inline asm, or
2249    ADDR_VEC insns. */
2250 static void
2251 emit_nop_for_insn (rtx insn)
2252 {
2253   int p;
2254   rtx new_insn;
2255   p = get_pipe (insn);
2256   if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn))
2257     new_insn = emit_insn_after (gen_lnop (), insn);
2258   else if (p == 1 && GET_MODE (insn) == TImode)
2259     {
2260       new_insn = emit_insn_before (gen_nopn (GEN_INT (127)), insn);
2261       PUT_MODE (new_insn, TImode);
2262       PUT_MODE (insn, VOIDmode);
2263     }
2264   else
2265     new_insn = emit_insn_after (gen_lnop (), insn);
2266   recog_memoized (new_insn);
2267 }
2268
2269 /* Insert nops in basic blocks to meet dual issue alignment
2270    requirements.  Also make sure hbrp and hint instructions are at least
2271    one cycle apart, possibly inserting a nop.  */
2272 static void
2273 pad_bb(void)
2274 {
2275   rtx insn, next_insn, prev_insn, hbr_insn = 0;
2276   int length;
2277   int addr;
2278
2279   /* This sets up INSN_ADDRESSES. */
2280   shorten_branches (get_insns ());
2281
2282   /* Keep track of length added by nops. */
2283   length = 0;
2284
2285   prev_insn = 0;
2286   insn = get_insns ();
2287   if (!active_insn_p (insn))
2288     insn = next_active_insn (insn);
2289   for (; insn; insn = next_insn)
2290     {
2291       next_insn = next_active_insn (insn);
2292       if (INSN_CODE (insn) == CODE_FOR_iprefetch
2293           || INSN_CODE (insn) == CODE_FOR_hbr)
2294         {
2295           if (hbr_insn)
2296             {
2297               int a0 = INSN_ADDRESSES (INSN_UID (hbr_insn));
2298               int a1 = INSN_ADDRESSES (INSN_UID (insn));
2299               if ((a1 - a0 == 8 && GET_MODE (insn) != TImode)
2300                   || (a1 - a0 == 4))
2301                 {
2302                   prev_insn = emit_insn_before (gen_lnop (), insn);
2303                   PUT_MODE (prev_insn, GET_MODE (insn));
2304                   PUT_MODE (insn, TImode);
2305                   length += 4;
2306                 }
2307             }
2308           hbr_insn = insn;
2309         }
2310       if (INSN_CODE (insn) == CODE_FOR_blockage)
2311         {
2312           if (GET_MODE (insn) == TImode)
2313             PUT_MODE (next_insn, TImode);
2314           insn = next_insn;
2315           next_insn = next_active_insn (insn);
2316         }
2317       addr = INSN_ADDRESSES (INSN_UID (insn));
2318       if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn))
2319         {
2320           if (((addr + length) & 7) != 0)
2321             {
2322               emit_nop_for_insn (prev_insn);
2323               length += 4;
2324             }
2325         }
2326       else if (GET_MODE (insn) == TImode
2327                && ((next_insn && GET_MODE (next_insn) != TImode)
2328                    || get_attr_type (insn) == TYPE_MULTI0)
2329                && ((addr + length) & 7) != 0)
2330         {
2331           /* prev_insn will always be set because the first insn is
2332              always 8-byte aligned. */
2333           emit_nop_for_insn (prev_insn);
2334           length += 4;
2335         }
2336       prev_insn = insn;
2337     }
2338 }
2339
2340 \f
2341 /* Routines for branch hints. */
2342
2343 static void
2344 spu_emit_branch_hint (rtx before, rtx branch, rtx target,
2345                       int distance, sbitmap blocks)
2346 {
2347   rtx branch_label = 0;
2348   rtx hint;
2349   rtx insn;
2350   rtx table;
2351
2352   if (before == 0 || branch == 0 || target == 0)
2353     return;
2354
2355   /* While scheduling we require hints to be no further than 600, so
2356      we need to enforce that here too */
2357   if (distance > 600)
2358     return;
2359
2360   /* If we have a Basic block note, emit it after the basic block note.  */
2361   if (NOTE_INSN_BASIC_BLOCK_P (before))
2362     before = NEXT_INSN (before);
2363
2364   branch_label = gen_label_rtx ();
2365   LABEL_NUSES (branch_label)++;
2366   LABEL_PRESERVE_P (branch_label) = 1;
2367   insn = emit_label_before (branch_label, branch);
2368   branch_label = gen_rtx_LABEL_REF (VOIDmode, branch_label);
2369   SET_BIT (blocks, BLOCK_FOR_INSN (branch)->index);
2370
2371   hint = emit_insn_before (gen_hbr (branch_label, target), before);
2372   recog_memoized (hint);
2373   HINTED_P (branch) = 1;
2374
2375   if (GET_CODE (target) == LABEL_REF)
2376     HINTED_P (XEXP (target, 0)) = 1;
2377   else if (tablejump_p (branch, 0, &table))
2378     {
2379       rtvec vec;
2380       int j;
2381       if (GET_CODE (PATTERN (table)) == ADDR_VEC)
2382         vec = XVEC (PATTERN (table), 0);
2383       else
2384         vec = XVEC (PATTERN (table), 1);
2385       for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
2386         HINTED_P (XEXP (RTVEC_ELT (vec, j), 0)) = 1;
2387     }
2388
2389   if (distance >= 588)
2390     {
2391       /* Make sure the hint isn't scheduled any earlier than this point,
2392          which could make it too far for the branch offest to fit */
2393       recog_memoized (emit_insn_before (gen_blockage (), hint));
2394     }
2395   else if (distance <= 8 * 4)
2396     {
2397       /* To guarantee at least 8 insns between the hint and branch we
2398          insert nops. */
2399       int d;
2400       for (d = distance; d < 8 * 4; d += 4)
2401         {
2402           insn =
2403             emit_insn_after (gen_nopn_nv (gen_rtx_REG (SImode, 127)), hint);
2404           recog_memoized (insn);
2405         }
2406
2407       /* Make sure any nops inserted aren't scheduled before the hint. */
2408       recog_memoized (emit_insn_after (gen_blockage (), hint));
2409
2410       /* Make sure any nops inserted aren't scheduled after the call. */
2411       if (CALL_P (branch) && distance < 8 * 4)
2412         recog_memoized (emit_insn_before (gen_blockage (), branch));
2413     }
2414 }
2415
2416 /* Returns 0 if we don't want a hint for this branch.  Otherwise return
2417    the rtx for the branch target. */
2418 static rtx
2419 get_branch_target (rtx branch)
2420 {
2421   if (GET_CODE (branch) == JUMP_INSN)
2422     {
2423       rtx set, src;
2424
2425       /* Return statements */
2426       if (GET_CODE (PATTERN (branch)) == RETURN)
2427         return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM);
2428
2429       /* jump table */
2430       if (GET_CODE (PATTERN (branch)) == ADDR_VEC
2431           || GET_CODE (PATTERN (branch)) == ADDR_DIFF_VEC)
2432         return 0;
2433
2434      /* ASM GOTOs. */
2435      if (extract_asm_operands (PATTERN (branch)) != NULL)
2436         return NULL;
2437
2438       set = single_set (branch);
2439       src = SET_SRC (set);
2440       if (GET_CODE (SET_DEST (set)) != PC)
2441         abort ();
2442
2443       if (GET_CODE (src) == IF_THEN_ELSE)
2444         {
2445           rtx lab = 0;
2446           rtx note = find_reg_note (branch, REG_BR_PROB, 0);
2447           if (note)
2448             {
2449               /* If the more probable case is not a fall through, then
2450                  try a branch hint.  */
2451               HOST_WIDE_INT prob = INTVAL (XEXP (note, 0));
2452               if (prob > (REG_BR_PROB_BASE * 6 / 10)
2453                   && GET_CODE (XEXP (src, 1)) != PC)
2454                 lab = XEXP (src, 1);
2455               else if (prob < (REG_BR_PROB_BASE * 4 / 10)
2456                        && GET_CODE (XEXP (src, 2)) != PC)
2457                 lab = XEXP (src, 2);
2458             }
2459           if (lab)
2460             {
2461               if (GET_CODE (lab) == RETURN)
2462                 return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM);
2463               return lab;
2464             }
2465           return 0;
2466         }
2467
2468       return src;
2469     }
2470   else if (GET_CODE (branch) == CALL_INSN)
2471     {
2472       rtx call;
2473       /* All of our call patterns are in a PARALLEL and the CALL is
2474          the first pattern in the PARALLEL. */
2475       if (GET_CODE (PATTERN (branch)) != PARALLEL)
2476         abort ();
2477       call = XVECEXP (PATTERN (branch), 0, 0);
2478       if (GET_CODE (call) == SET)
2479         call = SET_SRC (call);
2480       if (GET_CODE (call) != CALL)
2481         abort ();
2482       return XEXP (XEXP (call, 0), 0);
2483     }
2484   return 0;
2485 }
2486
2487 /* The special $hbr register is used to prevent the insn scheduler from
2488    moving hbr insns across instructions which invalidate them.  It
2489    should only be used in a clobber, and this function searches for
2490    insns which clobber it.  */
2491 static bool
2492 insn_clobbers_hbr (rtx insn)
2493 {
2494   if (INSN_P (insn)
2495       && GET_CODE (PATTERN (insn)) == PARALLEL)
2496     {
2497       rtx parallel = PATTERN (insn);
2498       rtx clobber;
2499       int j;
2500       for (j = XVECLEN (parallel, 0) - 1; j >= 0; j--)
2501         {
2502           clobber = XVECEXP (parallel, 0, j);
2503           if (GET_CODE (clobber) == CLOBBER
2504               && GET_CODE (XEXP (clobber, 0)) == REG
2505               && REGNO (XEXP (clobber, 0)) == HBR_REGNUM)
2506             return 1;
2507         }
2508     }
2509   return 0;
2510 }
2511
2512 /* Search up to 32 insns starting at FIRST:
2513    - at any kind of hinted branch, just return
2514    - at any unconditional branch in the first 15 insns, just return
2515    - at a call or indirect branch, after the first 15 insns, force it to
2516      an even address and return
2517    - at any unconditional branch, after the first 15 insns, force it to
2518      an even address. 
2519    At then end of the search, insert an hbrp within 4 insns of FIRST,
2520    and an hbrp within 16 instructions of FIRST.
2521  */
2522 static void
2523 insert_hbrp_for_ilb_runout (rtx first)
2524 {
2525   rtx insn, before_4 = 0, before_16 = 0;
2526   int addr = 0, length, first_addr = -1;
2527   int hbrp_addr0 = 128 * 4, hbrp_addr1 = 128 * 4;
2528   int insert_lnop_after = 0;
2529   for (insn = first; insn; insn = NEXT_INSN (insn))
2530     if (INSN_P (insn))
2531       {
2532         if (first_addr == -1)
2533           first_addr = INSN_ADDRESSES (INSN_UID (insn));
2534         addr = INSN_ADDRESSES (INSN_UID (insn)) - first_addr;
2535         length = get_attr_length (insn);
2536
2537         if (before_4 == 0 && addr + length >= 4 * 4)
2538           before_4 = insn;
2539         /* We test for 14 instructions because the first hbrp will add
2540            up to 2 instructions. */
2541         if (before_16 == 0 && addr + length >= 14 * 4)
2542           before_16 = insn;
2543
2544         if (INSN_CODE (insn) == CODE_FOR_hbr)
2545           {
2546             /* Make sure an hbrp is at least 2 cycles away from a hint. 
2547                Insert an lnop after the hbrp when necessary. */
2548             if (before_4 == 0 && addr > 0)
2549               {
2550                 before_4 = insn;
2551                 insert_lnop_after |= 1;
2552               }
2553             else if (before_4 && addr <= 4 * 4)
2554               insert_lnop_after |= 1;
2555             if (before_16 == 0 && addr > 10 * 4)
2556               {
2557                 before_16 = insn;
2558                 insert_lnop_after |= 2;
2559               }
2560             else if (before_16 && addr <= 14 * 4)
2561               insert_lnop_after |= 2;
2562           }
2563
2564         if (INSN_CODE (insn) == CODE_FOR_iprefetch)
2565           {
2566             if (addr < hbrp_addr0)
2567               hbrp_addr0 = addr;
2568             else if (addr < hbrp_addr1)
2569               hbrp_addr1 = addr;
2570           }
2571
2572         if (CALL_P (insn) || JUMP_P (insn))
2573           {
2574             if (HINTED_P (insn))
2575               return;
2576
2577             /* Any branch after the first 15 insns should be on an even
2578                address to avoid a special case branch.  There might be
2579                some nops and/or hbrps inserted, so we test after 10
2580                insns. */
2581             if (addr > 10 * 4)
2582               SCHED_ON_EVEN_P (insn) = 1;
2583           }
2584
2585         if (CALL_P (insn) || tablejump_p (insn, 0, 0))
2586           return;
2587
2588
2589         if (addr + length >= 32 * 4)
2590           {
2591             gcc_assert (before_4 && before_16);
2592             if (hbrp_addr0 > 4 * 4)
2593               {
2594                 insn =
2595                   emit_insn_before (gen_iprefetch (GEN_INT (1)), before_4);
2596                 recog_memoized (insn);
2597                 INSN_ADDRESSES_NEW (insn,
2598                                     INSN_ADDRESSES (INSN_UID (before_4)));
2599                 PUT_MODE (insn, GET_MODE (before_4));
2600                 PUT_MODE (before_4, TImode);
2601                 if (insert_lnop_after & 1)
2602                   {
2603                     insn = emit_insn_before (gen_lnop (), before_4);
2604                     recog_memoized (insn);
2605                     INSN_ADDRESSES_NEW (insn,
2606                                         INSN_ADDRESSES (INSN_UID (before_4)));
2607                     PUT_MODE (insn, TImode);
2608                   }
2609               }
2610             if ((hbrp_addr0 <= 4 * 4 || hbrp_addr0 > 16 * 4)
2611                 && hbrp_addr1 > 16 * 4)
2612               {
2613                 insn =
2614                   emit_insn_before (gen_iprefetch (GEN_INT (2)), before_16);
2615                 recog_memoized (insn);
2616                 INSN_ADDRESSES_NEW (insn,
2617                                     INSN_ADDRESSES (INSN_UID (before_16)));
2618                 PUT_MODE (insn, GET_MODE (before_16));
2619                 PUT_MODE (before_16, TImode);
2620                 if (insert_lnop_after & 2)
2621                   {
2622                     insn = emit_insn_before (gen_lnop (), before_16);
2623                     recog_memoized (insn);
2624                     INSN_ADDRESSES_NEW (insn,
2625                                         INSN_ADDRESSES (INSN_UID
2626                                                         (before_16)));
2627                     PUT_MODE (insn, TImode);
2628                   }
2629               }
2630             return;
2631           }
2632       }
2633     else if (BARRIER_P (insn))
2634       return;
2635
2636 }
2637
2638 /* The SPU might hang when it executes 48 inline instructions after a
2639    hinted branch jumps to its hinted target.  The beginning of a
2640    function and the return from a call might have been hinted, and must
2641    be handled as well.  To prevent a hang we insert 2 hbrps.  The first
2642    should be within 6 insns of the branch target.  The second should be
2643    within 22 insns of the branch target.  When determining if hbrps are
2644    necessary, we look for only 32 inline instructions, because up to to
2645    12 nops and 4 hbrps could be inserted.  Similarily, when inserting
2646    new hbrps, we insert them within 4 and 16 insns of the target.  */
2647 static void
2648 insert_hbrp (void)
2649 {
2650   rtx insn;
2651   if (TARGET_SAFE_HINTS)
2652     {
2653       shorten_branches (get_insns ());
2654       /* Insert hbrp at beginning of function */
2655       insn = next_active_insn (get_insns ());
2656       if (insn)
2657         insert_hbrp_for_ilb_runout (insn);
2658       /* Insert hbrp after hinted targets. */
2659       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2660         if ((LABEL_P (insn) && HINTED_P (insn)) || CALL_P (insn))
2661           insert_hbrp_for_ilb_runout (next_active_insn (insn));
2662     }
2663 }
2664
2665 static int in_spu_reorg;
2666
2667 /* Insert branch hints.  There are no branch optimizations after this
2668    pass, so it's safe to set our branch hints now. */
2669 static void
2670 spu_machine_dependent_reorg (void)
2671 {
2672   sbitmap blocks;
2673   basic_block bb;
2674   rtx branch, insn;
2675   rtx branch_target = 0;
2676   int branch_addr = 0, insn_addr, required_dist = 0;
2677   int i;
2678   unsigned int j;
2679
2680   if (!TARGET_BRANCH_HINTS || optimize == 0)
2681     {
2682       /* We still do it for unoptimized code because an external
2683          function might have hinted a call or return. */
2684       insert_hbrp ();
2685       pad_bb ();
2686       return;
2687     }
2688
2689   blocks = sbitmap_alloc (last_basic_block);
2690   sbitmap_zero (blocks);
2691
2692   in_spu_reorg = 1;
2693   compute_bb_for_insn ();
2694
2695   compact_blocks ();
2696
2697   spu_bb_info =
2698     (struct spu_bb_info *) xcalloc (n_basic_blocks,
2699                                     sizeof (struct spu_bb_info));
2700
2701   /* We need exact insn addresses and lengths.  */
2702   shorten_branches (get_insns ());
2703
2704   for (i = n_basic_blocks - 1; i >= 0; i--)
2705     {
2706       bb = BASIC_BLOCK (i);
2707       branch = 0;
2708       if (spu_bb_info[i].prop_jump)
2709         {
2710           branch = spu_bb_info[i].prop_jump;
2711           branch_target = get_branch_target (branch);
2712           branch_addr = INSN_ADDRESSES (INSN_UID (branch));
2713           required_dist = spu_hint_dist;
2714         }
2715       /* Search from end of a block to beginning.   In this loop, find
2716          jumps which need a branch and emit them only when:
2717          - it's an indirect branch and we're at the insn which sets
2718          the register  
2719          - we're at an insn that will invalidate the hint. e.g., a
2720          call, another hint insn, inline asm that clobbers $hbr, and
2721          some inlined operations (divmodsi4).  Don't consider jumps
2722          because they are only at the end of a block and are
2723          considered when we are deciding whether to propagate
2724          - we're getting too far away from the branch.  The hbr insns
2725          only have a signed 10 bit offset
2726          We go back as far as possible so the branch will be considered
2727          for propagation when we get to the beginning of the block.  */
2728       for (insn = BB_END (bb); insn; insn = PREV_INSN (insn))
2729         {
2730           if (INSN_P (insn))
2731             {
2732               insn_addr = INSN_ADDRESSES (INSN_UID (insn));
2733               if (branch
2734                   && ((GET_CODE (branch_target) == REG
2735                        && set_of (branch_target, insn) != NULL_RTX)
2736                       || insn_clobbers_hbr (insn)
2737                       || branch_addr - insn_addr > 600))
2738                 {
2739                   rtx next = NEXT_INSN (insn);
2740                   int next_addr = INSN_ADDRESSES (INSN_UID (next));
2741                   if (insn != BB_END (bb)
2742                       && branch_addr - next_addr >= required_dist)
2743                     {
2744                       if (dump_file)
2745                         fprintf (dump_file,
2746                                  "hint for %i in block %i before %i\n",
2747                                  INSN_UID (branch), bb->index,
2748                                  INSN_UID (next));
2749                       spu_emit_branch_hint (next, branch, branch_target,
2750                                             branch_addr - next_addr, blocks);
2751                     }
2752                   branch = 0;
2753                 }
2754
2755               /* JUMP_P will only be true at the end of a block.  When
2756                  branch is already set it means we've previously decided
2757                  to propagate a hint for that branch into this block. */
2758               if (CALL_P (insn) || (JUMP_P (insn) && !branch))
2759                 {
2760                   branch = 0;
2761                   if ((branch_target = get_branch_target (insn)))
2762                     {
2763                       branch = insn;
2764                       branch_addr = insn_addr;
2765                       required_dist = spu_hint_dist;
2766                     }
2767                 }
2768             }
2769           if (insn == BB_HEAD (bb))
2770             break;
2771         }
2772
2773       if (branch)
2774         {
2775           /* If we haven't emitted a hint for this branch yet, it might
2776              be profitable to emit it in one of the predecessor blocks,
2777              especially for loops.  */
2778           rtx bbend;
2779           basic_block prev = 0, prop = 0, prev2 = 0;
2780           int loop_exit = 0, simple_loop = 0;
2781           int next_addr = INSN_ADDRESSES (INSN_UID (NEXT_INSN (insn)));
2782
2783           for (j = 0; j < EDGE_COUNT (bb->preds); j++)
2784             if (EDGE_PRED (bb, j)->flags & EDGE_FALLTHRU)
2785               prev = EDGE_PRED (bb, j)->src;
2786             else
2787               prev2 = EDGE_PRED (bb, j)->src;
2788
2789           for (j = 0; j < EDGE_COUNT (bb->succs); j++)
2790             if (EDGE_SUCC (bb, j)->flags & EDGE_LOOP_EXIT)
2791               loop_exit = 1;
2792             else if (EDGE_SUCC (bb, j)->dest == bb)
2793               simple_loop = 1;
2794
2795           /* If this branch is a loop exit then propagate to previous
2796              fallthru block. This catches the cases when it is a simple
2797              loop or when there is an initial branch into the loop. */
2798           if (prev && (loop_exit || simple_loop)
2799               && prev->loop_depth <= bb->loop_depth)
2800             prop = prev;
2801
2802           /* If there is only one adjacent predecessor.  Don't propagate
2803              outside this loop.  This loop_depth test isn't perfect, but
2804              I'm not sure the loop_father member is valid at this point.  */
2805           else if (prev && single_pred_p (bb)
2806                    && prev->loop_depth == bb->loop_depth)
2807             prop = prev;
2808
2809           /* If this is the JOIN block of a simple IF-THEN then
2810              propogate the hint to the HEADER block. */
2811           else if (prev && prev2
2812                    && EDGE_COUNT (bb->preds) == 2
2813                    && EDGE_COUNT (prev->preds) == 1
2814                    && EDGE_PRED (prev, 0)->src == prev2
2815                    && prev2->loop_depth == bb->loop_depth
2816                    && GET_CODE (branch_target) != REG)
2817             prop = prev;
2818
2819           /* Don't propagate when:
2820              - this is a simple loop and the hint would be too far
2821              - this is not a simple loop and there are 16 insns in
2822              this block already
2823              - the predecessor block ends in a branch that will be
2824              hinted
2825              - the predecessor block ends in an insn that invalidates
2826              the hint */
2827           if (prop
2828               && prop->index >= 0
2829               && (bbend = BB_END (prop))
2830               && branch_addr - INSN_ADDRESSES (INSN_UID (bbend)) <
2831               (simple_loop ? 600 : 16 * 4) && get_branch_target (bbend) == 0
2832               && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend)))
2833             {
2834               if (dump_file)
2835                 fprintf (dump_file, "propagate from %i to %i (loop depth %i) "
2836                          "for %i (loop_exit %i simple_loop %i dist %i)\n",
2837                          bb->index, prop->index, bb->loop_depth,
2838                          INSN_UID (branch), loop_exit, simple_loop,
2839                          branch_addr - INSN_ADDRESSES (INSN_UID (bbend)));
2840
2841               spu_bb_info[prop->index].prop_jump = branch;
2842               spu_bb_info[prop->index].bb_index = i;
2843             }
2844           else if (branch_addr - next_addr >= required_dist)
2845             {
2846               if (dump_file)
2847                 fprintf (dump_file, "hint for %i in block %i before %i\n",
2848                          INSN_UID (branch), bb->index,
2849                          INSN_UID (NEXT_INSN (insn)));
2850               spu_emit_branch_hint (NEXT_INSN (insn), branch, branch_target,
2851                                     branch_addr - next_addr, blocks);
2852             }
2853           branch = 0;
2854         }
2855     }
2856   free (spu_bb_info);
2857
2858   if (!sbitmap_empty_p (blocks))
2859     find_many_sub_basic_blocks (blocks);
2860
2861   /* We have to schedule to make sure alignment is ok. */
2862   FOR_EACH_BB (bb) bb->flags &= ~BB_DISABLE_SCHEDULE;
2863
2864   /* The hints need to be scheduled, so call it again. */
2865   schedule_insns ();
2866
2867   insert_hbrp ();
2868
2869   pad_bb ();
2870
2871   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2872     if (NONJUMP_INSN_P (insn) && INSN_CODE (insn) == CODE_FOR_hbr)
2873       {
2874         /* Adjust the LABEL_REF in a hint when we have inserted a nop
2875            between its branch label and the branch .  We don't move the
2876            label because GCC expects it at the beginning of the block. */
2877         rtx unspec = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
2878         rtx label_ref = XVECEXP (unspec, 0, 0);
2879         rtx label = XEXP (label_ref, 0);
2880         rtx branch;
2881         int offset = 0;
2882         for (branch = NEXT_INSN (label);
2883              !JUMP_P (branch) && !CALL_P (branch);
2884              branch = NEXT_INSN (branch))
2885           if (NONJUMP_INSN_P (branch))
2886             offset += get_attr_length (branch);
2887         if (offset > 0)
2888           XVECEXP (unspec, 0, 0) = plus_constant (label_ref, offset);
2889       }
2890
2891   if (spu_flag_var_tracking)
2892     {
2893       df_analyze ();
2894       timevar_push (TV_VAR_TRACKING);
2895       variable_tracking_main ();
2896       timevar_pop (TV_VAR_TRACKING);
2897       df_finish_pass (false);
2898     }
2899
2900   free_bb_for_insn ();
2901
2902   in_spu_reorg = 0;
2903 }
2904 \f
2905
2906 /* Insn scheduling routines, primarily for dual issue. */
2907 static int
2908 spu_sched_issue_rate (void)
2909 {
2910   return 2;
2911 }
2912
2913 static int
2914 uses_ls_unit(rtx insn)
2915 {
2916   rtx set = single_set (insn);
2917   if (set != 0
2918       && (GET_CODE (SET_DEST (set)) == MEM
2919           || GET_CODE (SET_SRC (set)) == MEM))
2920     return 1;
2921   return 0;
2922 }
2923
2924 static int
2925 get_pipe (rtx insn)
2926 {
2927   enum attr_type t;
2928   /* Handle inline asm */
2929   if (INSN_CODE (insn) == -1)
2930     return -1;
2931   t = get_attr_type (insn);
2932   switch (t)
2933     {
2934     case TYPE_CONVERT:
2935       return -2;
2936     case TYPE_MULTI0:
2937       return -1;
2938
2939     case TYPE_FX2:
2940     case TYPE_FX3:
2941     case TYPE_SPR:
2942     case TYPE_NOP:
2943     case TYPE_FXB:
2944     case TYPE_FPD:
2945     case TYPE_FP6:
2946     case TYPE_FP7:
2947       return 0;
2948
2949     case TYPE_LNOP:
2950     case TYPE_SHUF:
2951     case TYPE_LOAD:
2952     case TYPE_STORE:
2953     case TYPE_BR:
2954     case TYPE_MULTI1:
2955     case TYPE_HBR:
2956     case TYPE_IPREFETCH:
2957       return 1;
2958     default:
2959       abort ();
2960     }
2961 }
2962
2963
2964 /* haifa-sched.c has a static variable that keeps track of the current
2965    cycle.  It is passed to spu_sched_reorder, and we record it here for
2966    use by spu_sched_variable_issue.  It won't be accurate if the
2967    scheduler updates it's clock_var between the two calls. */
2968 static int clock_var;
2969
2970 /* This is used to keep track of insn alignment.  Set to 0 at the
2971    beginning of each block and increased by the "length" attr of each
2972    insn scheduled. */
2973 static int spu_sched_length;
2974
2975 /* Record when we've issued pipe0 and pipe1 insns so we can reorder the
2976    ready list appropriately in spu_sched_reorder(). */
2977 static int pipe0_clock;
2978 static int pipe1_clock;
2979
2980 static int prev_clock_var;
2981
2982 static int prev_priority;
2983
2984 /* The SPU needs to load the next ilb sometime during the execution of
2985    the previous ilb.  There is a potential conflict if every cycle has a
2986    load or store.  To avoid the conflict we make sure the load/store
2987    unit is free for at least one cycle during the execution of insns in
2988    the previous ilb. */
2989 static int spu_ls_first;
2990 static int prev_ls_clock;
2991
2992 static void
2993 spu_sched_init_global (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
2994                        int max_ready ATTRIBUTE_UNUSED)
2995 {
2996   spu_sched_length = 0;
2997 }
2998
2999 static void
3000 spu_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
3001                 int max_ready ATTRIBUTE_UNUSED)
3002 {
3003   if (align_labels > 4 || align_loops > 4 || align_jumps > 4)
3004     {
3005       /* When any block might be at least 8-byte aligned, assume they
3006          will all be at least 8-byte aligned to make sure dual issue
3007          works out correctly. */
3008       spu_sched_length = 0;
3009     }
3010   spu_ls_first = INT_MAX;
3011   clock_var = -1;
3012   prev_ls_clock = -1;
3013   pipe0_clock = -1;
3014   pipe1_clock = -1;
3015   prev_clock_var = -1;
3016   prev_priority = -1;
3017 }
3018
3019 static int
3020 spu_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED,
3021                           int verbose ATTRIBUTE_UNUSED, rtx insn, int more)
3022 {
3023   int len;
3024   int p;
3025   if (GET_CODE (PATTERN (insn)) == USE
3026       || GET_CODE (PATTERN (insn)) == CLOBBER
3027       || (len = get_attr_length (insn)) == 0)
3028     return more;
3029
3030   spu_sched_length += len;
3031
3032   /* Reset on inline asm */
3033   if (INSN_CODE (insn) == -1)
3034     {
3035       spu_ls_first = INT_MAX;
3036       pipe0_clock = -1;
3037       pipe1_clock = -1;
3038       return 0;
3039     }
3040   p = get_pipe (insn);
3041   if (p == 0)
3042     pipe0_clock = clock_var;
3043   else
3044     pipe1_clock = clock_var;
3045
3046   if (in_spu_reorg)
3047     {
3048       if (clock_var - prev_ls_clock > 1
3049           || INSN_CODE (insn) == CODE_FOR_iprefetch)
3050         spu_ls_first = INT_MAX;
3051       if (uses_ls_unit (insn))
3052         {
3053           if (spu_ls_first == INT_MAX)
3054             spu_ls_first = spu_sched_length;
3055           prev_ls_clock = clock_var;
3056         }
3057
3058       /* The scheduler hasn't inserted the nop, but we will later on.
3059          Include those nops in spu_sched_length. */
3060       if (prev_clock_var == clock_var && (spu_sched_length & 7))
3061         spu_sched_length += 4;
3062       prev_clock_var = clock_var;
3063
3064       /* more is -1 when called from spu_sched_reorder for new insns
3065          that don't have INSN_PRIORITY */
3066       if (more >= 0)
3067         prev_priority = INSN_PRIORITY (insn);
3068     }
3069
3070   /* Always try issueing more insns.  spu_sched_reorder will decide 
3071      when the cycle should be advanced. */
3072   return 1;
3073 }
3074
3075 /* This function is called for both TARGET_SCHED_REORDER and
3076    TARGET_SCHED_REORDER2.  */
3077 static int
3078 spu_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
3079                    rtx *ready, int *nreadyp, int clock)
3080 {
3081   int i, nready = *nreadyp;
3082   int pipe_0, pipe_1, pipe_hbrp, pipe_ls, schedule_i;
3083   rtx insn;
3084
3085   clock_var = clock;
3086
3087   if (nready <= 0 || pipe1_clock >= clock)
3088     return 0;
3089
3090   /* Find any rtl insns that don't generate assembly insns and schedule
3091      them first. */
3092   for (i = nready - 1; i >= 0; i--)
3093     {
3094       insn = ready[i];
3095       if (INSN_CODE (insn) == -1
3096           || INSN_CODE (insn) == CODE_FOR_blockage
3097           || (INSN_P (insn) && get_attr_length (insn) == 0))
3098         {
3099           ready[i] = ready[nready - 1];
3100           ready[nready - 1] = insn;
3101           return 1;
3102         }
3103     }
3104
3105   pipe_0 = pipe_1 = pipe_hbrp = pipe_ls = schedule_i = -1;
3106   for (i = 0; i < nready; i++)
3107     if (INSN_CODE (ready[i]) != -1)
3108       {
3109         insn = ready[i];
3110         switch (get_attr_type (insn))
3111           {
3112           default:
3113           case TYPE_MULTI0:
3114           case TYPE_CONVERT:
3115           case TYPE_FX2:
3116           case TYPE_FX3:
3117           case TYPE_SPR:
3118           case TYPE_NOP:
3119           case TYPE_FXB:
3120           case TYPE_FPD:
3121           case TYPE_FP6:
3122           case TYPE_FP7:
3123             pipe_0 = i;
3124             break;
3125           case TYPE_LOAD:
3126           case TYPE_STORE:
3127             pipe_ls = i;
3128           case TYPE_LNOP:
3129           case TYPE_SHUF:
3130           case TYPE_BR:
3131           case TYPE_MULTI1:
3132           case TYPE_HBR:
3133             pipe_1 = i;
3134             break;
3135           case TYPE_IPREFETCH:
3136             pipe_hbrp = i;
3137             break;
3138           }
3139       }
3140
3141   /* In the first scheduling phase, schedule loads and stores together
3142      to increase the chance they will get merged during postreload CSE. */
3143   if (!reload_completed && pipe_ls >= 0)
3144     {
3145       insn = ready[pipe_ls];
3146       ready[pipe_ls] = ready[nready - 1];
3147       ready[nready - 1] = insn;
3148       return 1;
3149     }
3150
3151   /* If there is an hbrp ready, prefer it over other pipe 1 insns. */
3152   if (pipe_hbrp >= 0)
3153     pipe_1 = pipe_hbrp;
3154
3155   /* When we have loads/stores in every cycle of the last 15 insns and
3156      we are about to schedule another load/store, emit an hbrp insn
3157      instead. */
3158   if (in_spu_reorg
3159       && spu_sched_length - spu_ls_first >= 4 * 15
3160       && !(pipe0_clock < clock && pipe_0 >= 0) && pipe_1 == pipe_ls)
3161     {
3162       insn = sched_emit_insn (gen_iprefetch (GEN_INT (3)));
3163       recog_memoized (insn);
3164       if (pipe0_clock < clock)
3165         PUT_MODE (insn, TImode);
3166       spu_sched_variable_issue (file, verbose, insn, -1);
3167       return 0;
3168     }
3169
3170   /* In general, we want to emit nops to increase dual issue, but dual
3171      issue isn't faster when one of the insns could be scheduled later
3172      without effecting the critical path.  We look at INSN_PRIORITY to
3173      make a good guess, but it isn't perfect so -mdual-nops=n can be
3174      used to effect it. */
3175   if (in_spu_reorg && spu_dual_nops < 10)
3176     {
3177       /* When we are at an even address and we are not issueing nops to
3178          improve scheduling then we need to advance the cycle.  */
3179       if ((spu_sched_length & 7) == 0 && prev_clock_var == clock
3180           && (spu_dual_nops == 0
3181               || (pipe_1 != -1
3182                   && prev_priority >
3183                   INSN_PRIORITY (ready[pipe_1]) + spu_dual_nops)))
3184         return 0;
3185
3186       /* When at an odd address, schedule the highest priority insn
3187          without considering pipeline. */
3188       if ((spu_sched_length & 7) == 4 && prev_clock_var != clock
3189           && (spu_dual_nops == 0
3190               || (prev_priority >
3191                   INSN_PRIORITY (ready[nready - 1]) + spu_dual_nops)))
3192         return 1;
3193     }
3194
3195
3196   /* We haven't issued a pipe0 insn yet this cycle, if there is a
3197      pipe0 insn in the ready list, schedule it. */
3198   if (pipe0_clock < clock && pipe_0 >= 0)
3199     schedule_i = pipe_0;
3200
3201   /* Either we've scheduled a pipe0 insn already or there is no pipe0
3202      insn to schedule.  Put a pipe1 insn at the front of the ready list. */
3203   else
3204     schedule_i = pipe_1;
3205
3206   if (schedule_i > -1)
3207     {
3208       insn = ready[schedule_i];
3209       ready[schedule_i] = ready[nready - 1];
3210       ready[nready - 1] = insn;
3211       return 1;
3212     }
3213   return 0;
3214 }
3215
3216 /* INSN is dependent on DEP_INSN. */
3217 static int
3218 spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
3219 {
3220   rtx set;
3221
3222   /* The blockage pattern is used to prevent instructions from being
3223      moved across it and has no cost. */
3224   if (INSN_CODE (insn) == CODE_FOR_blockage
3225       || INSN_CODE (dep_insn) == CODE_FOR_blockage)
3226     return 0;
3227
3228   if ((INSN_P (insn) && get_attr_length (insn) == 0)
3229       || (INSN_P (dep_insn) && get_attr_length (dep_insn) == 0))
3230     return 0;
3231
3232   /* Make sure hbrps are spread out. */
3233   if (INSN_CODE (insn) == CODE_FOR_iprefetch
3234       && INSN_CODE (dep_insn) == CODE_FOR_iprefetch)
3235     return 8;
3236
3237   /* Make sure hints and hbrps are 2 cycles apart. */
3238   if ((INSN_CODE (insn) == CODE_FOR_iprefetch
3239        || INSN_CODE (insn) == CODE_FOR_hbr)
3240        && (INSN_CODE (dep_insn) == CODE_FOR_iprefetch
3241            || INSN_CODE (dep_insn) == CODE_FOR_hbr))
3242     return 2;
3243
3244   /* An hbrp has no real dependency on other insns. */
3245   if (INSN_CODE (insn) == CODE_FOR_iprefetch
3246       || INSN_CODE (dep_insn) == CODE_FOR_iprefetch)
3247     return 0;
3248
3249   /* Assuming that it is unlikely an argument register will be used in
3250      the first cycle of the called function, we reduce the cost for
3251      slightly better scheduling of dep_insn.  When not hinted, the
3252      mispredicted branch would hide the cost as well.  */
3253   if (CALL_P (insn))
3254   {
3255     rtx target = get_branch_target (insn);
3256     if (GET_CODE (target) != REG || !set_of (target, insn))
3257       return cost - 2;
3258     return cost;
3259   }
3260
3261   /* And when returning from a function, let's assume the return values
3262      are completed sooner too. */
3263   if (CALL_P (dep_insn))
3264     return cost - 2;
3265
3266   /* Make sure an instruction that loads from the back chain is schedule
3267      away from the return instruction so a hint is more likely to get
3268      issued. */
3269   if (INSN_CODE (insn) == CODE_FOR__return
3270       && (set = single_set (dep_insn))
3271       && GET_CODE (SET_DEST (set)) == REG
3272       && REGNO (SET_DEST (set)) == LINK_REGISTER_REGNUM)
3273     return 20;
3274
3275   /* The dfa scheduler sets cost to 0 for all anti-dependencies and the
3276      scheduler makes every insn in a block anti-dependent on the final
3277      jump_insn.  We adjust here so higher cost insns will get scheduled
3278      earlier. */
3279   if (JUMP_P (insn) && REG_NOTE_KIND (link) == REG_DEP_ANTI)
3280     return insn_cost (dep_insn) - 3;
3281
3282   return cost;
3283 }
3284 \f
3285 /* Create a CONST_DOUBLE from a string.  */
3286 struct rtx_def *
3287 spu_float_const (const char *string, enum machine_mode mode)
3288 {
3289   REAL_VALUE_TYPE value;
3290   value = REAL_VALUE_ATOF (string, mode);
3291   return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
3292 }
3293
3294 int
3295 spu_constant_address_p (rtx x)
3296 {
3297   return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
3298           || GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST
3299           || GET_CODE (x) == HIGH);
3300 }
3301
3302 static enum spu_immediate
3303 which_immediate_load (HOST_WIDE_INT val)
3304 {
3305   gcc_assert (val == trunc_int_for_mode (val, SImode));
3306
3307   if (val >= -0x8000 && val <= 0x7fff)
3308     return SPU_IL;
3309   if (val >= 0 && val <= 0x3ffff)
3310     return SPU_ILA;
3311   if ((val & 0xffff) == ((val >> 16) & 0xffff))
3312     return SPU_ILH;
3313   if ((val & 0xffff) == 0)
3314     return SPU_ILHU;
3315
3316   return SPU_NONE;
3317 }
3318
3319 /* Return true when OP can be loaded by one of the il instructions, or
3320    when flow2 is not completed and OP can be loaded using ilhu and iohl. */
3321 int
3322 immediate_load_p (rtx op, enum machine_mode mode)
3323 {
3324   if (CONSTANT_P (op))
3325     {
3326       enum immediate_class c = classify_immediate (op, mode);
3327       return c == IC_IL1 || c == IC_IL1s
3328              || (!epilogue_completed && (c == IC_IL2 || c == IC_IL2s));
3329     }
3330   return 0;
3331 }
3332
3333 /* Return true if the first SIZE bytes of arr is a constant that can be
3334    generated with cbd, chd, cwd or cdd.  When non-NULL, PRUN and PSTART
3335    represent the size and offset of the instruction to use. */
3336 static int
3337 cpat_info(unsigned char *arr, int size, int *prun, int *pstart)
3338 {
3339   int cpat, run, i, start;
3340   cpat = 1;
3341   run = 0;
3342   start = -1;
3343   for (i = 0; i < size && cpat; i++)
3344     if (arr[i] != i+16)
3345       { 
3346         if (!run)
3347           {
3348             start = i;
3349             if (arr[i] == 3)
3350               run = 1;
3351             else if (arr[i] == 2 && arr[i+1] == 3)
3352               run = 2;
3353             else if (arr[i] == 0)
3354               {
3355                 while (arr[i+run] == run && i+run < 16)
3356                   run++;
3357                 if (run != 4 && run != 8)
3358                   cpat = 0;
3359               }
3360             else
3361               cpat = 0;
3362             if ((i & (run-1)) != 0)
3363               cpat = 0;
3364             i += run;
3365           }
3366         else
3367           cpat = 0;
3368       }
3369   if (cpat && (run || size < 16))
3370     {
3371       if (run == 0)
3372         run = 1;
3373       if (prun)
3374         *prun = run;
3375       if (pstart)
3376         *pstart = start == -1 ? 16-run : start;
3377       return 1;
3378     }
3379   return 0;
3380 }
3381
3382 /* OP is a CONSTANT_P.  Determine what instructions can be used to load
3383    it into a register.  MODE is only valid when OP is a CONST_INT. */
3384 static enum immediate_class
3385 classify_immediate (rtx op, enum machine_mode mode)
3386 {
3387   HOST_WIDE_INT val;
3388   unsigned char arr[16];
3389   int i, j, repeated, fsmbi, repeat;
3390
3391   gcc_assert (CONSTANT_P (op));
3392
3393   if (GET_MODE (op) != VOIDmode)
3394     mode = GET_MODE (op);
3395
3396   /* A V4SI const_vector with all identical symbols is ok. */
3397   if (!flag_pic
3398       && mode == V4SImode
3399       && GET_CODE (op) == CONST_VECTOR
3400       && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
3401       && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE
3402       && CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)
3403       && CONST_VECTOR_ELT (op, 1) == CONST_VECTOR_ELT (op, 2)
3404       && CONST_VECTOR_ELT (op, 2) == CONST_VECTOR_ELT (op, 3))
3405     op = CONST_VECTOR_ELT (op, 0);
3406
3407   switch (GET_CODE (op))
3408     {
3409     case SYMBOL_REF:
3410     case LABEL_REF:
3411       return TARGET_LARGE_MEM ? IC_IL2s : IC_IL1s;
3412
3413     case CONST:
3414       /* We can never know if the resulting address fits in 18 bits and can be
3415          loaded with ila.  For now, assume the address will not overflow if
3416          the displacement is "small" (fits 'K' constraint).  */
3417       if (!TARGET_LARGE_MEM && GET_CODE (XEXP (op, 0)) == PLUS)
3418         {
3419           rtx sym = XEXP (XEXP (op, 0), 0);
3420           rtx cst = XEXP (XEXP (op, 0), 1);
3421
3422           if (GET_CODE (sym) == SYMBOL_REF
3423               && GET_CODE (cst) == CONST_INT
3424               && satisfies_constraint_K (cst))
3425             return IC_IL1s;
3426         }
3427       return IC_IL2s;
3428
3429     case HIGH:
3430       return IC_IL1s;
3431
3432     case CONST_VECTOR:
3433       for (i = 0; i < GET_MODE_NUNITS (mode); i++)
3434         if (GET_CODE (CONST_VECTOR_ELT (op, i)) != CONST_INT
3435             && GET_CODE (CONST_VECTOR_ELT (op, i)) != CONST_DOUBLE)
3436           return IC_POOL;
3437       /* Fall through. */
3438
3439     case CONST_INT:
3440     case CONST_DOUBLE:
3441       constant_to_array (mode, op, arr);
3442
3443       /* Check that each 4-byte slot is identical. */
3444       repeated = 1;
3445       for (i = 4; i < 16; i += 4)
3446         for (j = 0; j < 4; j++)
3447           if (arr[j] != arr[i + j])
3448             repeated = 0;
3449
3450       if (repeated)
3451         {
3452           val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
3453           val = trunc_int_for_mode (val, SImode);
3454
3455           if (which_immediate_load (val) != SPU_NONE)
3456             return IC_IL1;
3457         }
3458
3459       /* Any mode of 2 bytes or smaller can be loaded with an il
3460          instruction. */
3461       gcc_assert (GET_MODE_SIZE (mode) > 2);
3462
3463       fsmbi = 1;
3464       repeat = 0;
3465       for (i = 0; i < 16 && fsmbi; i++)
3466         if (arr[i] != 0 && repeat == 0)
3467           repeat = arr[i];
3468         else if (arr[i] != 0 && arr[i] != repeat)
3469           fsmbi = 0;
3470       if (fsmbi)
3471         return repeat == 0xff ? IC_FSMBI : IC_FSMBI2;
3472
3473       if (cpat_info (arr, GET_MODE_SIZE (mode), 0, 0))
3474         return IC_CPAT;
3475
3476       if (repeated)
3477         return IC_IL2;
3478