[llvm-commits] [llvm-gcc-4.2] r115245 - in /llvm-gcc-4.2/trunk/gcc: config/i386/i386.c config/i386/llvm-i386-target.h config/i386/llvm-i386.cpp llvm-abi.h llvm-convert.cpp llvm-types.cpp
Dale Johannesen
dalej at apple.com
Thu Sep 30 16:59:33 PDT 2010
Author: johannes
Date: Thu Sep 30 18:59:33 2010
New Revision: 115245
URL: http://llvm.org/viewvc/llvm-project?rev=115245&view=rev
Log:
llvm-gcc part of MMX rewrite (goes with 115243).
Modified:
llvm-gcc-4.2/trunk/gcc/config/i386/i386.c
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
llvm-gcc-4.2/trunk/gcc/llvm-abi.h
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.c?rev=115245&r1=115244&r2=115245&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/i386.c (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Thu Sep 30 18:59:33 2010
@@ -17046,7 +17046,8 @@
/* Merom New Instructions. */
def_builtin (MASK_SSSE3, "__builtin_ia32_palignr128",
v2di_ftype_v2di_v2di_int, IX86_BUILTIN_PALIGNR128);
- def_builtin (MASK_SSSE3, "__builtin_ia32_palignr", v1di_ftype_v1di_v1di_int,
+ /* LLVM LOCAL - This is an MMX builtin */
+ def_builtin (MASK_MMX, "__builtin_ia32_palignr", v1di_ftype_v1di_v1di_int,
IX86_BUILTIN_PALIGNR);
/* APPLE LOCAL end 4656532 */
@@ -18170,7 +18171,6 @@
case IX86_BUILTIN_MOVNTQ:
/* APPLE LOCAL 4656532 use V1DImode for _m64 */
return ix86_expand_store_builtin (CODE_FOR_sse_movntv1di, arglist);
-
case IX86_BUILTIN_LDMXCSR:
op0 = expand_normal (TREE_VALUE (arglist));
target = assign_386_stack_local (SImode, SLOT_VIRTUAL);
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h?rev=115245&r1=115244&r2=115245&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386-target.h Thu Sep 30 18:59:33 2010
@@ -24,6 +24,25 @@
#ifndef LLVM_I386_TARGET_H
#define LLVM_I386_TARGET_H
+/* Detect MMX register variables. We use this to generate an x86mmx LLVM type
+ for these rather than <2 x i32>. This is an utter hack, but
+ there is no counterpart to x86mmx in the gcc type system, and trying to
+ add it is a can of worms. */
+#define LLVM_IS_DECL_MMX_REGISTER(decl) \
+ (TARGET_MMX && \
+ TREE_CODE(decl) == VAR_DECL && DECL_REGISTER(decl) && DECL_NAME(decl) && \
+ strncmp("%mm", IDENTIFIER_POINTER(DECL_NAME(decl)), 3)==0)
+
+/* Similarly, parameters of MMX vector type <2 x i32>, <4 x i16>, <2 x i32>
+ must be changed to m86mmx at the last minute. <2 x f32> is unsupported;
+ it is filtered out here to avoid crashes in the gcc testsuite. */
+#define LLVM_ADJUST_MMX_PARAMETER_TYPE(LLVMTy) \
+ ((TARGET_MMX && \
+ LLVMTy->isVectorTy() && LLVMTy->getPrimitiveSizeInBits()==64 && \
+ dyn_cast<VectorType>(LLVMTy)->getElementType()->isIntegerTy() && \
+ LLVMTy->getScalarSizeInBits() !=64) ? \
+ Type::getX86_MMXTy(Context) : LLVMTy)
+
/* LLVM specific stuff for supporting calling convention output */
#define TARGET_ADJUST_LLVM_CC(CC, type) \
{ \
Modified: llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp?rev=115245&r1=115244&r2=115245&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/config/i386/llvm-i386.cpp Thu Sep 30 18:59:33 2010
@@ -40,6 +40,53 @@
static LLVMContext &Context = getGlobalContext();
+/* ConvertToX86_MMXTy - Convert a value from an "old" MMX type to the new x86mmx
+ * type.
+ */
+static Value *ConvertToX86_MMXTy(Value *Val, LLVMBuilder &Builder) {
+ static const Type *MMXTy = Type::getX86_MMXTy(Context);
+ if (Val->getType() == MMXTy) return Val;
+ return Builder.CreateBitCast(Val, MMXTy, "mmx_var");
+}
+
+namespace Encode {
+ enum {
+ Return = 0x01,
+ Arg0 = 0x02,
+ Arg1 = 0x04
+ };
+}
+
+/* CreateMMXIntrinsicCall - Create an intrinsic call to an MMX intrinsic.
+ */
+static void CreateMMXIntrinsicCall(Intrinsic::ID IntID, Value *&Result,
+ std::vector<Value*> &Ops,
+ unsigned EncodePattern,
+ LLVMBuilder &Builder) {
+ unsigned NumOps = Ops.size();
+ static const Type *MMXTy = Type::getX86_MMXTy(Context);
+ Function *Func = Intrinsic::getDeclaration(TheModule, IntID);
+
+ Value *Arg0 = 0, *Arg1 = 0;
+ if (NumOps >= 1)
+ Arg0 = EncodePattern & Encode::Arg0 ?
+ ConvertToX86_MMXTy(Ops[0], Builder) : Ops[0];
+
+ if (NumOps >= 2)
+ Arg1 = EncodePattern & Encode::Arg1 ?
+ ConvertToX86_MMXTy(Ops[1], Builder) : Ops[1];
+
+ Value *CallOps[10] = { Arg0, Arg1 };
+
+ for (unsigned I = 2; I < NumOps && I < 10; ++I)
+ CallOps[I] = Ops[I];
+
+ Result = Builder.CreateCall(Func, CallOps, CallOps + NumOps);
+
+ if (EncodePattern & Encode::Return)
+ Result = Builder.CreateBitCast(Result, MMXTy);
+}
+
/* TargetIntrinsicLower - For builtins that we want to expand to normal LLVM
* code, emit the code now. If we can handle the code, this macro should emit
* the code, return true.
@@ -52,14 +99,406 @@
std::vector<Value*> &Ops) {
switch (FnCode) {
default: break;
- case IX86_BUILTIN_ADDPS:
- case IX86_BUILTIN_ADDPD:
- Result = Builder.CreateFAdd(Ops[0], Ops[1]);
- return true;
+
+ /* MMX Builtins */
case IX86_BUILTIN_PADDB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_padd_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
case IX86_BUILTIN_PADDW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_padd_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
case IX86_BUILTIN_PADDD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_padd_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
case IX86_BUILTIN_PADDQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_padd_q, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PADDSB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_padds_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PADDSW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_padds_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PADDUSB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_paddus_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PADDUSW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_paddus_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psub_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psub_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psub_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psub_q, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBSB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psubs_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBSW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psubs_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBUSB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psubus_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSUBUSW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psubus_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMULHW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmulh_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMULLW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmull_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMULHUW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmulhu_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMULUDQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmulu_dq, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMADDWD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmadd_wd, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PAND:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pand, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PANDN:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pandn, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_POR:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_por, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PXOR:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pxor, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PAVGB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pavg_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PAVGW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pavg_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMAXUB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmaxu_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMAXSW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmaxs_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMINUB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pminu_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMINSW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmins_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSADBW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psad_bw, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSLLW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psll_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSLLD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psll_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSLLQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psll_q, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRLW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrl_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRLD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrl_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRLQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrl_q, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRAW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psra_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRAD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psra_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSLLWI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pslli_w, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSLLDI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pslli_d, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSLLQI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pslli_q, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRLWI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrli_w, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRLDI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrli_d, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRLQI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrli_q, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRAWI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrai_w, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PSRADI:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_psrai_d, Result, Ops,
+ Encode::Return | Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PACKSSWB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_packsswb, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PACKSSDW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_packssdw, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PACKUSWB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_packuswb, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PUNPCKHBW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_punpckhbw, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PUNPCKHWD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_punpckhwd, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PUNPCKHDQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_punpckhdq, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PUNPCKLBW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_punpcklbw, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PUNPCKLWD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_punpcklwd, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PUNPCKLDQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_punpckldq, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+
+ case IX86_BUILTIN_PCMPEQB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pcmpeq_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PCMPEQW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pcmpeq_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PCMPEQD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pcmpeq_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PCMPGTB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pcmpgt_b, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PCMPGTW:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pcmpgt_w, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PCMPGTD:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pcmpgt_d, Result, Ops,
+ Encode::Return | Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+
+ /* FIXME: MMX extract, insert, and convert built-ins? */
+
+ case IX86_BUILTIN_MASKMOVQ:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_maskmovq, Result, Ops,
+ Encode::Arg0 | Encode::Arg1,
+ Builder);
+ return true;
+ case IX86_BUILTIN_PMOVMSKB:
+ CreateMMXIntrinsicCall(Intrinsic::x86_mmx_pmovmskb, Result, Ops,
+ Encode::Arg0,
+ Builder);
+ return true;
+ case IX86_BUILTIN_MOVNTQ: {
+ static const Type *MMXTy = Type::getX86_MMXTy(Context);
+ Function *Func = Intrinsic::getDeclaration(TheModule,
+ Intrinsic::x86_mmx_movnt_dq);
+ const PointerType *PTy = cast<PointerType>(Ops[0]->getType());
+ Value *Arg0 = 0;
+ if (PTy->getElementType() == MMXTy)
+ Arg0 = Ops[0];
+ else
+ Arg0 = Builder.CreateBitCast(Ops[0],
+ Type::getX86_MMXPtrTy(Context),
+ "mmx_ptr_var");
+
+ Value *Arg1 = ConvertToX86_MMXTy(Ops[1], Builder);
+ Value *CallOps[2] = { Arg0, Arg1 };
+ Result = Builder.CreateCall(Func, CallOps, CallOps + 2);
+ return true;
+ }
+ case IX86_BUILTIN_PALIGNR: {
+ static const Type *MMXTy = Type::getX86_MMXTy(Context);
+ Function *Func = Intrinsic::getDeclaration(TheModule,
+ Intrinsic::x86_mmx_palignr_b);
+ Value *Arg0 = ConvertToX86_MMXTy(Ops[0], Builder);
+ Value *Arg1 = ConvertToX86_MMXTy(Ops[1], Builder);
+ Value *Arg2 = Builder.CreateTrunc(Ops[2], Type::getInt8Ty(Context),
+ "i32_to_i8");
+
+ Value *CallOps[3] = { Arg0, Arg1, Arg2 };
+ Result = Builder.CreateCall(Func, CallOps, CallOps + 3);
+ Result = Builder.CreateBitCast(Result, MMXTy);
+ return true;
+ }
+ case IX86_BUILTIN_VEC_INIT_V8QI: {
+ // The operands to this vector init are helpfully turned into i32. Truncate
+ // them to i8, which is what's expected.
+ for (unsigned I = 0, E = Ops.size(); I != E; ++I)
+ Ops[I] = Builder.CreateTrunc(Ops[I], Type::getInt8Ty(Context),
+ "i32_to_i8");
+
+ Value *V = BuildVector(Ops);
+ Result = Builder.CreateBitCast(V, Type::getX86_MMXTy(Context));
+ return true;
+ }
+ case IX86_BUILTIN_VEC_INIT_V4HI: {
+ // The operands to this vector init are helpfully turned into i32. Truncate
+ // them to i16, which is what's expected.
+ for (unsigned I = 0, E = Ops.size(); I != E; ++I)
+ Ops[I] = Builder.CreateTrunc(Ops[I], Type::getInt16Ty(Context),
+ "i32_to_i16");
+
+ Value *V = BuildVector(Ops);
+ Result = Builder.CreateBitCast(V, Type::getX86_MMXTy(Context));
+ return true;
+ }
+ case IX86_BUILTIN_VEC_INIT_V2SI: {
+ Value *V = BuildVector(Ops);
+ Result = Builder.CreateBitCast(V, Type::getX86_MMXTy(Context));
+ return true;
+ }
+ case IX86_BUILTIN_VEC_EXT_V2SI:
+ Result = Builder.CreateBitCast(Ops[0],
+ VectorType::get(Type::getInt32Ty(Context), 2));
+ Result = Builder.CreateExtractElement(Result,
+ ConstantInt::get(Type::getInt32Ty(Context), 0));
+ return true;
+ case IX86_BUILTIN_ADDPS:
+ case IX86_BUILTIN_ADDPD:
+ Result = Builder.CreateFAdd(Ops[0], Ops[1]);
+ return true;
case IX86_BUILTIN_PADDB128:
case IX86_BUILTIN_PADDW128:
case IX86_BUILTIN_PADDD128:
@@ -70,10 +509,6 @@
case IX86_BUILTIN_SUBPD:
Result = Builder.CreateFSub(Ops[0], Ops[1]);
return true;
- case IX86_BUILTIN_PSUBB:
- case IX86_BUILTIN_PSUBW:
- case IX86_BUILTIN_PSUBD:
- case IX86_BUILTIN_PSUBQ:
case IX86_BUILTIN_PSUBB128:
case IX86_BUILTIN_PSUBW128:
case IX86_BUILTIN_PSUBD128:
@@ -84,7 +519,6 @@
case IX86_BUILTIN_MULPD:
Result = Builder.CreateFMul(Ops[0], Ops[1]);
return true;
- case IX86_BUILTIN_PMULLW:
case IX86_BUILTIN_PMULLW128:
case IX86_BUILTIN_PMULLD128:
Result = Builder.CreateMul(Ops[0], Ops[1]);
@@ -93,20 +527,16 @@
case IX86_BUILTIN_DIVPD:
Result = Builder.CreateFDiv(Ops[0], Ops[1]);
return true;
- case IX86_BUILTIN_PAND:
case IX86_BUILTIN_PAND128:
Result = Builder.CreateAnd(Ops[0], Ops[1]);
return true;
- case IX86_BUILTIN_PANDN:
case IX86_BUILTIN_PANDN128:
Ops[0] = Builder.CreateNot(Ops[0]);
Result = Builder.CreateAnd(Ops[0], Ops[1]);
return true;
- case IX86_BUILTIN_POR:
case IX86_BUILTIN_POR128:
Result = Builder.CreateOr(Ops[0], Ops[1]);
return true;
- case IX86_BUILTIN_PXOR:
case IX86_BUILTIN_PXOR128:
Result = Builder.CreateXor(Ops[0], Ops[1]);
return true;
@@ -205,26 +635,6 @@
}
return true;
- case IX86_BUILTIN_PUNPCKHBW:
- Result = BuildVectorShuffle(Ops[0], Ops[1], 4, 12, 5, 13,
- 6, 14, 7, 15);
- return true;
- case IX86_BUILTIN_PUNPCKHWD:
- Result = BuildVectorShuffle(Ops[0], Ops[1], 2, 6, 3, 7);
- return true;
- case IX86_BUILTIN_PUNPCKHDQ:
- Result = BuildVectorShuffle(Ops[0], Ops[1], 1, 3);
- return true;
- case IX86_BUILTIN_PUNPCKLBW:
- Result = BuildVectorShuffle(Ops[0], Ops[1], 0, 8, 1, 9,
- 2, 10, 3, 11);
- return true;
- case IX86_BUILTIN_PUNPCKLWD:
- Result = BuildVectorShuffle(Ops[0], Ops[1], 0, 4, 1, 5);
- return true;
- case IX86_BUILTIN_PUNPCKLDQ:
- Result = BuildVectorShuffle(Ops[0], Ops[1], 0, 2);
- return true;
case IX86_BUILTIN_PUNPCKHBW128:
Result = BuildVectorShuffle(Ops[0], Ops[1], 8, 24, 9, 25,
10, 26, 11, 27,
@@ -409,23 +819,6 @@
case IX86_BUILTIN_MOVSLDUP:
Result = BuildVectorShuffle(Ops[0], Ops[0], 0, 0, 2, 2);
return true;
- case IX86_BUILTIN_VEC_INIT_V2SI:
- Result = BuildVector(Ops[0], Ops[1], NULL);
- return true;
- case IX86_BUILTIN_VEC_INIT_V4HI:
- // Sometimes G++ promotes arguments to int.
- for (unsigned i = 0; i != 4; ++i)
- Ops[i] = Builder.CreateIntCast(Ops[i], Type::getInt16Ty(Context), false);
- Result = BuildVector(Ops[0], Ops[1], Ops[2], Ops[3], NULL);
- return true;
- case IX86_BUILTIN_VEC_INIT_V8QI:
- // Sometimes G++ promotes arguments to int.
- for (unsigned i = 0; i != 8; ++i)
- Ops[i] = Builder.CreateIntCast(Ops[i], Type::getInt8Ty(Context), false);
- Result = BuildVector(Ops[0], Ops[1], Ops[2], Ops[3],
- Ops[4], Ops[5], Ops[6], Ops[7], NULL);
- return true;
- case IX86_BUILTIN_VEC_EXT_V2SI:
case IX86_BUILTIN_VEC_EXT_V4HI:
case IX86_BUILTIN_VEC_EXT_V2DF:
case IX86_BUILTIN_VEC_EXT_V2DI:
@@ -610,58 +1003,6 @@
Result = Builder.CreateLoad(Ptr);
return true;
}
- case IX86_BUILTIN_PALIGNR: {
- if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[2])) {
-
- // In the header we multiply by 8, correct that back now.
- unsigned shiftVal = (cast<ConstantInt>(Ops[2])->getZExtValue())/8;
-
- // If palignr is shifting the pair of input vectors less than 9 bytes,
- // emit a shuffle instruction.
- if (shiftVal <= 8) {
- const llvm::Type *IntTy = Type::getInt32Ty(Context);
- const llvm::Type *EltTy = Type::getInt8Ty(Context);
- const llvm::Type *VecTy = VectorType::get(EltTy, 8);
-
- Ops[1] = Builder.CreateBitCast(Ops[1], VecTy);
- Ops[0] = Builder.CreateBitCast(Ops[0], VecTy);
-
- SmallVector<Constant*, 8> Indices;
- for (unsigned i = 0; i != 8; ++i)
- Indices.push_back(ConstantInt::get(IntTy, shiftVal + i));
-
- Value* SV = ConstantVector::get(Indices.begin(), Indices.size());
- Result = Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
- return true;
- }
-
- // If palignr is shifting the pair of input vectors more than 8 but less
- // than 16 bytes, emit a logical right shift of the destination.
- if (shiftVal < 16) {
- // MMX has these as 1 x i64 vectors for some odd optimization reasons.
- const llvm::Type *EltTy = Type::getInt64Ty(Context);
- const llvm::Type *VecTy = VectorType::get(EltTy, 1);
-
- Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
- Ops[1] = ConstantInt::get(VecTy, (shiftVal-8) * 8);
-
- // create i32 constant
- Function *F = Intrinsic::getDeclaration(TheModule,
- Intrinsic::x86_mmx_psrl_q);
- Result = Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
- return true;
- }
-
- // If palignr is shifting the pair of vectors more than 32 bytes,
- // emit zero.
- Result = Constant::getNullValue(ResultType);
- return true;
- } else {
- error("%Hmask must be an immediate", &EXPR_LOCATION(exp));
- Result = Ops[0];
- return true;
- }
- }
case IX86_BUILTIN_PALIGNR128: {
if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[2])) {
Modified: llvm-gcc-4.2/trunk/gcc/llvm-abi.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-abi.h?rev=115245&r1=115244&r2=115245&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-abi.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-abi.h Thu Sep 30 18:59:33 2010
@@ -380,6 +380,14 @@
assert (0 && "LLVM_EXTRACT_MULTIPLE_RETURN_VALUE is not implemented!");
}
+#ifndef LLVM_IS_DECL_MMX_REGISTER
+#define LLVM_IS_DECL_MMX_REGISTER(decl) false
+#endif
+
+#ifndef LLVM_ADJUST_MMX_PARAMETER_TYPE
+#define LLVM_ADJUST_MMX_PARAMETER_TYPE(LLVMTy) LLVMTy
+#endif
+
/// DefaultABI - This class implements the default LLVM ABI where structures are
/// passed by decimating them into individual components and unions are passed
/// by passing the largest member of the union.
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=115245&r1=115244&r2=115245&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Sep 30 18:59:33 2010
@@ -344,6 +344,7 @@
void HandleScalarArgument(const llvm::Type *LLVMTy, tree type,
unsigned RealSize = 0) {
Value *ArgVal = AI;
+ LLVMTy = LLVM_ADJUST_MMX_PARAMETER_TYPE(LLVMTy);
if (ArgVal->getType() != LLVMTy) {
if (ArgVal->getType()->isPointerTy() && LLVMTy->isPointerTy()) {
// If this is GCC being sloppy about pointer types, insert a bitcast.
@@ -1319,7 +1320,9 @@
// node. This may not hold for bitfields because the type of a bitfield need
// not match the type of the value being loaded out of it. Since LLVM has no
// void* type, don't insist that void* be converted to a specific LLVM type.
+ // For MMX registers, we deliberately changed the type to x86mmx here.
assert((LV.isBitfield() || VOID_TYPE_P(TREE_TYPE(exp)) ||
+ LLVM_IS_DECL_MMX_REGISTER(exp) ||
LV.Ptr->getType() == ConvertType(TREE_TYPE(exp))->getPointerTo()) &&
"LValue has wrong type!");
@@ -1859,6 +1862,9 @@
}
}
+ if (LLVM_IS_DECL_MMX_REGISTER(decl))
+ Ty = Type::getX86_MMXTy(Context);
+
unsigned Alignment = 0; // Alignment in bytes.
// Set the alignment for the local if one of the following condition is met
@@ -2500,6 +2506,8 @@
LValue LV = EmitLV(exp);
bool isVolatile = TREE_THIS_VOLATILE(exp);
const Type *Ty = ConvertType(TREE_TYPE(exp));
+ if (LLVM_IS_DECL_MMX_REGISTER(exp))
+ Ty = Type::getX86_MMXTy(Context);
unsigned Alignment = LV.getAlignment();
if (!LV.isBitfield()) {
@@ -4948,6 +4956,8 @@
const Type *LLVMTy = ConvertType(type);
Value *Op = 0;
+ if (LLVM_IS_DECL_MMX_REGISTER(Val))
+ LLVMTy = Type::getX86_MMXTy(Context);
const Type *OpTy = LLVMTy;
if (LLVMTy->isSingleValueType()) {
if (TREE_CODE(Val)==ADDR_EXPR &&
@@ -7519,6 +7529,8 @@
// If we have "extern void foo", make the global have type {} instead of
// type void.
if (Ty->isVoidTy()) Ty = StructType::get(Context);
+ if (LLVM_IS_DECL_MMX_REGISTER(exp))
+ Ty = Type::getX86_MMXTy(Context);
const PointerType *PTy = Ty->getPointerTo();
unsigned Alignment = Ty->isSized() ? TD.getABITypeAlignment(Ty) : 1;
if (DECL_ALIGN(exp)) {
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=115245&r1=115244&r2=115245&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Sep 30 18:59:33 2010
@@ -1021,6 +1021,7 @@
LLVMTy->isIntegerTy(1))
LLVMTy = Type::getInt32Ty(Context);
}
+ LLVMTy = LLVM_ADJUST_MMX_PARAMETER_TYPE(LLVMTy);
ArgTypes.push_back(LLVMTy);
}
More information about the llvm-commits
mailing list