comparison gcc/config/spu/spu.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents 3bfb6c00c1e0
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
46 #include "reload.h" 46 #include "reload.h"
47 #include "cfglayout.h" 47 #include "cfglayout.h"
48 #include "sched-int.h" 48 #include "sched-int.h"
49 #include "params.h" 49 #include "params.h"
50 #include "assert.h" 50 #include "assert.h"
51 #include "c-common.h"
52 #include "machmode.h" 51 #include "machmode.h"
53 #include "gimple.h" 52 #include "gimple.h"
54 #include "tm-constrs.h" 53 #include "tm-constrs.h"
55 #include "ddg.h" 54 #include "ddg.h"
56 #include "sbitmap.h" 55 #include "sbitmap.h"
149 /* Target specific attribute specifications. */ 148 /* Target specific attribute specifications. */
150 char regs_ever_allocated[FIRST_PSEUDO_REGISTER]; 149 char regs_ever_allocated[FIRST_PSEUDO_REGISTER];
151 150
152 /* Prototypes and external defs. */ 151 /* Prototypes and external defs. */
153 static void spu_init_builtins (void); 152 static void spu_init_builtins (void);
153 static tree spu_builtin_decl (unsigned, bool);
154 static unsigned char spu_scalar_mode_supported_p (enum machine_mode mode); 154 static unsigned char spu_scalar_mode_supported_p (enum machine_mode mode);
155 static unsigned char spu_vector_mode_supported_p (enum machine_mode mode); 155 static unsigned char spu_vector_mode_supported_p (enum machine_mode mode);
156 static bool spu_legitimate_address_p (enum machine_mode, rtx, bool);
157 static bool spu_addr_space_legitimate_address_p (enum machine_mode, rtx,
158 bool, addr_space_t);
156 static rtx adjust_operand (rtx op, HOST_WIDE_INT * start); 159 static rtx adjust_operand (rtx op, HOST_WIDE_INT * start);
157 static rtx get_pic_reg (void); 160 static rtx get_pic_reg (void);
158 static int need_to_save_reg (int regno, int saving); 161 static int need_to_save_reg (int regno, int saving);
159 static rtx frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset); 162 static rtx frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset);
160 static rtx frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset); 163 static rtx frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset);
199 static unsigned char spu_function_ok_for_sibcall (tree decl, tree exp); 202 static unsigned char spu_function_ok_for_sibcall (tree decl, tree exp);
200 static void spu_init_libfuncs (void); 203 static void spu_init_libfuncs (void);
201 static bool spu_return_in_memory (const_tree type, const_tree fntype); 204 static bool spu_return_in_memory (const_tree type, const_tree fntype);
202 static void fix_range (const char *); 205 static void fix_range (const char *);
203 static void spu_encode_section_info (tree, rtx, int); 206 static void spu_encode_section_info (tree, rtx, int);
207 static rtx spu_legitimize_address (rtx, rtx, enum machine_mode);
208 static rtx spu_addr_space_legitimize_address (rtx, rtx, enum machine_mode,
209 addr_space_t);
204 static tree spu_builtin_mul_widen_even (tree); 210 static tree spu_builtin_mul_widen_even (tree);
205 static tree spu_builtin_mul_widen_odd (tree); 211 static tree spu_builtin_mul_widen_odd (tree);
206 static tree spu_builtin_mask_for_load (void); 212 static tree spu_builtin_mask_for_load (void);
207 static int spu_builtin_vectorization_cost (bool); 213 static int spu_builtin_vectorization_cost (bool);
208 static bool spu_vector_alignment_reachable (const_tree, bool); 214 static bool spu_vector_alignment_reachable (const_tree, bool);
209 static tree spu_builtin_vec_perm (tree, tree *); 215 static tree spu_builtin_vec_perm (tree, tree *);
216 static enum machine_mode spu_addr_space_pointer_mode (addr_space_t);
217 static enum machine_mode spu_addr_space_address_mode (addr_space_t);
218 static bool spu_addr_space_subset_p (addr_space_t, addr_space_t);
219 static rtx spu_addr_space_convert (rtx, tree, tree);
210 static int spu_sms_res_mii (struct ddg *g); 220 static int spu_sms_res_mii (struct ddg *g);
211 static void asm_file_start (void); 221 static void asm_file_start (void);
212 static unsigned int spu_section_type_flags (tree, const char *, int); 222 static unsigned int spu_section_type_flags (tree, const char *, int);
223 static section *spu_select_section (tree, int, unsigned HOST_WIDE_INT);
224 static void spu_unique_section (tree, int);
213 static rtx spu_expand_load (rtx, rtx, rtx, int); 225 static rtx spu_expand_load (rtx, rtx, rtx, int);
226 static void spu_trampoline_init (rtx, tree, rtx);
214 227
215 extern const char *reg_names[]; 228 extern const char *reg_names[];
216 rtx spu_compare_op0, spu_compare_op1;
217 229
218 /* Which instruction set architecture to use. */ 230 /* Which instruction set architecture to use. */
219 int spu_arch; 231 int spu_arch;
220 /* Which cpu are we tuning for. */ 232 /* Which cpu are we tuning for. */
221 int spu_tune; 233 int spu_tune;
267 spu_libgcc_cmp_return_mode (void); 279 spu_libgcc_cmp_return_mode (void);
268 280
269 static enum machine_mode 281 static enum machine_mode
270 spu_libgcc_shift_count_mode (void); 282 spu_libgcc_shift_count_mode (void);
271 283
284 /* Pointer mode for __ea references. */
285 #define EAmode (spu_ea_model != 32 ? DImode : SImode)
286
287
288 /* Table of machine attributes. */
289 static const struct attribute_spec spu_attribute_table[] =
290 {
291 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
292 { "naked", 0, 0, true, false, false, spu_handle_fndecl_attribute },
293 { "spu_vector", 0, 0, false, true, false, spu_handle_vector_attribute },
294 { NULL, 0, 0, false, false, false, NULL }
295 };
272 296
273 /* TARGET overrides. */ 297 /* TARGET overrides. */
274 298
299 #undef TARGET_ADDR_SPACE_POINTER_MODE
300 #define TARGET_ADDR_SPACE_POINTER_MODE spu_addr_space_pointer_mode
301
302 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
303 #define TARGET_ADDR_SPACE_ADDRESS_MODE spu_addr_space_address_mode
304
305 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
306 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
307 spu_addr_space_legitimate_address_p
308
309 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
310 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS spu_addr_space_legitimize_address
311
312 #undef TARGET_ADDR_SPACE_SUBSET_P
313 #define TARGET_ADDR_SPACE_SUBSET_P spu_addr_space_subset_p
314
315 #undef TARGET_ADDR_SPACE_CONVERT
316 #define TARGET_ADDR_SPACE_CONVERT spu_addr_space_convert
317
275 #undef TARGET_INIT_BUILTINS 318 #undef TARGET_INIT_BUILTINS
276 #define TARGET_INIT_BUILTINS spu_init_builtins 319 #define TARGET_INIT_BUILTINS spu_init_builtins
320 #undef TARGET_BUILTIN_DECL
321 #define TARGET_BUILTIN_DECL spu_builtin_decl
277 322
278 #undef TARGET_EXPAND_BUILTIN 323 #undef TARGET_EXPAND_BUILTIN
279 #define TARGET_EXPAND_BUILTIN spu_expand_builtin 324 #define TARGET_EXPAND_BUILTIN spu_expand_builtin
280 325
281 #undef TARGET_UNWIND_WORD_MODE 326 #undef TARGET_UNWIND_WORD_MODE
282 #define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode 327 #define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode
328
329 #undef TARGET_LEGITIMIZE_ADDRESS
330 #define TARGET_LEGITIMIZE_ADDRESS spu_legitimize_address
331
332 /* The current assembler doesn't like .4byte foo@ppu, so use the normal .long
333 and .quad for the debugger. When it is known that the assembler is fixed,
334 these can be removed. */
335 #undef TARGET_ASM_UNALIGNED_SI_OP
336 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
337
338 #undef TARGET_ASM_ALIGNED_DI_OP
339 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
283 340
284 /* The .8byte directive doesn't seem to work well for a 32 bit 341 /* The .8byte directive doesn't seem to work well for a 32 bit
285 architecture. */ 342 architecture. */
286 #undef TARGET_ASM_UNALIGNED_DI_OP 343 #undef TARGET_ASM_UNALIGNED_DI_OP
287 #define TARGET_ASM_UNALIGNED_DI_OP NULL 344 #define TARGET_ASM_UNALIGNED_DI_OP NULL
311 #define TARGET_SCHED_REORDER2 spu_sched_reorder 368 #define TARGET_SCHED_REORDER2 spu_sched_reorder
312 369
313 #undef TARGET_SCHED_ADJUST_COST 370 #undef TARGET_SCHED_ADJUST_COST
314 #define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost 371 #define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost
315 372
316 const struct attribute_spec spu_attribute_table[];
317 #undef TARGET_ATTRIBUTE_TABLE 373 #undef TARGET_ATTRIBUTE_TABLE
318 #define TARGET_ATTRIBUTE_TABLE spu_attribute_table 374 #define TARGET_ATTRIBUTE_TABLE spu_attribute_table
319 375
320 #undef TARGET_ASM_INTEGER 376 #undef TARGET_ASM_INTEGER
321 #define TARGET_ASM_INTEGER spu_assemble_integer 377 #define TARGET_ASM_INTEGER spu_assemble_integer
395 #undef TARGET_ASM_FILE_START 451 #undef TARGET_ASM_FILE_START
396 #define TARGET_ASM_FILE_START asm_file_start 452 #define TARGET_ASM_FILE_START asm_file_start
397 453
398 #undef TARGET_SECTION_TYPE_FLAGS 454 #undef TARGET_SECTION_TYPE_FLAGS
399 #define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags 455 #define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags
456
457 #undef TARGET_ASM_SELECT_SECTION
458 #define TARGET_ASM_SELECT_SECTION spu_select_section
459
460 #undef TARGET_ASM_UNIQUE_SECTION
461 #define TARGET_ASM_UNIQUE_SECTION spu_unique_section
462
463 #undef TARGET_LEGITIMATE_ADDRESS_P
464 #define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p
465
466 #undef TARGET_TRAMPOLINE_INIT
467 #define TARGET_TRAMPOLINE_INIT spu_trampoline_init
400 468
401 struct gcc_target targetm = TARGET_INITIALIZER; 469 struct gcc_target targetm = TARGET_INITIALIZER;
402 470
403 void 471 void
404 spu_optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED) 472 spu_optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
472 REAL_MODE_FORMAT (SFmode) = &spu_single_format; 540 REAL_MODE_FORMAT (SFmode) = &spu_single_format;
473 } 541 }
474 542
475 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in 543 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
476 struct attribute_spec.handler. */ 544 struct attribute_spec.handler. */
477
478 /* Table of machine attributes. */
479 const struct attribute_spec spu_attribute_table[] =
480 {
481 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
482 { "naked", 0, 0, true, false, false, spu_handle_fndecl_attribute },
483 { "spu_vector", 0, 0, false, true, false, spu_handle_vector_attribute },
484 { NULL, 0, 0, false, false, false, NULL }
485 };
486 545
487 /* True if MODE is valid for the target. By "valid", we mean able to 546 /* True if MODE is valid for the target. By "valid", we mean able to
488 be manipulated in non-trivial ways. In particular, this means all 547 be manipulated in non-trivial ways. In particular, this means all
489 the arithmetic is supported. */ 548 the arithmetic is supported. */
490 static bool 549 static bool
635 if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode)) 694 if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode))
636 emit_insn (gen_rtx_SET (VOIDmode, s0, gen_rtx_ZERO_EXTEND (TImode, r))); 695 emit_insn (gen_rtx_SET (VOIDmode, s0, gen_rtx_ZERO_EXTEND (TImode, r)));
637 else 696 else
638 emit_move_insn (s0, src); 697 emit_move_insn (s0, src);
639 } 698 }
640 else 699 else
641 { 700 {
642 gcc_assert (REG_P (src) && GET_MODE (src) == TImode); 701 gcc_assert (REG_P (src) && GET_MODE (src) == TImode);
643 s0 = gen_reg_rtx (TImode); 702 s0 = gen_reg_rtx (TImode);
644 emit_move_insn (s0, src); 703 emit_move_insn (s0, src);
645 } 704 }
862 the result of the compare. GCC can figure this out too if we don't 921 the result of the compare. GCC can figure this out too if we don't
863 provide all variations of compares, but GCC always wants to use 922 provide all variations of compares, but GCC always wants to use
864 WORD_MODE, we can generate better code in most cases if we do it 923 WORD_MODE, we can generate better code in most cases if we do it
865 ourselves. */ 924 ourselves. */
866 void 925 void
867 spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[]) 926 spu_emit_branch_or_set (int is_set, rtx cmp, rtx operands[])
868 { 927 {
869 int reverse_compare = 0; 928 int reverse_compare = 0;
870 int reverse_test = 0; 929 int reverse_test = 0;
871 rtx compare_result, eq_result; 930 rtx compare_result, eq_result;
872 rtx comp_rtx, eq_rtx; 931 rtx comp_rtx, eq_rtx;
873 rtx target = operands[0];
874 enum machine_mode comp_mode; 932 enum machine_mode comp_mode;
875 enum machine_mode op_mode; 933 enum machine_mode op_mode;
876 enum spu_comp_code scode, eq_code, ior_code; 934 enum spu_comp_code scode, eq_code;
935 enum insn_code ior_code;
936 enum rtx_code code = GET_CODE (cmp);
937 rtx op0 = XEXP (cmp, 0);
938 rtx op1 = XEXP (cmp, 1);
877 int index; 939 int index;
878 int eq_test = 0; 940 int eq_test = 0;
879 941
880 /* When spu_compare_op1 is a CONST_INT change (X >= C) to (X > C-1), 942 /* When op1 is a CONST_INT change (X >= C) to (X > C-1),
881 and so on, to keep the constant in operand 1. */ 943 and so on, to keep the constant in operand 1. */
882 if (GET_CODE (spu_compare_op1) == CONST_INT) 944 if (GET_CODE (op1) == CONST_INT)
883 { 945 {
884 HOST_WIDE_INT val = INTVAL (spu_compare_op1) - 1; 946 HOST_WIDE_INT val = INTVAL (op1) - 1;
885 if (trunc_int_for_mode (val, GET_MODE (spu_compare_op0)) == val) 947 if (trunc_int_for_mode (val, GET_MODE (op0)) == val)
886 switch (code) 948 switch (code)
887 { 949 {
888 case GE: 950 case GE:
889 spu_compare_op1 = GEN_INT (val); 951 op1 = GEN_INT (val);
890 code = GT; 952 code = GT;
891 break; 953 break;
892 case LT: 954 case LT:
893 spu_compare_op1 = GEN_INT (val); 955 op1 = GEN_INT (val);
894 code = LE; 956 code = LE;
895 break; 957 break;
896 case GEU: 958 case GEU:
897 spu_compare_op1 = GEN_INT (val); 959 op1 = GEN_INT (val);
898 code = GTU; 960 code = GTU;
899 break; 961 break;
900 case LTU: 962 case LTU:
901 spu_compare_op1 = GEN_INT (val); 963 op1 = GEN_INT (val);
902 code = LEU; 964 code = LEU;
903 break; 965 break;
904 default: 966 default:
905 break; 967 break;
906 } 968 }
907 } 969 }
908 970
909 comp_mode = SImode; 971 comp_mode = SImode;
910 op_mode = GET_MODE (spu_compare_op0); 972 op_mode = GET_MODE (op0);
911 973
912 switch (code) 974 switch (code)
913 { 975 {
914 case GE: 976 case GE:
915 scode = SPU_GT; 977 scode = SPU_GT;
1029 case V2DImode: 1091 case V2DImode:
1030 default: 1092 default:
1031 abort (); 1093 abort ();
1032 } 1094 }
1033 1095
1034 if (GET_MODE (spu_compare_op1) == DFmode 1096 if (GET_MODE (op1) == DFmode
1035 && (scode != SPU_GT && scode != SPU_EQ)) 1097 && (scode != SPU_GT && scode != SPU_EQ))
1036 abort (); 1098 abort ();
1037 1099
1038 if (is_set == 0 && spu_compare_op1 == const0_rtx 1100 if (is_set == 0 && op1 == const0_rtx
1039 && (GET_MODE (spu_compare_op0) == SImode 1101 && (GET_MODE (op0) == SImode
1040 || GET_MODE (spu_compare_op0) == HImode) && scode == SPU_EQ) 1102 || GET_MODE (op0) == HImode) && scode == SPU_EQ)
1041 { 1103 {
1042 /* Don't need to set a register with the result when we are 1104 /* Don't need to set a register with the result when we are
1043 comparing against zero and branching. */ 1105 comparing against zero and branching. */
1044 reverse_test = !reverse_test; 1106 reverse_test = !reverse_test;
1045 compare_result = spu_compare_op0; 1107 compare_result = op0;
1046 } 1108 }
1047 else 1109 else
1048 { 1110 {
1049 compare_result = gen_reg_rtx (comp_mode); 1111 compare_result = gen_reg_rtx (comp_mode);
1050 1112
1051 if (reverse_compare) 1113 if (reverse_compare)
1052 { 1114 {
1053 rtx t = spu_compare_op1; 1115 rtx t = op1;
1054 spu_compare_op1 = spu_compare_op0; 1116 op1 = op0;
1055 spu_compare_op0 = t; 1117 op0 = t;
1056 } 1118 }
1057 1119
1058 if (spu_comp_icode[index][scode] == 0) 1120 if (spu_comp_icode[index][scode] == 0)
1059 abort (); 1121 abort ();
1060 1122
1061 if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate) 1123 if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate)
1062 (spu_compare_op0, op_mode)) 1124 (op0, op_mode))
1063 spu_compare_op0 = force_reg (op_mode, spu_compare_op0); 1125 op0 = force_reg (op_mode, op0);
1064 if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate) 1126 if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate)
1065 (spu_compare_op1, op_mode)) 1127 (op1, op_mode))
1066 spu_compare_op1 = force_reg (op_mode, spu_compare_op1); 1128 op1 = force_reg (op_mode, op1);
1067 comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result, 1129 comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result,
1068 spu_compare_op0, 1130 op0, op1);
1069 spu_compare_op1);
1070 if (comp_rtx == 0) 1131 if (comp_rtx == 0)
1071 abort (); 1132 abort ();
1072 emit_insn (comp_rtx); 1133 emit_insn (comp_rtx);
1073 1134
1074 if (eq_test) 1135 if (eq_test)
1075 { 1136 {
1076 eq_result = gen_reg_rtx (comp_mode); 1137 eq_result = gen_reg_rtx (comp_mode);
1077 eq_rtx = GEN_FCN (spu_comp_icode[index][eq_code]) (eq_result, 1138 eq_rtx = GEN_FCN (spu_comp_icode[index][eq_code]) (eq_result,
1078 spu_compare_op0, 1139 op0, op1);
1079 spu_compare_op1);
1080 if (eq_rtx == 0) 1140 if (eq_rtx == 0)
1081 abort (); 1141 abort ();
1082 emit_insn (eq_rtx); 1142 emit_insn (eq_rtx);
1083 ior_code = ior_optab->handlers[(int)comp_mode].insn_code; 1143 ior_code = ior_optab->handlers[(int)comp_mode].insn_code;
1084 gcc_assert (ior_code != CODE_FOR_nothing); 1144 gcc_assert (ior_code != CODE_FOR_nothing);
1105 if (reverse_test) 1165 if (reverse_test)
1106 bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx); 1166 bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx);
1107 else 1167 else
1108 bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx); 1168 bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx);
1109 1169
1110 loc_ref = gen_rtx_LABEL_REF (VOIDmode, target); 1170 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
1111 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 1171 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
1112 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, 1172 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1113 loc_ref, pc_rtx))); 1173 loc_ref, pc_rtx)));
1114 } 1174 }
1115 else if (is_set == 2) 1175 else if (is_set == 2)
1116 { 1176 {
1177 rtx target = operands[0];
1117 int compare_size = GET_MODE_BITSIZE (comp_mode); 1178 int compare_size = GET_MODE_BITSIZE (comp_mode);
1118 int target_size = GET_MODE_BITSIZE (GET_MODE (target)); 1179 int target_size = GET_MODE_BITSIZE (GET_MODE (target));
1119 enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0); 1180 enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0);
1120 rtx select_mask; 1181 rtx select_mask;
1121 rtx op_t = operands[2]; 1182 rtx op_t = operands[2];
1146 else 1207 else
1147 emit_insn (gen_selb (target, op_f, op_t, select_mask)); 1208 emit_insn (gen_selb (target, op_f, op_t, select_mask));
1148 } 1209 }
1149 else 1210 else
1150 { 1211 {
1212 rtx target = operands[0];
1151 if (reverse_test) 1213 if (reverse_test)
1152 emit_insn (gen_rtx_SET (VOIDmode, compare_result, 1214 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
1153 gen_rtx_NOT (comp_mode, compare_result))); 1215 gen_rtx_NOT (comp_mode, compare_result)));
1154 if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode) 1216 if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode)
1155 emit_insn (gen_extendhisi2 (target, compare_result)); 1217 emit_insn (gen_extendhisi2 (target, compare_result));
1972 /* In this case we save the back chain first. */ 2034 /* In this case we save the back chain first. */
1973 insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size); 2035 insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size);
1974 insn = 2036 insn =
1975 frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0); 2037 frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0);
1976 } 2038 }
1977 else if (satisfies_constraint_K (GEN_INT (-total_size)))
1978 {
1979 insn = emit_move_insn (scratch_reg_0, sp_reg);
1980 insn =
1981 emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size)));
1982 }
1983 else 2039 else
1984 { 2040 {
1985 insn = emit_move_insn (scratch_reg_0, sp_reg); 2041 insn = emit_move_insn (scratch_reg_0, sp_reg);
1986 insn = 2042 insn =
1987 frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1); 2043 frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1);
1988 } 2044 }
1989 RTX_FRAME_RELATED_P (insn) = 1; 2045 RTX_FRAME_RELATED_P (insn) = 1;
1990 real = gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size)); 2046 real = gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size));
1991 REG_NOTES (insn) = 2047 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
1992 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, real, REG_NOTES (insn));
1993 2048
1994 if (total_size > 2000) 2049 if (total_size > 2000)
1995 { 2050 {
1996 /* Save the back chain ptr */ 2051 /* Save the back chain ptr */
1997 insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0); 2052 insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0);
2004 + crtl->outgoing_args_size; 2059 + crtl->outgoing_args_size;
2005 /* Set the new frame_pointer */ 2060 /* Set the new frame_pointer */
2006 insn = frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0); 2061 insn = frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
2007 RTX_FRAME_RELATED_P (insn) = 1; 2062 RTX_FRAME_RELATED_P (insn) = 1;
2008 real = gen_addsi3 (fp_reg, sp_reg, GEN_INT (fp_offset)); 2063 real = gen_addsi3 (fp_reg, sp_reg, GEN_INT (fp_offset));
2009 REG_NOTES (insn) = 2064 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
2010 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2011 real, REG_NOTES (insn));
2012 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY; 2065 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
2013 } 2066 }
2014 } 2067 }
2015 2068
2016 emit_note (NOTE_INSN_DELETED); 2069 emit_note (NOTE_INSN_DELETED);
2361 2414
2362 /* jump table */ 2415 /* jump table */
2363 if (GET_CODE (PATTERN (branch)) == ADDR_VEC 2416 if (GET_CODE (PATTERN (branch)) == ADDR_VEC
2364 || GET_CODE (PATTERN (branch)) == ADDR_DIFF_VEC) 2417 || GET_CODE (PATTERN (branch)) == ADDR_DIFF_VEC)
2365 return 0; 2418 return 0;
2419
2420 /* ASM GOTOs. */
2421 if (extract_asm_operands (PATTERN (branch)) != NULL)
2422 return NULL;
2366 2423
2367 set = single_set (branch); 2424 set = single_set (branch);
2368 src = SET_SRC (set); 2425 src = SET_SRC (set);
2369 if (GET_CODE (SET_DEST (set)) != PC) 2426 if (GET_CODE (SET_DEST (set)) != PC)
2370 abort (); 2427 abort ();
3604 && exp >= low && exp <= high; 3661 && exp >= low && exp <= high;
3605 } 3662 }
3606 return FALSE; 3663 return FALSE;
3607 } 3664 }
3608 3665
3666 /* Return true if X is a SYMBOL_REF to an __ea qualified variable. */
3667
3668 static int
3669 ea_symbol_ref (rtx *px, void *data ATTRIBUTE_UNUSED)
3670 {
3671 rtx x = *px;
3672 tree decl;
3673
3674 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
3675 {
3676 rtx plus = XEXP (x, 0);
3677 rtx op0 = XEXP (plus, 0);
3678 rtx op1 = XEXP (plus, 1);
3679 if (GET_CODE (op1) == CONST_INT)
3680 x = op0;
3681 }
3682
3683 return (GET_CODE (x) == SYMBOL_REF
3684 && (decl = SYMBOL_REF_DECL (x)) != 0
3685 && TREE_CODE (decl) == VAR_DECL
3686 && TYPE_ADDR_SPACE (TREE_TYPE (decl)));
3687 }
3688
3609 /* We accept: 3689 /* We accept:
3610 - any 32-bit constant (SImode, SFmode) 3690 - any 32-bit constant (SImode, SFmode)
3611 - any constant that can be generated with fsmbi (any mode) 3691 - any constant that can be generated with fsmbi (any mode)
3612 - a 64-bit constant where the high and low bits are identical 3692 - a 64-bit constant where the high and low bits are identical
3613 (DImode, DFmode) 3693 (DImode, DFmode)
3615 int 3695 int
3616 spu_legitimate_constant_p (rtx x) 3696 spu_legitimate_constant_p (rtx x)
3617 { 3697 {
3618 if (GET_CODE (x) == HIGH) 3698 if (GET_CODE (x) == HIGH)
3619 x = XEXP (x, 0); 3699 x = XEXP (x, 0);
3700
3701 /* Reject any __ea qualified reference. These can't appear in
3702 instructions but must be forced to the constant pool. */
3703 if (for_each_rtx (&x, ea_symbol_ref, 0))
3704 return 0;
3705
3620 /* V4SI with all identical symbols is valid. */ 3706 /* V4SI with all identical symbols is valid. */
3621 if (!flag_pic 3707 if (!flag_pic
3622 && GET_MODE (x) == V4SImode 3708 && GET_MODE (x) == V4SImode
3623 && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF 3709 && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF
3624 || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF 3710 || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF
3640 - reg + reg, alignment doesn't matter 3726 - reg + reg, alignment doesn't matter
3641 The alignment matters in the reg+const case because lqd and stqd 3727 The alignment matters in the reg+const case because lqd and stqd
3642 ignore the 4 least significant bits of the const. We only care about 3728 ignore the 4 least significant bits of the const. We only care about
3643 16 byte modes because the expand phase will change all smaller MEM 3729 16 byte modes because the expand phase will change all smaller MEM
3644 references to TImode. */ 3730 references to TImode. */
3645 int 3731 static bool
3646 spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, 3732 spu_legitimate_address_p (enum machine_mode mode,
3647 rtx x, int reg_ok_strict) 3733 rtx x, bool reg_ok_strict)
3648 { 3734 {
3649 int aligned = GET_MODE_SIZE (mode) >= 16; 3735 int aligned = GET_MODE_SIZE (mode) >= 16;
3650 if (aligned 3736 if (aligned
3651 && GET_CODE (x) == AND 3737 && GET_CODE (x) == AND
3652 && GET_CODE (XEXP (x, 1)) == CONST_INT 3738 && GET_CODE (XEXP (x, 1)) == CONST_INT
3653 && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT) - 16) 3739 && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT) - 16)
3654 x = XEXP (x, 0); 3740 x = XEXP (x, 0);
3655 switch (GET_CODE (x)) 3741 switch (GET_CODE (x))
3656 { 3742 {
3657 case LABEL_REF: 3743 case LABEL_REF:
3744 return !TARGET_LARGE_MEM;
3745
3658 case SYMBOL_REF: 3746 case SYMBOL_REF:
3659 case CONST: 3747 case CONST:
3748 /* Keep __ea references until reload so that spu_expand_mov can see them
3749 in MEMs. */
3750 if (ea_symbol_ref (&x, 0))
3751 return !reload_in_progress && !reload_completed;
3660 return !TARGET_LARGE_MEM; 3752 return !TARGET_LARGE_MEM;
3661 3753
3662 case CONST_INT: 3754 case CONST_INT:
3663 return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff; 3755 return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff;
3664 3756
3698 break; 3790 break;
3699 } 3791 }
3700 return FALSE; 3792 return FALSE;
3701 } 3793 }
3702 3794
3795 /* Like spu_legitimate_address_p, except with named addresses. */
3796 static bool
3797 spu_addr_space_legitimate_address_p (enum machine_mode mode, rtx x,
3798 bool reg_ok_strict, addr_space_t as)
3799 {
3800 if (as == ADDR_SPACE_EA)
3801 return (REG_P (x) && (GET_MODE (x) == EAmode));
3802
3803 else if (as != ADDR_SPACE_GENERIC)
3804 gcc_unreachable ();
3805
3806 return spu_legitimate_address_p (mode, x, reg_ok_strict);
3807 }
3808
3703 /* When the address is reg + const_int, force the const_int into a 3809 /* When the address is reg + const_int, force the const_int into a
3704 register. */ 3810 register. */
3705 rtx 3811 rtx
3706 spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, 3812 spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3707 enum machine_mode mode) 3813 enum machine_mode mode ATTRIBUTE_UNUSED)
3708 { 3814 {
3709 rtx op0, op1; 3815 rtx op0, op1;
3710 /* Make sure both operands are registers. */ 3816 /* Make sure both operands are registers. */
3711 if (GET_CODE (x) == PLUS) 3817 if (GET_CODE (x) == PLUS)
3712 { 3818 {
3725 mark_reg_pointer (op1, 128); 3831 mark_reg_pointer (op1, 128);
3726 } 3832 }
3727 else if (GET_CODE (op1) != REG) 3833 else if (GET_CODE (op1) != REG)
3728 op1 = force_reg (Pmode, op1); 3834 op1 = force_reg (Pmode, op1);
3729 x = gen_rtx_PLUS (Pmode, op0, op1); 3835 x = gen_rtx_PLUS (Pmode, op0, op1);
3730 if (spu_legitimate_address (mode, x, 0)) 3836 }
3731 return x; 3837 return x;
3732 } 3838 }
3733 return NULL_RTX; 3839
3840 /* Like spu_legitimate_address, except with named address support. */
3841 static rtx
3842 spu_addr_space_legitimize_address (rtx x, rtx oldx, enum machine_mode mode,
3843 addr_space_t as)
3844 {
3845 if (as != ADDR_SPACE_GENERIC)
3846 return x;
3847
3848 return spu_legitimize_address (x, oldx, mode);
3734 } 3849 }
3735 3850
3736 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in 3851 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
3737 struct attribute_spec.handler. */ 3852 struct attribute_spec.handler. */
3738 static tree 3853 static tree
3741 tree args ATTRIBUTE_UNUSED, 3856 tree args ATTRIBUTE_UNUSED,
3742 int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) 3857 int flags ATTRIBUTE_UNUSED, bool * no_add_attrs)
3743 { 3858 {
3744 if (TREE_CODE (*node) != FUNCTION_DECL) 3859 if (TREE_CODE (*node) != FUNCTION_DECL)
3745 { 3860 {
3746 warning (0, "`%s' attribute only applies to functions", 3861 warning (0, "%qE attribute only applies to functions",
3747 IDENTIFIER_POINTER (name)); 3862 name);
3748 *no_add_attrs = true; 3863 *no_add_attrs = true;
3749 } 3864 }
3750 3865
3751 return NULL_TREE; 3866 return NULL_TREE;
3752 } 3867 }
3799 result = build_qualified_type (result, TYPE_QUALS (type)); 3914 result = build_qualified_type (result, TYPE_QUALS (type));
3800 3915
3801 *no_add_attrs = true; /* No need to hang on to the attribute. */ 3916 *no_add_attrs = true; /* No need to hang on to the attribute. */
3802 3917
3803 if (!result) 3918 if (!result)
3804 warning (0, "`%s' attribute ignored", IDENTIFIER_POINTER (name)); 3919 warning (0, "%qE attribute ignored", name);
3805 else 3920 else
3806 *node = lang_hooks.types.reconstruct_complex_type (*node, result); 3921 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
3807 3922
3808 return NULL_TREE; 3923 return NULL_TREE;
3809 } 3924 }
3954 bool owp; 4069 bool owp;
3955 4070
3956 record = (*lang_hooks.types.make_type) (RECORD_TYPE); 4071 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
3957 4072
3958 type_decl = 4073 type_decl =
3959 build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record); 4074 build_decl (BUILTINS_LOCATION,
3960 4075 TYPE_DECL, get_identifier ("__va_list_tag"), record);
3961 f_args = build_decl (FIELD_DECL, get_identifier ("__args"), ptr_type_node); 4076
3962 f_skip = build_decl (FIELD_DECL, get_identifier ("__skip"), ptr_type_node); 4077 f_args = build_decl (BUILTINS_LOCATION,
4078 FIELD_DECL, get_identifier ("__args"), ptr_type_node);
4079 f_skip = build_decl (BUILTINS_LOCATION,
4080 FIELD_DECL, get_identifier ("__skip"), ptr_type_node);
3963 4081
3964 DECL_FIELD_CONTEXT (f_args) = record; 4082 DECL_FIELD_CONTEXT (f_args) = record;
3965 DECL_ALIGN (f_args) = 128; 4083 DECL_ALIGN (f_args) = 128;
3966 DECL_USER_ALIGN (f_args) = 1; 4084 DECL_USER_ALIGN (f_args) = 1;
3967 4085
4069 build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE); 4187 build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE);
4070 skip = 4188 skip =
4071 build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE); 4189 build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
4072 4190
4073 addr = create_tmp_var (ptr_type_node, "va_arg"); 4191 addr = create_tmp_var (ptr_type_node, "va_arg");
4074 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
4075 4192
4076 /* if an object is dynamically sized, a pointer to it is passed 4193 /* if an object is dynamically sized, a pointer to it is passed
4077 instead of the object itself. */ 4194 instead of the object itself. */
4078 pass_by_reference_p = spu_pass_by_reference (NULL, TYPE_MODE (type), type, 4195 pass_by_reference_p = spu_pass_by_reference (NULL, TYPE_MODE (type), type,
4079 false); 4196 false);
4099 4216
4100 /* update VALIST.__args */ 4217 /* update VALIST.__args */
4101 tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, paddedsize); 4218 tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, paddedsize);
4102 gimplify_assign (unshare_expr (args), tmp, pre_p); 4219 gimplify_assign (unshare_expr (args), tmp, pre_p);
4103 4220
4104 addr = fold_convert (build_pointer_type (type), addr); 4221 addr = fold_convert (build_pointer_type_for_mode (type, ptr_mode, true),
4222 addr);
4105 4223
4106 if (pass_by_reference_p) 4224 if (pass_by_reference_p)
4107 addr = build_va_arg_indirect_ref (addr); 4225 addr = build_va_arg_indirect_ref (addr);
4108 4226
4109 return build_va_arg_indirect_ref (addr); 4227 return build_va_arg_indirect_ref (addr);
4231 return 1; 4349 return 1;
4232 4350
4233 return 0; 4351 return 0;
4234 } 4352 }
4235 4353
4354 static GTY(()) rtx cache_fetch; /* __cache_fetch function */
4355 static GTY(()) rtx cache_fetch_dirty; /* __cache_fetch_dirty function */
4356 static alias_set_type ea_alias_set = -1; /* alias set for __ea memory */
4357
4358 /* MEM is known to be an __ea qualified memory access. Emit a call to
4359 fetch the ppu memory to local store, and return its address in local
4360 store. */
4361
4362 static void
4363 ea_load_store (rtx mem, bool is_store, rtx ea_addr, rtx data_addr)
4364 {
4365 if (is_store)
4366 {
4367 rtx ndirty = GEN_INT (GET_MODE_SIZE (GET_MODE (mem)));
4368 if (!cache_fetch_dirty)
4369 cache_fetch_dirty = init_one_libfunc ("__cache_fetch_dirty");
4370 emit_library_call_value (cache_fetch_dirty, data_addr, LCT_NORMAL, Pmode,
4371 2, ea_addr, EAmode, ndirty, SImode);
4372 }
4373 else
4374 {
4375 if (!cache_fetch)
4376 cache_fetch = init_one_libfunc ("__cache_fetch");
4377 emit_library_call_value (cache_fetch, data_addr, LCT_NORMAL, Pmode,
4378 1, ea_addr, EAmode);
4379 }
4380 }
4381
4382 /* Like ea_load_store, but do the cache tag comparison and, for stores,
4383 dirty bit marking, inline.
4384
4385 The cache control data structure is an array of
4386
4387 struct __cache_tag_array
4388 {
4389 unsigned int tag_lo[4];
4390 unsigned int tag_hi[4];
4391 void *data_pointer[4];
4392 int reserved[4];
4393 vector unsigned short dirty_bits[4];
4394 } */
4395
4396 static void
4397 ea_load_store_inline (rtx mem, bool is_store, rtx ea_addr, rtx data_addr)
4398 {
4399 rtx ea_addr_si;
4400 HOST_WIDE_INT v;
4401 rtx tag_size_sym = gen_rtx_SYMBOL_REF (Pmode, "__cache_tag_array_size");
4402 rtx tag_arr_sym = gen_rtx_SYMBOL_REF (Pmode, "__cache_tag_array");
4403 rtx index_mask = gen_reg_rtx (SImode);
4404 rtx tag_arr = gen_reg_rtx (Pmode);
4405 rtx splat_mask = gen_reg_rtx (TImode);
4406 rtx splat = gen_reg_rtx (V4SImode);
4407 rtx splat_hi = NULL_RTX;
4408 rtx tag_index = gen_reg_rtx (Pmode);
4409 rtx block_off = gen_reg_rtx (SImode);
4410 rtx tag_addr = gen_reg_rtx (Pmode);
4411 rtx tag = gen_reg_rtx (V4SImode);
4412 rtx cache_tag = gen_reg_rtx (V4SImode);
4413 rtx cache_tag_hi = NULL_RTX;
4414 rtx cache_ptrs = gen_reg_rtx (TImode);
4415 rtx cache_ptrs_si = gen_reg_rtx (SImode);
4416 rtx tag_equal = gen_reg_rtx (V4SImode);
4417 rtx tag_equal_hi = NULL_RTX;
4418 rtx tag_eq_pack = gen_reg_rtx (V4SImode);
4419 rtx tag_eq_pack_si = gen_reg_rtx (SImode);
4420 rtx eq_index = gen_reg_rtx (SImode);
4421 rtx bcomp, hit_label, hit_ref, cont_label, insn;
4422
4423 if (spu_ea_model != 32)
4424 {
4425 splat_hi = gen_reg_rtx (V4SImode);
4426 cache_tag_hi = gen_reg_rtx (V4SImode);
4427 tag_equal_hi = gen_reg_rtx (V4SImode);
4428 }
4429
4430 emit_move_insn (index_mask, plus_constant (tag_size_sym, -128));
4431 emit_move_insn (tag_arr, tag_arr_sym);
4432 v = 0x0001020300010203LL;
4433 emit_move_insn (splat_mask, immed_double_const (v, v, TImode));
4434 ea_addr_si = ea_addr;
4435 if (spu_ea_model != 32)
4436 ea_addr_si = convert_to_mode (SImode, ea_addr, 1);
4437
4438 /* tag_index = ea_addr & (tag_array_size - 128) */
4439 emit_insn (gen_andsi3 (tag_index, ea_addr_si, index_mask));
4440
4441 /* splat ea_addr to all 4 slots. */
4442 emit_insn (gen_shufb (splat, ea_addr_si, ea_addr_si, splat_mask));
4443 /* Similarly for high 32 bits of ea_addr. */
4444 if (spu_ea_model != 32)
4445 emit_insn (gen_shufb (splat_hi, ea_addr, ea_addr, splat_mask));
4446
4447 /* block_off = ea_addr & 127 */
4448 emit_insn (gen_andsi3 (block_off, ea_addr_si, spu_const (SImode, 127)));
4449
4450 /* tag_addr = tag_arr + tag_index */
4451 emit_insn (gen_addsi3 (tag_addr, tag_arr, tag_index));
4452
4453 /* Read cache tags. */
4454 emit_move_insn (cache_tag, gen_rtx_MEM (V4SImode, tag_addr));
4455 if (spu_ea_model != 32)
4456 emit_move_insn (cache_tag_hi, gen_rtx_MEM (V4SImode,
4457 plus_constant (tag_addr, 16)));
4458
4459 /* tag = ea_addr & -128 */
4460 emit_insn (gen_andv4si3 (tag, splat, spu_const (V4SImode, -128)));
4461
4462 /* Read all four cache data pointers. */
4463 emit_move_insn (cache_ptrs, gen_rtx_MEM (TImode,
4464 plus_constant (tag_addr, 32)));
4465
4466 /* Compare tags. */
4467 emit_insn (gen_ceq_v4si (tag_equal, tag, cache_tag));
4468 if (spu_ea_model != 32)
4469 {
4470 emit_insn (gen_ceq_v4si (tag_equal_hi, splat_hi, cache_tag_hi));
4471 emit_insn (gen_andv4si3 (tag_equal, tag_equal, tag_equal_hi));
4472 }
4473
4474 /* At most one of the tags compare equal, so tag_equal has one
4475 32-bit slot set to all 1's, with the other slots all zero.
4476 gbb picks off low bit from each byte in the 128-bit registers,
4477 so tag_eq_pack is one of 0xf000, 0x0f00, 0x00f0, 0x000f, assuming
4478 we have a hit. */
4479 emit_insn (gen_spu_gbb (tag_eq_pack, spu_gen_subreg (V16QImode, tag_equal)));
4480 emit_insn (gen_spu_convert (tag_eq_pack_si, tag_eq_pack));
4481
4482 /* So counting leading zeros will set eq_index to 16, 20, 24 or 28. */
4483 emit_insn (gen_clzsi2 (eq_index, tag_eq_pack_si));
4484
4485 /* Allowing us to rotate the corresponding cache data pointer to slot0.
4486 (rotating eq_index mod 16 bytes). */
4487 emit_insn (gen_rotqby_ti (cache_ptrs, cache_ptrs, eq_index));
4488 emit_insn (gen_spu_convert (cache_ptrs_si, cache_ptrs));
4489
4490 /* Add block offset to form final data address. */
4491 emit_insn (gen_addsi3 (data_addr, cache_ptrs_si, block_off));
4492
4493 /* Check that we did hit. */
4494 hit_label = gen_label_rtx ();
4495 hit_ref = gen_rtx_LABEL_REF (VOIDmode, hit_label);
4496 bcomp = gen_rtx_NE (SImode, tag_eq_pack_si, const0_rtx);
4497 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4498 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4499 hit_ref, pc_rtx)));
4500 /* Say that this branch is very likely to happen. */
4501 v = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100 - 1;
4502 REG_NOTES (insn)
4503 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (v), REG_NOTES (insn));
4504
4505 ea_load_store (mem, is_store, ea_addr, data_addr);
4506 cont_label = gen_label_rtx ();
4507 emit_jump_insn (gen_jump (cont_label));
4508 emit_barrier ();
4509
4510 emit_label (hit_label);
4511
4512 if (is_store)
4513 {
4514 HOST_WIDE_INT v_hi;
4515 rtx dirty_bits = gen_reg_rtx (TImode);
4516 rtx dirty_off = gen_reg_rtx (SImode);
4517 rtx dirty_128 = gen_reg_rtx (TImode);
4518 rtx neg_block_off = gen_reg_rtx (SImode);
4519
4520 /* Set up mask with one dirty bit per byte of the mem we are
4521 writing, starting from top bit. */
4522 v_hi = v = -1;
4523 v <<= (128 - GET_MODE_SIZE (GET_MODE (mem))) & 63;
4524 if ((128 - GET_MODE_SIZE (GET_MODE (mem))) >= 64)
4525 {
4526 v_hi = v;
4527 v = 0;
4528 }
4529 emit_move_insn (dirty_bits, immed_double_const (v, v_hi, TImode));
4530
4531 /* Form index into cache dirty_bits. eq_index is one of
4532 0x10, 0x14, 0x18 or 0x1c. Multiplying by 4 gives us
4533 0x40, 0x50, 0x60 or 0x70 which just happens to be the
4534 offset to each of the four dirty_bits elements. */
4535 emit_insn (gen_ashlsi3 (dirty_off, eq_index, spu_const (SImode, 2)));
4536
4537 emit_insn (gen_spu_lqx (dirty_128, tag_addr, dirty_off));
4538
4539 /* Rotate bit mask to proper bit. */
4540 emit_insn (gen_negsi2 (neg_block_off, block_off));
4541 emit_insn (gen_rotqbybi_ti (dirty_bits, dirty_bits, neg_block_off));
4542 emit_insn (gen_rotqbi_ti (dirty_bits, dirty_bits, neg_block_off));
4543
4544 /* Or in the new dirty bits. */
4545 emit_insn (gen_iorti3 (dirty_128, dirty_bits, dirty_128));
4546
4547 /* Store. */
4548 emit_insn (gen_spu_stqx (dirty_128, tag_addr, dirty_off));
4549 }
4550
4551 emit_label (cont_label);
4552 }
4553
4554 static rtx
4555 expand_ea_mem (rtx mem, bool is_store)
4556 {
4557 rtx ea_addr;
4558 rtx data_addr = gen_reg_rtx (Pmode);
4559 rtx new_mem;
4560
4561 ea_addr = force_reg (EAmode, XEXP (mem, 0));
4562 if (optimize_size || optimize == 0)
4563 ea_load_store (mem, is_store, ea_addr, data_addr);
4564 else
4565 ea_load_store_inline (mem, is_store, ea_addr, data_addr);
4566
4567 if (ea_alias_set == -1)
4568 ea_alias_set = new_alias_set ();
4569
4570 /* We generate a new MEM RTX to refer to the copy of the data
4571 in the cache. We do not copy memory attributes (except the
4572 alignment) from the original MEM, as they may no longer apply
4573 to the cache copy. */
4574 new_mem = gen_rtx_MEM (GET_MODE (mem), data_addr);
4575 set_mem_alias_set (new_mem, ea_alias_set);
4576 set_mem_align (new_mem, MIN (MEM_ALIGN (mem), 128 * 8));
4577
4578 return new_mem;
4579 }
4580
4236 int 4581 int
4237 spu_expand_mov (rtx * ops, enum machine_mode mode) 4582 spu_expand_mov (rtx * ops, enum machine_mode mode)
4238 { 4583 {
4239 if (GET_CODE (ops[0]) == SUBREG && !valid_subreg (ops[0])) 4584 if (GET_CODE (ops[0]) == SUBREG && !valid_subreg (ops[0]))
4240 abort (); 4585 abort ();
4288 emit_move_insn (ops[0], GEN_INT (val)); 4633 emit_move_insn (ops[0], GEN_INT (val));
4289 return 1; 4634 return 1;
4290 } 4635 }
4291 } 4636 }
4292 if (MEM_P (ops[0])) 4637 if (MEM_P (ops[0]))
4293 return spu_split_store (ops); 4638 {
4639 if (MEM_ADDR_SPACE (ops[0]))
4640 ops[0] = expand_ea_mem (ops[0], true);
4641 return spu_split_store (ops);
4642 }
4294 if (MEM_P (ops[1])) 4643 if (MEM_P (ops[1]))
4295 return spu_split_load (ops); 4644 {
4645 if (MEM_ADDR_SPACE (ops[1]))
4646 ops[1] = expand_ea_mem (ops[1], false);
4647 return spu_split_load (ops);
4648 }
4296 4649
4297 return 0; 4650 return 0;
4298 } 4651 }
4299 4652
4300 static void 4653 static void
4315 emit_move_insn (dst, reg); 4668 emit_move_insn (dst, reg);
4316 } 4669 }
4317 } 4670 }
4318 4671
4319 /* Load TImode values into DST0 and DST1 (when it is non-NULL) using 4672 /* Load TImode values into DST0 and DST1 (when it is non-NULL) using
4320 the address from SRC and SRC+16. Return a REG or CONST_INT that 4673 the address from SRC and SRC+16. Return a REG or CONST_INT that
4321 specifies how many bytes to rotate the loaded registers, plus any 4674 specifies how many bytes to rotate the loaded registers, plus any
4322 extra from EXTRA_ROTQBY. The address and rotate amounts are 4675 extra from EXTRA_ROTQBY. The address and rotate amounts are
4323 normalized to improve merging of loads and rotate computations. */ 4676 normalized to improve merging of loads and rotate computations. */
4324 static rtx 4677 static rtx
4325 spu_expand_load (rtx dst0, rtx dst1, rtx src, int extra_rotby) 4678 spu_expand_load (rtx dst0, rtx dst1, rtx src, int extra_rotby)
4877 5230
4878 /* Convert a 16 byte array to a constant of mode MODE. When MODE is 5231 /* Convert a 16 byte array to a constant of mode MODE. When MODE is
4879 smaller than 16 bytes, use the bytes that would represent that value 5232 smaller than 16 bytes, use the bytes that would represent that value
4880 in a register, e.g., for QImode return the value of arr[3]. */ 5233 in a register, e.g., for QImode return the value of arr[3]. */
4881 rtx 5234 rtx
4882 array_to_constant (enum machine_mode mode, unsigned char arr[16]) 5235 array_to_constant (enum machine_mode mode, const unsigned char arr[16])
4883 { 5236 {
4884 enum machine_mode inner_mode; 5237 enum machine_mode inner_mode;
4885 rtvec v; 5238 rtvec v;
4886 int units, size, i, j, k; 5239 int units, size, i, j, k;
4887 HOST_WIDE_INT val; 5240 HOST_WIDE_INT val;
4945 } 5298 }
4946 5299
4947 static void 5300 static void
4948 reloc_diagnostic (rtx x) 5301 reloc_diagnostic (rtx x)
4949 { 5302 {
4950 tree loc_decl, decl = 0; 5303 tree decl = 0;
4951 const char *msg;
4952 if (!flag_pic || !(TARGET_WARN_RELOC || TARGET_ERROR_RELOC)) 5304 if (!flag_pic || !(TARGET_WARN_RELOC || TARGET_ERROR_RELOC))
4953 return; 5305 return;
4954 5306
4955 if (GET_CODE (x) == SYMBOL_REF) 5307 if (GET_CODE (x) == SYMBOL_REF)
4956 decl = SYMBOL_REF_DECL (x); 5308 decl = SYMBOL_REF_DECL (x);
4960 5312
4961 /* SYMBOL_REF_DECL is not necessarily a DECL. */ 5313 /* SYMBOL_REF_DECL is not necessarily a DECL. */
4962 if (decl && !DECL_P (decl)) 5314 if (decl && !DECL_P (decl))
4963 decl = 0; 5315 decl = 0;
4964 5316
4965 /* We use last_assemble_variable_decl to get line information. It's
4966 not always going to be right and might not even be close, but will
4967 be right for the more common cases. */
4968 if (!last_assemble_variable_decl || in_section == ctors_section)
4969 loc_decl = decl;
4970 else
4971 loc_decl = last_assemble_variable_decl;
4972
4973 /* The decl could be a string constant. */ 5317 /* The decl could be a string constant. */
4974 if (decl && DECL_P (decl)) 5318 if (decl && DECL_P (decl))
4975 msg = "%Jcreating run-time relocation for %qD"; 5319 {
4976 else 5320 location_t loc;
4977 msg = "creating run-time relocation"; 5321 /* We use last_assemble_variable_decl to get line information. It's
4978 5322 not always going to be right and might not even be close, but will
4979 if (TARGET_WARN_RELOC) 5323 be right for the more common cases. */
4980 warning (0, msg, loc_decl, decl); 5324 if (!last_assemble_variable_decl || in_section == ctors_section)
4981 else 5325 loc = DECL_SOURCE_LOCATION (decl);
4982 error (msg, loc_decl, decl); 5326 else
5327 loc = DECL_SOURCE_LOCATION (last_assemble_variable_decl);
5328
5329 if (TARGET_WARN_RELOC)
5330 warning_at (loc, 0,
5331 "creating run-time relocation for %qD", decl);
5332 else
5333 error_at (loc,
5334 "creating run-time relocation for %qD", decl);
5335 }
5336 else
5337 {
5338 if (TARGET_WARN_RELOC)
5339 warning_at (input_location, 0, "creating run-time relocation");
5340 else
5341 error_at (input_location, "creating run-time relocation");
5342 }
4983 } 5343 }
4984 5344
4985 /* Hook into assemble_integer so we can generate an error for run-time 5345 /* Hook into assemble_integer so we can generate an error for run-time
4986 relocations. The SPU ABI disallows them. */ 5346 relocations. The SPU ABI disallows them. */
4987 static bool 5347 static bool
5270 #define DEF_BUILTIN(fcode, icode, name, type, params) \ 5630 #define DEF_BUILTIN(fcode, icode, name, type, params) \
5271 {fcode, icode, name, type, params, NULL_TREE}, 5631 {fcode, icode, name, type, params, NULL_TREE},
5272 #include "spu-builtins.def" 5632 #include "spu-builtins.def"
5273 #undef DEF_BUILTIN 5633 #undef DEF_BUILTIN
5274 }; 5634 };
5635
5636 /* Returns the rs6000 builtin decl for CODE. */
5637
5638 static tree
5639 spu_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
5640 {
5641 if (code >= NUM_SPU_BUILTINS)
5642 return error_mark_node;
5643
5644 return spu_builtins[code].fndecl;
5645 }
5646
5275 5647
5276 static void 5648 static void
5277 spu_init_builtins (void) 5649 spu_init_builtins (void)
5278 { 5650 {
5279 struct spu_builtin_description *d; 5651 struct spu_builtin_description *d;
5574 } 5946 }
5575 } 5947 }
5576 emit_insn (gen_rotqby_ti (rot, from, offset)); 5948 emit_insn (gen_rotqby_ti (rot, from, offset));
5577 } 5949 }
5578 5950
5579 void 5951 static void
5580 spu_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt) 5952 spu_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
5581 { 5953 {
5954 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
5582 rtx shuf = gen_reg_rtx (V4SImode); 5955 rtx shuf = gen_reg_rtx (V4SImode);
5583 rtx insn = gen_reg_rtx (V4SImode); 5956 rtx insn = gen_reg_rtx (V4SImode);
5584 rtx shufc; 5957 rtx shufc;
5585 rtx insnc; 5958 rtx insnc;
5586 rtx mem; 5959 rtx mem;
5591 if (TARGET_LARGE_MEM) 5964 if (TARGET_LARGE_MEM)
5592 { 5965 {
5593 rtx rotl = gen_reg_rtx (V4SImode); 5966 rtx rotl = gen_reg_rtx (V4SImode);
5594 rtx mask = gen_reg_rtx (V4SImode); 5967 rtx mask = gen_reg_rtx (V4SImode);
5595 rtx bi = gen_reg_rtx (SImode); 5968 rtx bi = gen_reg_rtx (SImode);
5596 unsigned char shufa[16] = { 5969 static unsigned char const shufa[16] = {
5597 2, 3, 0, 1, 18, 19, 16, 17, 5970 2, 3, 0, 1, 18, 19, 16, 17,
5598 0, 1, 2, 3, 16, 17, 18, 19 5971 0, 1, 2, 3, 16, 17, 18, 19
5599 }; 5972 };
5600 unsigned char insna[16] = { 5973 static unsigned char const insna[16] = {
5601 0x41, 0, 0, 79, 5974 0x41, 0, 0, 79,
5602 0x41, 0, 0, STATIC_CHAIN_REGNUM, 5975 0x41, 0, 0, STATIC_CHAIN_REGNUM,
5603 0x60, 0x80, 0, 79, 5976 0x60, 0x80, 0, 79,
5604 0x60, 0x80, 0, STATIC_CHAIN_REGNUM 5977 0x60, 0x80, 0, STATIC_CHAIN_REGNUM
5605 }; 5978 };
5610 emit_insn (gen_shufb (shuf, fnaddr, cxt, shufc)); 5983 emit_insn (gen_shufb (shuf, fnaddr, cxt, shufc));
5611 emit_insn (gen_vrotlv4si3 (rotl, shuf, spu_const (V4SImode, 7))); 5984 emit_insn (gen_vrotlv4si3 (rotl, shuf, spu_const (V4SImode, 7)));
5612 emit_insn (gen_movv4si (mask, spu_const (V4SImode, 0xffff << 7))); 5985 emit_insn (gen_movv4si (mask, spu_const (V4SImode, 0xffff << 7)));
5613 emit_insn (gen_selb (insn, insnc, rotl, mask)); 5986 emit_insn (gen_selb (insn, insnc, rotl, mask));
5614 5987
5615 mem = memory_address (Pmode, tramp); 5988 mem = adjust_address (m_tramp, V4SImode, 0);
5616 emit_move_insn (gen_rtx_MEM (V4SImode, mem), insn); 5989 emit_move_insn (mem, insn);
5617 5990
5618 emit_move_insn (bi, GEN_INT (0x35000000 + (79 << 7))); 5991 emit_move_insn (bi, GEN_INT (0x35000000 + (79 << 7)));
5619 mem = memory_address (Pmode, plus_constant (tramp, 16)); 5992 mem = adjust_address (m_tramp, Pmode, 16);
5620 emit_move_insn (gen_rtx_MEM (Pmode, mem), bi); 5993 emit_move_insn (mem, bi);
5621 } 5994 }
5622 else 5995 else
5623 { 5996 {
5624 rtx scxt = gen_reg_rtx (SImode); 5997 rtx scxt = gen_reg_rtx (SImode);
5625 rtx sfnaddr = gen_reg_rtx (SImode); 5998 rtx sfnaddr = gen_reg_rtx (SImode);
5626 unsigned char insna[16] = { 5999 static unsigned char const insna[16] = {
5627 0x42, 0, 0, STATIC_CHAIN_REGNUM, 6000 0x42, 0, 0, STATIC_CHAIN_REGNUM,
5628 0x30, 0, 0, 0, 6001 0x30, 0, 0, 0,
5629 0, 0, 0, 0, 6002 0, 0, 0, 0,
5630 0, 0, 0, 0 6003 0, 0, 0, 0
5631 }; 6004 };
5643 emit_insn (gen_cpat 6016 emit_insn (gen_cpat
5644 (shufc, stack_pointer_rtx, GEN_INT (4), GEN_INT (4))); 6017 (shufc, stack_pointer_rtx, GEN_INT (4), GEN_INT (4)));
5645 emit_insn (gen_shufb (shuf, sfnaddr, scxt, shufc)); 6018 emit_insn (gen_shufb (shuf, sfnaddr, scxt, shufc));
5646 emit_insn (gen_iorv4si3 (insn, insnc, shuf)); 6019 emit_insn (gen_iorv4si3 (insn, insnc, shuf));
5647 6020
5648 mem = memory_address (Pmode, tramp); 6021 mem = adjust_address (m_tramp, V4SImode, 0);
5649 emit_move_insn (gen_rtx_MEM (V4SImode, mem), insn); 6022 emit_move_insn (mem, insn);
5650
5651 } 6023 }
5652 emit_insn (gen_sync ()); 6024 emit_insn (gen_sync ());
5653 } 6025 }
5654 6026
5655 void 6027 void
6082 6454
6083 static int 6455 static int
6084 expand_builtin_args (struct spu_builtin_description *d, tree exp, 6456 expand_builtin_args (struct spu_builtin_description *d, tree exp,
6085 rtx target, rtx ops[]) 6457 rtx target, rtx ops[])
6086 { 6458 {
6087 enum insn_code icode = d->icode; 6459 enum insn_code icode = (enum insn_code) d->icode;
6088 int i = 0, a; 6460 int i = 0, a;
6089 6461
6090 /* Expand the arguments into rtl. */ 6462 /* Expand the arguments into rtl. */
6091 6463
6092 if (d->parm[0] != SPU_BTI_VOID) 6464 if (d->parm[0] != SPU_BTI_VOID)
6095 for (a = 0; d->parm[a+1] != SPU_BTI_END_OF_PARAMS; i++, a++) 6467 for (a = 0; d->parm[a+1] != SPU_BTI_END_OF_PARAMS; i++, a++)
6096 { 6468 {
6097 tree arg = CALL_EXPR_ARG (exp, a); 6469 tree arg = CALL_EXPR_ARG (exp, a);
6098 if (arg == 0) 6470 if (arg == 0)
6099 abort (); 6471 abort ();
6100 ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0); 6472 ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6101 } 6473 }
6102 6474
6103 /* The insn pattern may have additional operands (SCRATCH). 6475 /* The insn pattern may have additional operands (SCRATCH).
6104 Return the number of actual non-SCRATCH operands. */ 6476 Return the number of actual non-SCRATCH operands. */
6105 gcc_assert (i <= insn_data[icode].n_operands); 6477 gcc_assert (i <= insn_data[icode].n_operands);
6110 spu_expand_builtin_1 (struct spu_builtin_description *d, 6482 spu_expand_builtin_1 (struct spu_builtin_description *d,
6111 tree exp, rtx target) 6483 tree exp, rtx target)
6112 { 6484 {
6113 rtx pat; 6485 rtx pat;
6114 rtx ops[8]; 6486 rtx ops[8];
6115 enum insn_code icode = d->icode; 6487 enum insn_code icode = (enum insn_code) d->icode;
6116 enum machine_mode mode, tmode; 6488 enum machine_mode mode, tmode;
6117 int i, p; 6489 int i, p;
6118 int n_operands; 6490 int n_operands;
6119 tree return_type; 6491 tree return_type;
6120 6492
6413 6785
6414 gcc_assert (d); 6786 gcc_assert (d);
6415 return d->fndecl; 6787 return d->fndecl;
6416 } 6788 }
6417 6789
6790 /* Return the appropriate mode for a named address pointer. */
6791 static enum machine_mode
6792 spu_addr_space_pointer_mode (addr_space_t addrspace)
6793 {
6794 switch (addrspace)
6795 {
6796 case ADDR_SPACE_GENERIC:
6797 return ptr_mode;
6798 case ADDR_SPACE_EA:
6799 return EAmode;
6800 default:
6801 gcc_unreachable ();
6802 }
6803 }
6804
6805 /* Return the appropriate mode for a named address address. */
6806 static enum machine_mode
6807 spu_addr_space_address_mode (addr_space_t addrspace)
6808 {
6809 switch (addrspace)
6810 {
6811 case ADDR_SPACE_GENERIC:
6812 return Pmode;
6813 case ADDR_SPACE_EA:
6814 return EAmode;
6815 default:
6816 gcc_unreachable ();
6817 }
6818 }
6819
6820 /* Determine if one named address space is a subset of another. */
6821
6822 static bool
6823 spu_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
6824 {
6825 gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_EA);
6826 gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_EA);
6827
6828 if (subset == superset)
6829 return true;
6830
6831 /* If we have -mno-address-space-conversion, treat __ea and generic as not
6832 being subsets but instead as disjoint address spaces. */
6833 else if (!TARGET_ADDRESS_SPACE_CONVERSION)
6834 return false;
6835
6836 else
6837 return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_EA);
6838 }
6839
6840 /* Convert from one address space to another. */
6841 static rtx
6842 spu_addr_space_convert (rtx op, tree from_type, tree to_type)
6843 {
6844 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
6845 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
6846
6847 gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_EA);
6848 gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_EA);
6849
6850 if (to_as == ADDR_SPACE_GENERIC && from_as == ADDR_SPACE_EA)
6851 {
6852 rtx result, ls;
6853
6854 ls = gen_const_mem (DImode,
6855 gen_rtx_SYMBOL_REF (Pmode, "__ea_local_store"));
6856 set_mem_align (ls, 128);
6857
6858 result = gen_reg_rtx (Pmode);
6859 ls = force_reg (Pmode, convert_modes (Pmode, DImode, ls, 1));
6860 op = force_reg (Pmode, convert_modes (Pmode, EAmode, op, 1));
6861 ls = emit_conditional_move (ls, NE, op, const0_rtx, Pmode,
6862 ls, const0_rtx, Pmode, 1);
6863
6864 emit_insn (gen_subsi3 (result, op, ls));
6865
6866 return result;
6867 }
6868
6869 else if (to_as == ADDR_SPACE_EA && from_as == ADDR_SPACE_GENERIC)
6870 {
6871 rtx result, ls;
6872
6873 ls = gen_const_mem (DImode,
6874 gen_rtx_SYMBOL_REF (Pmode, "__ea_local_store"));
6875 set_mem_align (ls, 128);
6876
6877 result = gen_reg_rtx (EAmode);
6878 ls = force_reg (EAmode, convert_modes (EAmode, DImode, ls, 1));
6879 op = force_reg (Pmode, op);
6880 ls = emit_conditional_move (ls, NE, op, const0_rtx, Pmode,
6881 ls, const0_rtx, EAmode, 1);
6882 op = force_reg (EAmode, convert_modes (EAmode, Pmode, op, 1));
6883
6884 if (EAmode == SImode)
6885 emit_insn (gen_addsi3 (result, op, ls));
6886 else
6887 emit_insn (gen_adddi3 (result, op, ls));
6888
6889 return result;
6890 }
6891
6892 else
6893 gcc_unreachable ();
6894 }
6895
6896
6418 /* Count the total number of instructions in each pipe and return the 6897 /* Count the total number of instructions in each pipe and return the
6419 maximum, which is used as the Minimum Iteration Interval (MII) 6898 maximum, which is used as the Minimum Iteration Interval (MII)
6420 in the modulo scheduler. get_pipe() will return -2, -1, 0, or 1. 6899 in the modulo scheduler. get_pipe() will return -2, -1, 0, or 1.
6421 -2 are instructions that can go in pipe0 or pipe1. */ 6900 -2 are instructions that can go in pipe0 or pipe1. */
6422 static int 6901 static int
6505 spu_section_type_flags (tree decl, const char *name, int reloc) 6984 spu_section_type_flags (tree decl, const char *name, int reloc)
6506 { 6985 {
6507 /* .toe needs to have type @nobits. */ 6986 /* .toe needs to have type @nobits. */
6508 if (strcmp (name, ".toe") == 0) 6987 if (strcmp (name, ".toe") == 0)
6509 return SECTION_BSS; 6988 return SECTION_BSS;
6989 /* Don't load _ea into the current address space. */
6990 if (strcmp (name, "._ea") == 0)
6991 return SECTION_WRITE | SECTION_DEBUG;
6510 return default_section_type_flags (decl, name, reloc); 6992 return default_section_type_flags (decl, name, reloc);
6993 }
6994
6995 /* Implement targetm.select_section. */
6996 static section *
6997 spu_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
6998 {
6999 /* Variables and constants defined in the __ea address space
7000 go into a special section named "._ea". */
7001 if (TREE_TYPE (decl) != error_mark_node
7002 && TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_EA)
7003 {
7004 /* We might get called with string constants, but get_named_section
7005 doesn't like them as they are not DECLs. Also, we need to set
7006 flags in that case. */
7007 if (!DECL_P (decl))
7008 return get_section ("._ea", SECTION_WRITE | SECTION_DEBUG, NULL);
7009
7010 return get_named_section (decl, "._ea", reloc);
7011 }
7012
7013 return default_elf_select_section (decl, reloc, align);
7014 }
7015
7016 /* Implement targetm.unique_section. */
7017 static void
7018 spu_unique_section (tree decl, int reloc)
7019 {
7020 /* We don't support unique section names in the __ea address
7021 space for now. */
7022 if (TREE_TYPE (decl) != error_mark_node
7023 && TYPE_ADDR_SPACE (TREE_TYPE (decl)) != 0)
7024 return;
7025
7026 default_unique_section (decl, reloc);
6511 } 7027 }
6512 7028
6513 /* Generate a constant or register which contains 2^SCALE. We assume 7029 /* Generate a constant or register which contains 2^SCALE. We assume
6514 the result is valid for MODE. Currently, MODE must be V4SFmode and 7030 the result is valid for MODE. Currently, MODE must be V4SFmode and
6515 SCALE must be SImode. */ 7031 SCALE must be SImode. */
6528 emit_insn (gen_addsi3 (exp, reg, GEN_INT (127))); 7044 emit_insn (gen_addsi3 (exp, reg, GEN_INT (127)));
6529 emit_insn (gen_ashlsi3 (exp, exp, GEN_INT (23))); 7045 emit_insn (gen_ashlsi3 (exp, exp, GEN_INT (23)));
6530 emit_insn (gen_spu_splats (mul, gen_rtx_SUBREG (GET_MODE_INNER (mode), exp, 0))); 7046 emit_insn (gen_spu_splats (mul, gen_rtx_SUBREG (GET_MODE_INNER (mode), exp, 0)));
6531 return mul; 7047 return mul;
6532 } 7048 }
6533 else 7049 else
6534 { 7050 {
6535 HOST_WIDE_INT exp = 127 + INTVAL (scale); 7051 HOST_WIDE_INT exp = 127 + INTVAL (scale);
6536 unsigned char arr[16]; 7052 unsigned char arr[16];
6537 arr[0] = arr[4] = arr[8] = arr[12] = exp >> 1; 7053 arr[0] = arr[4] = arr[8] = arr[12] = exp >> 1;
6538 arr[1] = arr[5] = arr[9] = arr[13] = exp << 7; 7054 arr[1] = arr[5] = arr[9] = arr[13] = exp << 7;
6556 rtx op1 = gen_rtx_REG (TImode, REGNO (ops[1])); 7072 rtx op1 = gen_rtx_REG (TImode, REGNO (ops[1]));
6557 emit_insn (gen_move_insn (op0, op1)); 7073 emit_insn (gen_move_insn (op0, op1));
6558 } 7074 }
6559 } 7075 }
6560 7076
7077 void
7078 spu_function_profiler (FILE * file, int labelno)
7079 {
7080 fprintf (file, "# profile\n");
7081 fprintf (file, "brsl $75, _mcount\n");
7082 }
7083
6561 #include "gt-spu.h" 7084 #include "gt-spu.h"
6562