diff mbox

[MIPS,committed] Fix extraction from odd-numbered MSA registers

Message ID 6D39441BF12EF246A7ABCE6654B0235380BE17BF@HHMAIL01.hh.imgtec.org
State New
Headers show

Commit Message

Matthew Fortune March 31, 2017, 9:25 a.m. UTC
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 mbox

Patch

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>")])