From 2f88dcdfb3a9c9592da93dcf3f0e0a9333932187 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 8 Mar 2007 22:09:11 +0000 Subject: [PATCH] Added "padd*" support for MMX. Added MMX move stuff to X86InstrInfo so that 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 | 4 +++ include/llvm/IntrinsicsX86.td | 17 +++++++++++ lib/Target/X86/X86ISelLowering.cpp | 21 ++++++++----- lib/Target/X86/X86InstrInfo.cpp | 7 ++++- lib/Target/X86/X86InstrMMX.td | 47 ++++++++++++++++++++++++++++++ lib/Target/X86/X86RegisterInfo.cpp | 6 ++++ 6 files changed, 93 insertions(+), 9 deletions(-) diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 1e18a4ce6a0..0f3dfb6e08e 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -98,6 +98,10 @@ def llvm_v4i32_ty : LLVMVectorType; // 4 x i32 def llvm_v4f32_ty : LLVMVectorType; // 4 x float def llvm_v2f64_ty : LLVMVectorType;// 2 x double +// MMX Vector Types +def llvm_v8i8_ty : LLVMVectorType; // 8 x i8 +def llvm_v4i16_ty : LLVMVectorType; // 4 x i16 + def llvm_vararg_ty : LLVMType; // vararg //===----------------------------------------------------------------------===// diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index d512786d6fa..76db55ab294 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -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]>; +} diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 1d2c623216d..2ab5e086197 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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()) { diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 87f04b80ba3..24e434cca15 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -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 && diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td index b301b405b6b..5096c203bac 100644 --- a/lib/Target/X86/X86InstrMMX.td +++ b/lib/Target/X86/X86InstrMMX.td @@ -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 opc, string OpcodeStr, SDNode OpNode, + ValueType OpVT, bit Commutable = 0> { + def rr : MMXI { + let isCommutable = Commutable; + } + def rm : MMXI; + } +} + +let isTwoAddress = 1 in { + multiclass MMXI_binop_rm_int opc, string OpcodeStr, Intrinsic IntId, + bit Commutable = 0> { + def rr : MMXI { + let isCommutable = Commutable; + } + def rm : MMXI; + } +} + //===----------------------------------------------------------------------===// // 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}", []>; diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index bf7c8721983..749bb1f3edc 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -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();