avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Improvon 8*16 Multiplication


From: Georg-Johann Lay
Subject: [avr-gcc-list] Improvon 8*16 Multiplication
Date: Thu, 28 May 2009 08:35:13 +0200
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

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);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]