Another MSA related fix; this time relating to using -mno-odd-spreg.
This fixes a build-failure with gcc.c-torture/execute/20050604-1.c
when using -mabi=32 -mmsa -mno-odd-spreg.

The fix is to copy the whole vector from the odd-numbered source
register to the even numbered single-precision destination register
and then re-interpret the vector as single precision in the
destination. The mov.s is always eliminated as it is a trivial
no-op; this is permitted by the architecture as the single-precision
and double-precision registers overlay with the 0th element of the
MSA registers. Also, trivial no-ops were already being generated
and eliminated prior to this change when source and destination
register numbers happened to be the same.

No additional test failures introduced when running the testsuite
with -mmsa. The fix is covered by a pre-existing test so no new
testcase added.

gcc/
        * config/mips/mips-msa.md (msa_vec_extract_<msafmt_f>): Update
        extraction from odd-numbered MSA register

Committed.

Thanks,
Matthew


diff --git a/gcc/config/mips/mips-msa.md b/gcc/config/mips/mips-msa.md
index accb8de..c80be47 100644
--- a/gcc/config/mips/mips-msa.md
+++ b/gcc/config/mips/mips-msa.md
@@ -366,7 +366,20 @@ (define_insn_and_split "msa_vec_extract_<msafmt_f>"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (match_dup 1))]
-  "operands[1] = gen_rtx_REG (<UNITMODE>mode, REGNO (operands[1]));"
+{
+  /* An MSA register cannot be reinterpreted as a single precision
+     register when using -mno-odd-spreg and the MSA register is
+     an odd number.  */
+  if (<UNITMODE>mode == SFmode && !TARGET_ODD_SPREG
+      && (REGNO (operands[1]) & 1))
+    {
+      emit_move_insn (gen_rtx_REG (<MODE>mode, REGNO (operands[0])),
+                     operands[1]);
+      operands[1] = operands[0];
+    }
+  else
+    operands[1] = gen_rtx_REG (<UNITMODE>mode, REGNO (operands[1]));
+}
   [(set_attr "move_type" "fmove")
    (set_attr "mode" "<UNITMODE>")])

Reply via email to