Hi, This patch fixes the widening multiply high/low operations to work correctly in the presence of the first patch of this series, which reverses the meanings of multiply even/odd instructions. Here we reorder the input operands to the vector merge low/high instructions.
The general rule is that vmrghh(x,y) [BE] = vmrglh(y,x) [LE], and so on; that is, we need to reverse the usage of merge high and merge low, and also swap their inputs, to obtain the same semantics. In this case we are only swapping the inputs, because the reversed usage of high and low has already been done for us in the generic handling code for VEC_WIDEN_MULT_LO_EXPR. Bootstrapped and tested with the rest of the patch set on powerpc64{,le}-unknown-linux-gnu, with no regressions. Is this ok for trunk? Thanks, Bill 2013-11-03 Bill Schmidt <wschm...@linux.vnet.ibm.com> * config/rs6000/altivec.md (vec_widen_umult_hi_v16qi): Swap arguments to merge instruction for little endian. (vec_widen_umult_lo_v16qi): Likewise. (vec_widen_smult_hi_v16qi): Likewise. (vec_widen_smult_lo_v16qi): Likewise. (vec_widen_umult_hi_v8hi): Likewise. (vec_widen_umult_lo_v8hi): Likewise. (vec_widen_smult_hi_v8hi): Likewise. (vec_widen_smult_lo_v8hi): Likewise. Index: gcc/config/rs6000/altivec.md =================================================================== --- gcc/config/rs6000/altivec.md (revision 204192) +++ gcc/config/rs6000/altivec.md (working copy) @@ -2185,7 +2235,10 @@ emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghh (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrghh (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrghh (operands[0], vo, ve)); DONE; }") @@ -2202,7 +2255,10 @@ emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglh (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrglh (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrglh (operands[0], vo, ve)); DONE; }") @@ -2219,7 +2275,10 @@ emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghh (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrghh (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrghh (operands[0], vo, ve)); DONE; }") @@ -2236,7 +2295,10 @@ emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglh (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrglh (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrglh (operands[0], vo, ve)); DONE; }") @@ -2253,7 +2315,10 @@ emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghw (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrghw (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrghw (operands[0], vo, ve)); DONE; }") @@ -2270,7 +2335,10 @@ emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglw (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrglw (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrglw (operands[0], vo, ve)); DONE; }") @@ -2287,7 +2355,10 @@ emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghw (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrghw (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrghw (operands[0], vo, ve)); DONE; }") @@ -2304,7 +2375,10 @@ emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2])); emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglw (operands[0], ve, vo)); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vmrglw (operands[0], ve, vo)); + else + emit_insn (gen_altivec_vmrglw (operands[0], vo, ve)); DONE; }")