Added "padd*" support for MMX. Added MMX move stuff to X86InstrInfo so that
authorBill Wendling <isanbard@gmail.com>
Thu, 8 Mar 2007 22:09:11 +0000 (22:09 +0000)
committerBill Wendling <isanbard@gmail.com>
Thu, 8 Mar 2007 22:09:11 +0000 (22:09 +0000)
moves, loads, etc. are recognized.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35031 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Intrinsics.td
include/llvm/IntrinsicsX86.td
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86InstrInfo.cpp
lib/Target/X86/X86InstrMMX.td
lib/Target/X86/X86RegisterInfo.cpp

index 1e18a4ce6a07e88ba4f4e2f83a1f49f375dc9c6f..0f3dfb6e08e8dc2a287372eb938ca4283b22e988 100644 (file)
@@ -98,6 +98,10 @@ def llvm_v4i32_ty      : LLVMVectorType<v4i32, 4, llvm_i32_ty>;   //  4 x i32
 def llvm_v4f32_ty      : LLVMVectorType<v4f32, 4, llvm_float_ty>; //  4 x float
 def llvm_v2f64_ty      : LLVMVectorType<v2f64, 2, llvm_double_ty>;//  2 x double
 
+// MMX Vector Types
+def llvm_v8i8_ty       : LLVMVectorType<v8i8,  8, llvm_i8_ty>;    //  8 x i8
+def llvm_v4i16_ty      : LLVMVectorType<v4i16, 4, llvm_i16_ty>;   //  4 x i16
+
 def llvm_vararg_ty     : LLVMType<isVoid, "...">; // vararg
 
 //===----------------------------------------------------------------------===//
index d512786d6fae3948895d95fb99c6f8bd069c0f1e..76db55ab294aac094103cd991a57a490b2a365ac 100644 (file)
@@ -544,3 +544,20 @@ let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
   def int_x86_mmx_emms : GCCBuiltin<"__builtin_ia32_emms">,
               Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
 }
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_mmx_padds_b : GCCBuiltin<"__builtin_ia32_paddsb">,
+              Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+                         llvm_v8i8_ty], [IntrNoMem]>;
+  def int_x86_mmx_padds_w : GCCBuiltin<"__builtin_ia32_paddsw">,
+              Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+                         llvm_v4i16_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb">,
+              Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+                         llvm_v8i8_ty], [IntrNoMem]>;
+  def int_x86_mmx_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw">,
+              Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+                         llvm_v4i16_ty], [IntrNoMem]>;
+}
index 1d2c623216df44ebd3789257e9d98e3b2f0cdebe..2ab5e086197114fd3ee92e975846cedebc7b204b 100644 (file)
@@ -326,15 +326,20 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     addRegisterClass(MVT::v2i32, X86::VR64RegisterClass);
 
     // FIXME: add MMX packed arithmetics
-    setOperationAction(ISD::LOAD,             MVT::v8i8,  Promote);
-    AddPromotedToType (ISD::LOAD,             MVT::v8i8,  MVT::v2i32);
-    setOperationAction(ISD::LOAD,             MVT::v4i16, Promote);
-    AddPromotedToType (ISD::LOAD,             MVT::v4i16, MVT::v2i32);
-    setOperationAction(ISD::LOAD,             MVT::v2i32, Legal);
-
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v8i8,  Expand);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v4i16, Expand);
-    setOperationAction(ISD::BUILD_VECTOR,     MVT::v2i32, Expand);
+
+    setOperationAction(ISD::ADD,                MVT::v8i8,  Legal);
+    setOperationAction(ISD::ADD,                MVT::v4i16, Legal);
+    setOperationAction(ISD::ADD,                MVT::v2i32, Legal);
+
+    setOperationAction(ISD::LOAD,               MVT::v8i8,  Promote);
+    AddPromotedToType (ISD::LOAD,               MVT::v8i8,  MVT::v2i32);
+    setOperationAction(ISD::LOAD,               MVT::v4i16, Promote);
+    AddPromotedToType (ISD::LOAD,               MVT::v4i16, MVT::v2i32);
+    setOperationAction(ISD::LOAD,               MVT::v2i32, Legal);
+
+    setOperationAction(ISD::BUILD_VECTOR,       MVT::v8i8,  Expand);
+    setOperationAction(ISD::BUILD_VECTOR,       MVT::v4i16, Expand);
+    setOperationAction(ISD::BUILD_VECTOR,       MVT::v2i32, Expand);
   }
 
   if (Subtarget->hasSSE1()) {
index 87f04b80ba36a73646fcf08193f0ade1666d3701..24e434cca15be967595046661efe56eebf20ef70 100644 (file)
@@ -37,7 +37,8 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
       oc == X86::FsMOVAPSrr || oc == X86::FsMOVAPDrr ||
       oc == X86::MOVAPSrr || oc == X86::MOVAPDrr ||
       oc == X86::MOVSS2PSrr || oc == X86::MOVSD2PDrr ||
-      oc == X86::MOVPS2SSrr || oc == X86::MOVPD2SDrr) {
+      oc == X86::MOVPS2SSrr || oc == X86::MOVPD2SDrr ||
+      oc == X86::MOVD64rr || oc == X86::MOVQ64rr) {
       assert(MI.getNumOperands() == 2 &&
              MI.getOperand(0).isRegister() &&
              MI.getOperand(1).isRegister() &&
@@ -64,6 +65,8 @@ unsigned X86InstrInfo::isLoadFromStackSlot(MachineInstr *MI,
   case X86::MOVSDrm:
   case X86::MOVAPSrm:
   case X86::MOVAPDrm:
+  case X86::MOVD64rm:
+  case X86::MOVQ64rm:
     if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() &&
         MI->getOperand(3).isRegister() && MI->getOperand(4).isImmediate() &&
         MI->getOperand(2).getImmedValue() == 1 &&
@@ -92,6 +95,8 @@ unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI,
   case X86::MOVSDmr:
   case X86::MOVAPSmr:
   case X86::MOVAPDmr:
+  case X86::MOVD64mr:
+  case X86::MOVQ64mr:
     if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() &&
         MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() &&
         MI->getOperand(1).getImmedValue() == 1 &&
index b301b405b6bd5ae4a6ac1f910492614b241421db..5096c203bacea9882339e59c9dd118aa104b51f3 100644 (file)
@@ -44,6 +44,42 @@ def : Pat<(v2i32 (undef)), (IMPLICIT_DEF_VR64)>;
 
 def loadv2i32 : PatFrag<(ops node:$ptr), (v2i32 (load node:$ptr))>;
 
+//===----------------------------------------------------------------------===//
+// MMX Multiclasses
+//===----------------------------------------------------------------------===//
+
+let isTwoAddress = 1 in {
+  // MMXI_binop_rm - Simple MMX binary operator.
+  multiclass MMXI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
+                           ValueType OpVT, bit Commutable = 0> {
+    def rr : MMXI<opc, MRMSrcReg, (ops VR64:$dst, VR64:$src1, VR64:$src2),
+                  !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
+                  [(set VR64:$dst, (OpVT (OpNode VR64:$src1, VR64:$src2)))]> {
+      let isCommutable = Commutable;
+    }
+    def rm : MMXI<opc, MRMSrcMem, (ops VR64:$dst, VR64:$src1, i64mem:$src2),
+                  !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
+                  [(set VR64:$dst, (OpVT (OpNode VR64:$src1,
+                                         (bitconvert
+                                          (loadv2i32 addr:$src2)))))]>;
+  }
+}
+
+let isTwoAddress = 1 in {
+  multiclass MMXI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
+                               bit Commutable = 0> {
+    def rr : MMXI<opc, MRMSrcReg, (ops VR64:$dst, VR64:$src1, VR64:$src2),
+                 !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
+                 [(set VR64:$dst, (IntId VR64:$src1, VR64:$src2))]> {
+      let isCommutable = Commutable;
+    }
+    def rm : MMXI<opc, MRMSrcMem, (ops VR64:$dst, VR64:$src1, i64mem:$src2),
+                 !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
+                 [(set VR64:$dst, (IntId VR64:$src1,
+                                   (bitconvert (loadv2i32 addr:$src2))))]>;
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // MMX EMMS Instruction
 //===----------------------------------------------------------------------===//
@@ -54,6 +90,17 @@ def EMMS : MMXI<0x77, RawFrm, (ops), "emms", [(int_x86_mmx_emms)]>;
 // MMX Scalar Instructions
 //===----------------------------------------------------------------------===//
 
+// Arithmetic Instructions
+defm MMX_PADDB : MMXI_binop_rm<0xFC, "paddb", add, v8i8, 1>;
+defm MMX_PADDW : MMXI_binop_rm<0xFD, "paddw", add, v4i16, 1>;
+defm MMX_PADDD : MMXI_binop_rm<0xFE, "paddd", add, v2i32, 1>;
+
+defm MMX_PADDSB  : MMXI_binop_rm_int<0xEC, "paddsb" , int_x86_mmx_padds_b, 1>;
+defm MMX_PADDSW  : MMXI_binop_rm_int<0xED, "paddsw" , int_x86_mmx_padds_w, 1>;
+
+defm MMX_PADDUSB : MMXI_binop_rm_int<0xDC, "paddusb", int_x86_mmx_paddus_b, 1>;
+defm MMX_PADDUSW : MMXI_binop_rm_int<0xDD, "paddusw", int_x86_mmx_paddus_w, 1>;
+
 // Move Instructions
 def MOVD64rr : MMXI<0x6E, MRMSrcReg, (ops VR64:$dst, GR32:$src),
                     "movd {$src, $dst|$dst, $src}", []>;
index bf7c87219835507287f3aa9c4caa7ba41d7d2c38..749bb1f3edcd76e3cf55274d0434f2fa3bb9c138 100644 (file)
@@ -89,6 +89,8 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
     Opc = X86::MOVSDmr;
   } else if (RC == &X86::VR128RegClass) {
     Opc = X86::MOVAPSmr;
+  } else if (RC == &X86::VR64RegClass) {
+    Opc = X86::MOVQ64mr;
   } else {
     assert(0 && "Unknown regclass");
     abort();
@@ -122,6 +124,8 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
     Opc = X86::MOVSDrm;
   } else if (RC == &X86::VR128RegClass) {
     Opc = X86::MOVAPSrm;
+  } else if (RC == &X86::VR64RegClass) {
+    Opc = X86::MOVQ64rm;
   } else {
     assert(0 && "Unknown regclass");
     abort();
@@ -154,6 +158,8 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
     Opc = X86::FsMOVAPDrr;
   } else if (RC == &X86::VR128RegClass) {
     Opc = X86::MOVAPSrr;
+  } else if (RC == &X86::VR64RegClass) {
+    Opc = X86::MOVQ64rr;
   } else {
     assert(0 && "Unknown regclass");
     abort();