Moin guys,

this little patch improves 16*8 multiplication to some degree.

The FSF did'n yet send the assignment papers, but maybe the stuff is still useful all the same.

cheers

Georg-Johann
Index: avr.md
===================================================================
--- avr.md	(Revision 147721)
+++ avr.md	(Arbeitskopie)
@@ -980,18 +980,31 @@
 (define_expand "mulhi3"
   [(set (match_operand:HI 0 "register_operand" "")
 	(mult:HI (match_operand:HI 1 "register_operand" "")
-		 (match_operand:HI 2 "register_operand" "")))]
+		 (match_operand:HI 2 "nonmemory_operand" "")))]
   ""
   "
 {
   if (!AVR_HAVE_MUL)
     {
+      if (!register_operand (operands[2], HImode))
+        operands[2] = copy_to_mode_reg (HImode, operands[2]);
       emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
       DONE;
     }
+  else if (immediate_operand (operands[2], HImode))
+    {
+      enum machine_mode mode = (satisfies_constraint_M (operands[2])) ? QImode : HImode;
+
+      operands[2] = force_reg (mode, operands[2]);
+      if (HImode == mode)
+        emit_insn (gen_mulhi3_enh (operands[0], operands[1], operands[2]));
+      else
+        emit_insn (gen_umulhi3_enh_zerox (operands[0], operands[2], operands[1]));
+      DONE;
+    }
 }")
 
-(define_insn "*mulhi3_enh"
+(define_insn "mulhi3_enh"
   [(set (match_operand:HI 0 "register_operand" "=&r")
 	(mult:HI (match_operand:HI 1 "register_operand" "r")
 		 (match_operand:HI 2 "register_operand" "r")))]
@@ -1006,6 +1019,19 @@
   [(set_attr "length" "7")
    (set_attr "cc" "clobber")])
 
+(define_insn "umulhi3_enh_zerox"
+  [(set (match_operand:HI 0 "register_operand" "=&r")
+	(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
+                                 (match_operand:HI 2 "register_operand" "r")))]
+  "AVR_HAVE_MUL"
+  "mul %A2,%1
+	movw %0,r0
+	mul %B2,%1
+	add %B0,r0
+	clr r1"
+  [(set_attr "length" "5")
+   (set_attr "cc" "clobber")])
+
 (define_expand "mulhi3_call"
   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
Index: avr.c
===================================================================
--- avr.c	(Revision 147721)
+++ avr.c	(Arbeitskopie)
@@ -45,6 +45,7 @@
 #include "target-def.h"
 #include "params.h"
 #include "df.h"
+#include "tm-constrs.h"
 
 /* Maximal allowed offset for an address in the LD command */
 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
@@ -5055,6 +5056,14 @@ avr_operand_rtx_cost (rtx x, enum machin
     case CONST_DOUBLE:
       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
 
+    case ZERO_EXTEND:
+      if (HImode == mode
+          && MULT == outer)
+        {
+          return 0;
+        }
+      break;
+
     default:
       break;
     }
@@ -5203,7 +5212,7 @@ avr_rtx_costs (rtx x, int code, int oute
 	{
 	case QImode:
 	  if (AVR_HAVE_MUL)
-	    *total = COSTS_N_INSNS (!speed ? 3 : 4);
+            *total = COSTS_N_INSNS (!speed ? 3 : 4);
 	  else if (!speed)
 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
 	  else
@@ -5212,7 +5221,18 @@ avr_rtx_costs (rtx x, int code, int oute
 
 	case HImode:
 	  if (AVR_HAVE_MUL)
-	    *total = COSTS_N_INSNS (!speed ? 7 : 10);
+            {
+              if (ZERO_EXTEND == GET_CODE (XEXP (x, 0))
+                  && ZERO_EXTEND == GET_CODE (XEXP (x, 1)))
+                *total = COSTS_N_INSNS (!speed ? 3 : 4);
+              else if (satisfies_constraint_M (XEXP (x, 0))
+                       || satisfies_constraint_M (XEXP (x, 1))
+                       || ZERO_EXTEND == GET_CODE (XEXP (x, 0))
+                       || ZERO_EXTEND == GET_CODE (XEXP (x, 1)))
+                *total = COSTS_N_INSNS (!speed ? 5 : 6);
+              else
+                *total = COSTS_N_INSNS (!speed ? 7 : 10);
+            }
 	  else if (!speed)
 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
 	  else
@@ -5313,8 +5333,10 @@ avr_rtx_costs (rtx x, int code, int oute
 	      case 9:
 		*total = COSTS_N_INSNS (3);
 		break;
-	      case 2:
 	      case 3:
+		*total = COSTS_N_INSNS (!speed ? 4 : 6);
+		break;
+	      case 2:
 	      case 10:
 	      case 15:
 		*total = COSTS_N_INSNS (4);
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to