aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2022-04-22 15:45:00 +0000
committerSegher Boessenkool <segher@kernel.crashing.org>2022-04-22 19:29:08 +0000
commit4938888ae1a1680e2aebf394d8fe80faad745bc7 (patch)
tree1e79f56e2d9e61ea4d1cbbc6a364cfdc25271fe1
parent55c17bc75c4c65d75597b545680f9fbff163ccd1 (diff)
downloadgcc-4938888ae1a1680e2aebf394d8fe80faad745bc7.zip
gcc-4938888ae1a1680e2aebf394d8fe80faad745bc7.tar.gz
gcc-4938888ae1a1680e2aebf394d8fe80faad745bc7.tar.bz2
rs6000: Fix pack for soft-float (PR105334)
For PR103623 I fixed unpack, but pack is broken as well, as reported in PR105334. Fixing that is a bit more code, but it is pretty simple code nonetheless. 2022-04-22 Segher Boessenkool <segher@kernel.crashing.org> PR target/105334 * config/rs6000/rs6000.md (pack<mode> for FMOVE128): New expander. (pack<mode> for FMOVE128): Rename and split the insn_and_split to... (pack<mode>_hard for FMOVE128): ... this... (pack<mode>_soft for FMOVE128): ... and this.
-rw-r--r--gcc/config/rs6000/rs6000.md45
1 files changed, 43 insertions, 2 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index a39b95f..64049a6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -14602,13 +14602,26 @@
}
[(set_attr "type" "fp,fpstore,store")])
-(define_insn_and_split "pack<mode>"
+(define_expand "pack<mode>"
+ [(use (match_operand:FMOVE128 0 "register_operand"))
+ (use (match_operand:<FP128_64> 1 "register_operand"))
+ (use (match_operand:<FP128_64> 2 "register_operand"))]
+ "FLOAT128_2REG_P (<MODE>mode)"
+{
+ if (TARGET_HARD_FLOAT)
+ emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn_and_split "pack<mode>_hard"
[(set (match_operand:FMOVE128 0 "register_operand" "=&d")
(unspec:FMOVE128
[(match_operand:<FP128_64> 1 "register_operand" "d")
(match_operand:<FP128_64> 2 "register_operand" "d")]
UNSPEC_PACK_128BIT))]
- "FLOAT128_2REG_P (<MODE>mode)"
+ "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
"#"
"&& reload_completed"
[(set (match_dup 3) (match_dup 1))
@@ -14626,6 +14639,34 @@
[(set_attr "type" "fp")
(set_attr "length" "8")])
+(define_insn_and_split "pack<mode>_soft"
+ [(set (match_operand:FMOVE128 0 "register_operand" "=&r")
+ (unspec:FMOVE128
+ [(match_operand:<FP128_64> 1 "register_operand" "r")
+ (match_operand:<FP128_64> 2 "register_operand" "r")]
+ UNSPEC_PACK_128BIT))]
+ "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (match_dup 2))]
+{
+ unsigned dest_hi = REGNO (operands[0]);
+ unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2);
+
+ gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
+ gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
+ operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
+}
+ [(set_attr "type" "integer")
+ (set (attr "length")
+ (if_then_else
+ (match_test "TARGET_POWERPC64")
+ (const_string "8")
+ (const_string "16")))])
+
(define_insn "unpack<mode>"
[(set (match_operand:DI 0 "register_operand" "=wa,wa")
(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")