diff options
Diffstat (limited to 'gcc-4.8/gcc/config/rs6000/vector.md')
-rw-r--r-- | gcc-4.8/gcc/config/rs6000/vector.md | 130 |
1 files changed, 63 insertions, 67 deletions
diff --git a/gcc-4.8/gcc/config/rs6000/vector.md b/gcc-4.8/gcc/config/rs6000/vector.md index 5a6e1fb30..5c45ec3f9 100644 --- a/gcc-4.8/gcc/config/rs6000/vector.md +++ b/gcc-4.8/gcc/config/rs6000/vector.md @@ -24,28 +24,28 @@ ;; Vector int modes -(define_mode_iterator VEC_I [V16QI V8HI V4SI]) +(define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI]) ;; Vector float modes (define_mode_iterator VEC_F [V4SF V2DF]) ;; Vector arithmetic modes -(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF V2DF]) +(define_mode_iterator VEC_A [V16QI V8HI V4SI V2DI V4SF V2DF]) ;; Vector modes that need alginment via permutes (define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF]) ;; Vector logical modes -(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF TI]) +(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI]) ;; Vector modes for moves. Don't do TImode here. -(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF]) +(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI]) ;; Vector modes for types that don't need a realignment under VSX -(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF]) +(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF V1TI]) ;; Vector comparison modes -(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF]) +(define_mode_iterator VEC_C [V16QI V8HI V4SI V2DI V4SF V2DF]) ;; Vector init/extract modes (define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF]) @@ -54,7 +54,8 @@ (define_mode_iterator VEC_64 [V2DI V2DF]) ;; Vector reload iterator -(define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF DF TI]) +(define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF V1TI + SF SD SI DF DD DI TI]) ;; Base type from vector mode (define_mode_attr VEC_base [(V16QI "QI") @@ -63,6 +64,7 @@ (V2DI "DI") (V4SF "SF") (V2DF "DF") + (V1TI "TI") (TI "TI")]) ;; Same size integer type for floating point data @@ -88,7 +90,8 @@ (smax "smax")]) -;; Vector move instructions. +;; Vector move instructions. Little-endian VSX loads and stores require +;; special handling to circumvent "element endianness." (define_expand "mov<mode>" [(set (match_operand:VEC_M 0 "nonimmediate_operand" "") (match_operand:VEC_M 1 "any_operand" ""))] @@ -104,6 +107,15 @@ && !vlogical_operand (operands[1], <MODE>mode)) operands[1] = force_reg (<MODE>mode, operands[1]); } + if (!BYTES_BIG_ENDIAN + && VECTOR_MEM_VSX_P (<MODE>mode) + && !gpr_or_gpr_p (operands[0], operands[1]) + && (memory_operand (operands[0], <MODE>mode) + ^ memory_operand (operands[1], <MODE>mode))) + { + rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode); + DONE; + } }) ;; Generic vector floating point load/store instructions. These will match @@ -126,7 +138,9 @@ (match_operand:VEC_L 1 "input_operand" ""))] "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed - && gpr_or_gpr_p (operands[0], operands[1])" + && gpr_or_gpr_p (operands[0], operands[1]) + && !direct_move_p (operands[0], operands[1]) + && !quad_load_store_p (operands[0], operands[1])" [(pc)] { rs6000_split_multireg_move (operands[0], operands[1]); @@ -249,7 +263,7 @@ [(set (match_operand:VEC_F 0 "vfloat_operand" "") (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_VSX_P (<MODE>mode) || VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" { if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) { @@ -395,7 +409,7 @@ (match_operand:VEC_I 5 "vint_operand" "")]) (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], @@ -451,7 +465,7 @@ (match_operand:VEC_I 5 "vint_operand" "")]) (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" " { if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], @@ -505,14 +519,14 @@ [(set (match_operand:VEC_I 0 "vint_operand" "") (gtu:VEC_I (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_expand "vector_geu<mode>" [(set (match_operand:VEC_I 0 "vint_operand" "") (geu:VEC_I (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") (define_insn_and_split "*vector_uneq<mode>" @@ -595,8 +609,8 @@ (ge:VEC_F (match_dup 2) (match_dup 1))) (set (match_dup 0) - (not:VEC_F (ior:VEC_F (match_dup 3) - (match_dup 4))))] + (and:VEC_F (not:VEC_F (match_dup 3)) + (not:VEC_F (match_dup 4))))] " { operands[3] = gen_reg_rtx (<MODE>mode); @@ -708,47 +722,18 @@ "") -;; Vector logical instructions -(define_expand "xor<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "ior<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "and<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") +;; Vector count leading zeros +(define_expand "clz<mode>2" + [(set (match_operand:VEC_I 0 "register_operand" "") + (clz:VEC_I (match_operand:VEC_I 1 "register_operand" "")))] + "TARGET_P8_VECTOR") -(define_expand "one_cmpl<mode>2" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") +;; Vector population count +(define_expand "popcount<mode>2" + [(set (match_operand:VEC_I 0 "register_operand" "") + (popcount:VEC_I (match_operand:VEC_I 1 "register_operand" "")))] + "TARGET_P8_VECTOR") -(define_expand "nor<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" ""))))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "andc<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" "")) - (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") ;; Same size conversions (define_expand "float<VEC_int><mode>2" @@ -889,7 +874,7 @@ { rtx reg = gen_reg_rtx (V4SFmode); - rs6000_expand_interleave (reg, operands[1], operands[1], true); + rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); DONE; }) @@ -901,7 +886,7 @@ { rtx reg = gen_reg_rtx (V4SFmode); - rs6000_expand_interleave (reg, operands[1], operands[1], false); + rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); DONE; }) @@ -913,7 +898,7 @@ { rtx reg = gen_reg_rtx (V4SImode); - rs6000_expand_interleave (reg, operands[1], operands[1], true); + rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); DONE; }) @@ -925,7 +910,7 @@ { rtx reg = gen_reg_rtx (V4SImode); - rs6000_expand_interleave (reg, operands[1], operands[1], false); + rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); DONE; }) @@ -937,7 +922,7 @@ { rtx reg = gen_reg_rtx (V4SImode); - rs6000_expand_interleave (reg, operands[1], operands[1], true); + rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); DONE; }) @@ -949,7 +934,7 @@ { rtx reg = gen_reg_rtx (V4SImode); - rs6000_expand_interleave (reg, operands[1], operands[1], false); + rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); DONE; }) @@ -963,8 +948,19 @@ (match_operand:V16QI 3 "vlogical_operand" "")] "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { - emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2], - operands[3])); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], + operands[2], operands[3])); + else + { + /* We have changed lvsr to lvsl, so to complete the transformation + of vperm for LE, we must swap the inputs. */ + rtx unspec = gen_rtx_UNSPEC (<MODE>mode, + gen_rtvec (3, operands[2], + operands[1], operands[3]), + UNSPEC_VPERM); + emit_move_insn (operands[0], unspec); + } DONE; }) @@ -1064,7 +1060,7 @@ [(set (match_operand:VEC_I 0 "vint_operand" "") (rotate:VEC_I (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Expanders for arithmetic shift left on each vector element @@ -1072,7 +1068,7 @@ [(set (match_operand:VEC_I 0 "vint_operand" "") (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Expanders for logical shift right on each vector element @@ -1080,7 +1076,7 @@ [(set (match_operand:VEC_I 0 "vint_operand" "") (lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Expanders for arithmetic shift right on each vector element @@ -1088,7 +1084,7 @@ [(set (match_operand:VEC_I 0 "vint_operand" "") (ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "") (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" "") ;; Vector reduction expanders for VSX |