This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[powerpc] fix movdf_hardfloat32 pattern


This patch fixes a bug I found in a 3.4 toolchain. The bug is still present in mainline, but the testcase I have doesn't tickle the problematic sequence.

This testcase has a massive structure, such that the byte offset to the double member is 0x297ff8 bytes. We construct a sequence that ends with,

(insn:TI 13 11 32 0 (set (mem/s:DF (plus:SI (reg/f:SI 11 11 [121])
                (const_int 32760 [0x7ff8])) [7 <variable>.member+0 S8 A64])
        (reg:DF 9 9 [122])) 311 {*movdf_hardfloat32}

Because of rs6000_mode_dependent_address we do not consider the 0x7ff8' addend to be an offsettable address. Hence the the output pattern of case 2: uses the second alternative of stx/cal/stx/cal sequence. but here, we've not got an indexable address so the assembler barfs. the load patterns have the same problem.

The obvious fix is to use %X output format to append the 'x' as necessary.

I'm not sure if it's worth committing the testcase, given it no longer generates this code.

Tested on powerpc-wrs-vxworks, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2006-12-15  Nathan Sidwell  <nathan@codesourcery.com>

	* config/rs6000/rs6000.md (*movdf_hardfloat32): Use %X format to
	determine if memory operand is an indexed address or not.

Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 119362)
+++ config/rs6000/rs6000.md	(working copy)
@@ -8359,15 +8359,15 @@
 				 operands[1], 0))
 	    {
 	      output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
-	      output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+	      output_asm_insn (\"{l|lwz}%X1 %L0,%1\", operands);
 	      output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
-	      return \"{lx|lwzx} %0,%1\";
+	      return \"{l|lwz}%X1 %0,%1\";
 	    }
 	  else
 	    {
-	      output_asm_insn (\"{lx|lwzx} %0,%1\", operands);
+	      output_asm_insn (\"{l|lwz}%X1 %0,%1\", operands);
 	      output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
-	      output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+	      output_asm_insn (\"{l|lwz}%X1 %L0,%1\", operands);
 	      output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
 	      return \"\";
 	    }
@@ -8384,9 +8384,9 @@
 	  rtx addreg;
 
 	  addreg = find_addr_reg (XEXP (operands[0], 0));
-	  output_asm_insn (\"{stx|stwx} %1,%0\", operands);
+	  output_asm_insn (\"{st|stw}%X0 %1,%0\", operands);
 	  output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
-	  output_asm_insn (\"{stx|stwx} %L1,%0\", operands);
+	  output_asm_insn (\"{st|stw}%X0 %L1,%0\", operands);
 	  output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
 	  return \"\";
 	}
struct Bar
{
  int pad[679933];
  double member;
};

extern struct Bar *ptr;

void Foo (void)
{
  ptr->member = 5.0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]