i86: add 32-bit integer support; add zero-extend patterns
authorDaniel Verkamp <daniel.verkamp@gmail.com>
Thu, 2 Aug 2007 22:50:04 +0000 (18:50 -0400)
committerDaniel Verkamp <daniel.verkamp@gmail.com>
Thu, 2 Aug 2007 22:50:04 +0000 (18:50 -0400)
gcc/config/i86/i86.c
gcc/config/i86/i86.h
gcc/config/i86/i86.md

index 0ba82a4..92e72a4 100644 (file)
@@ -267,7 +267,7 @@ i86_const_ok_for_letter_p(int v, int c)
   {
   case 'I':
     /* The constant that we can shift by: shl ax,1 */
-    return v == 1;
+    return v >= 0 && v <= 31;
   case 'J':
     /* I/O ports and byte registers */
     return v >= 0 && v <= 255;
index 17cb98a..a234b4d 100644 (file)
@@ -201,7 +201,7 @@ extern enum reg_class regclass_map[];       /* smallest class containing REGNO */
 
 #define CASE_VECTOR_MODE       HImode
 /*#define EASY_DIV_EXPR                TRUNC_DIV_EXPR*/
-#define MOVE_MAX               2
+#define MOVE_MAX               4
 #define Pmode                  HImode
 #define FUNCTION_MODE          QImode
 #define        NO_IMPLICIT_EXTERN_C    1
index c7a3e10..3124200 100644 (file)
    mov word ptr %0,%1"
   )
 
+(define_expand "movsi"
+  [(set (match_operand:SI 0 "general_operand" "")
+       (match_operand:SI 1 "general_operand" ""))]
+  ""
+  "
+{
+  /* Don't generate memory->memory moves, go through a register */
+  if ((reload_in_progress | reload_completed) == 0
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (operands[1]) == MEM)
+    {
+      operands[1] = force_reg (SImode, operands[1]);
+    }
+}")
+
+(define_insn ""
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,m")
+       (match_operand:SI 1 "general_operand" " g,r,i"))]
+  "(GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
+  "@
+   mov %e0,%1
+   mov %0,%e1
+   mov dword ptr %0,%1"
+  )
+
 (define_insn "addqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,=rm")
        (plus:QI (match_operand:QI 1 "general_operand" "0,0")
 }
   )
 
+(define_insn "addsi3"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,=rm")
+       (plus:SI (match_operand:SI 1 "general_operand" "0,0")
+                (match_operand:SI 2 "general_operand" "rm,ri")))]
+  ""
+{
+  /* Use shorter opcodes when possible */
+  if (operands[2] == const1_rtx)
+    if (MEM_P (operands[0]))
+      return "inc      dword ptr %0";
+    else
+      return "inc      %e0";
+  else if (operands[2] == constm1_rtx)
+    if (MEM_P (operands[0]))
+      return "dec      dword ptr %0";
+    else
+      return "dec      %e0";
+  else
+    if (MEM_P (operands[0]))
+      return "add      dword ptr %0, %e2";
+    else
+      return "add      %e0,%e2";
+}
+  )
+
 (define_insn "subhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,=rm")
        (minus:HI (match_operand:HI 1 "general_operand" "0,0")
    imul        word ptr %2"
   )
 
+(define_insn "mulsi3"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=a,a,a")
+       (mult:SI (match_operand:SI 1 "general_operand" "a,a,a")
+                (match_operand:SI 2 "general_operand" "r,i,m")))
+   (clobber (match_scratch:SI 3 "=&d,d,d"))]
+  ""
+  "@ 
+   imul        %e2
+   imul %2
+   imul        dword ptr %2"
+  )
+
 (define_insn "divhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,a")
        (div:HI (match_operand:HI 1 "general_operand" "a,a")
   "cmp %0,%1"
   )
 
-(define_insn "extendqihi2"
+;;
+;; sign extension
+;;
+
+
+(define_expand "extendqihi2"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
+       (sign_extend:HI
+         (match_operand:QI 1 "general_operand" "")))]
+  ""
+  "
+{
+  /* Don't generate memory->memory moves, go through a register */
+  if ((reload_in_progress | reload_completed) == 0
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (operands[1]) == MEM)
+    {
+      operands[1] = force_reg (QImode, operands[1]);
+    }
+}
+  "
+  )
+
+(define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=a")
        (sign_extend:HI
          (match_operand:QI 1 "register_operand" "0")))]
   "cbw"
   )
 
+(define_insn ""
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m")
+    (sign_extend:HI
+      (match_operand:QI 1 "general_operand" "r,m,r")))]
+  ""
+  "@
+   movsx       %0, %L1
+   movsx       %0, byte ptr %1
+   movsx       word ptr %0, %L1"
+  )
+
+(define_expand "extendhisi2"
+  [(set (match_operand:SI 0 "general_operand" "")
+    (sign_extend:SI
+      (match_operand:HI 1 "general_operand" "")))]
+  ""
+  "
+{
+  /* Don't generate memory->memory moves, go through a register */
+  if ((reload_in_progress | reload_completed) == 0
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (operands[1]) == MEM)
+    {
+      operands[1] = force_reg (HImode, operands[1]);
+    }
+}
+  "
+  )
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=a")
+    (sign_extend:SI
+      (match_operand:HI 1 "register_operand" "0")))]
+  ""
+  "cwd"
+  )
+
+(define_insn ""
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+    (sign_extend:SI
+      (match_operand:HI 1 "general_operand" "r,m,r")))]
+  ""
+  "@
+   movsx       %e0, %1
+   movsx       %e0, word ptr %1
+   movsx       dword ptr %0, %1"
+  )
+
+
+
+;;
+;; zero extension
+;;
+
+
+(define_expand "zero_extendqihi2"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
+       (zero_extend:HI
+         (match_operand:QI 1 "general_operand" "")))]
+  ""
+  "
+{
+  /* Don't generate memory->memory moves, go through a register */
+  if ((reload_in_progress | reload_completed) == 0
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (operands[1]) == MEM)
+    {
+      operands[1] = force_reg (QImode, operands[1]);
+    }
+}
+  "
+  )
+
+(define_insn ""
+  [(set (match_operand:HI 0 "register_operand" "=abcd")
+       (zero_extend:HI
+         (match_operand:QI 1 "register_operand" "0")))]
+  ""
+  "xor %H0, %H0"
+  )
+
+(define_insn ""
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m")
+    (zero_extend:HI
+      (match_operand:QI 1 "general_operand" "r,m,r")))]
+  ""
+  "@
+   movzx       %0, %L1
+   movzx       %0, byte ptr %1
+   movzx       word ptr %0, %L1"
+  )
+
+(define_expand "zero_extendhisi2"
+  [(set (match_operand:SI 0 "general_operand" "")
+    (zero_extend:SI
+      (match_operand:HI 1 "general_operand" "")))]
+  ""
+  "
+{
+  /* Don't generate memory->memory moves, go through a register */
+  if ((reload_in_progress | reload_completed) == 0
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (operands[1]) == MEM)
+    {
+      operands[1] = force_reg (HImode, operands[1]);
+    }
+}
+  "
+  )
+
+(define_insn ""
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+    (zero_extend:SI
+      (match_operand:HI 1 "general_operand" "r,m,r")))]
+  ""
+  "@
+   movzx       %e0, %1
+   movzx       %e0, word ptr %1
+   movzx       dword ptr %0, %1"
+  )
+
+
+;;
+;; branches
+;;
+
 (define_insn "beq"
   [(set (pc)
         (if_then_else (eq (cc0)