diff options
author | Pat Haugen <pthaugen@us.ibm.com> | 2015-08-27 18:20:45 +0000 |
---|---|---|
committer | Pat Haugen <pthaugen@gcc.gnu.org> | 2015-08-27 18:20:45 +0000 |
commit | 2b6fb4aa47e25c530ee97c4354896443403da585 (patch) | |
tree | b2cec59ef3a583ee196b3de9541aa025bd9713c7 /gcc/config | |
parent | b7e36a33eb4b756440b9a93f812414a42800f38b (diff) | |
download | gcc-2b6fb4aa47e25c530ee97c4354896443403da585.zip gcc-2b6fb4aa47e25c530ee97c4354896443403da585.tar.gz gcc-2b6fb4aa47e25c530ee97c4354896443403da585.tar.bz2 |
vector.md (vec_shr_<mode>): Fix to do a shift instead of a rotate.
* config/rs6000/vector.md (vec_shr_<mode>): Fix to do a shift
instead of a rotate.
* gcc.target/powerpc/vec-shr.c: New.
From-SVN: r227270
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/vector.md | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index 4a62fbb..8821dec 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -977,6 +977,8 @@ ;; General shift amounts can be supported using vsro + vsr. We're ;; not expecting to see these yet (the vectorizer currently ;; generates only shifts by a whole number of vector elements). +;; Note that the vec_shr operation is actually defined as +;; 'shift toward element 0' so is a shr for LE and shl for BE. (define_expand "vec_shr_<mode>" [(match_operand:VEC_L 0 "vlogical_operand" "") (match_operand:VEC_L 1 "vlogical_operand" "") @@ -987,6 +989,7 @@ rtx bitshift = operands[2]; rtx shift; rtx insn; + rtx zero_reg, op1, op2; HOST_WIDE_INT bitshift_val; HOST_WIDE_INT byteshift_val; @@ -996,19 +999,29 @@ if (bitshift_val & 0x7) FAIL; byteshift_val = (bitshift_val >> 3); + zero_reg = gen_reg_rtx (<MODE>mode); + emit_move_insn (zero_reg, CONST0_RTX (<MODE>mode)); if (!BYTES_BIG_ENDIAN) - byteshift_val = 16 - byteshift_val; + { + byteshift_val = 16 - byteshift_val; + op1 = zero_reg; + op2 = operands[1]; + } + else + { + op1 = operands[1]; + op2 = zero_reg; + } + if (TARGET_VSX && (byteshift_val & 0x3) == 0) { shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); - insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1], - shift); + insn = gen_vsx_xxsldwi_<mode> (operands[0], op1, op2, shift); } else { shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], - shift); + insn = gen_altivec_vsldoi_<mode> (operands[0], op1, op2, shift); } emit_insn (insn); |