Patchwork [4.8.[01] ] PowerPC di->ti widening multiplication

login
register
mail settings
Submitter Richard Henderson
Date Jan. 30, 2013, 6:17 p.m.
Message ID <510963A8.6050900@redhat.com>
Download mbox | patch
Permalink /patch/216999/
State New
Headers show

Comments

Richard Henderson - Jan. 30, 2013, 6:17 p.m.
For gcc 4.9, I intend to ensure that optabs.c can make automatic use of 
[us]mul<mode>_highpart.  There are plenty of targets that only implement 
_highpart but not the widening pattern.  But that's not something that 
would be appropriate at this stage in the 4.8 cycle.

Whether this patch is appropriate for 4.8.0 is someone else's call, but 
it's probably safe to queue it for 4.8.1.


r~


	* config/rs6000/rs6000.md (smulditi3): New.
	(umulditi3): New.

Patch

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index a4af648..b3db681 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -6326,6 +6326,34 @@ 
   "mulhdu %0,%1,%2"
   [(set_attr "type" "lmul")])
 
+(define_expand "mulditi3"
+  [(set (match_operand:TI 0 "gpc_reg_operand")
+	(mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
+		 (sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))]
+  "TARGET_POWERPC64"
+{
+  rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
+  emit_insn (gen_muldi3 (l, operands[1], operands[2]));
+  emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2]));
+  emit_move_insn (gen_lowpart (DImode, operands[0]), l);
+  emit_move_insn (gen_highpart (DImode, operands[0]), h);
+  DONE;
+})
+
+(define_expand "umulditi3"
+  [(set (match_operand:TI 0 "gpc_reg_operand")
+	(mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
+		 (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))]
+  "TARGET_POWERPC64"
+{
+  rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
+  emit_insn (gen_muldi3 (l, operands[1], operands[2]));
+  emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2]));
+  emit_move_insn (gen_lowpart (DImode, operands[0]), l);
+  emit_move_insn (gen_highpart (DImode, operands[0]), h);
+  DONE;
+})
+
 (define_insn "rotldi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")