diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-03 00:16:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-03 00:16:29 +0000 |
commit | 73ab9b3c14673ebeaf2bf2f7bda3b0b1c2bbad7c (patch) | |
tree | ff7f72601d2e0459544c4a41a3ef85d27b32da7d | |
parent | 9e751cae2756933c9eec8076ff767bf9dc7a6a72 (diff) | |
download | bcm5719-llvm-73ab9b3c14673ebeaf2bf2f7bda3b0b1c2bbad7c.tar.gz bcm5719-llvm-73ab9b3c14673ebeaf2bf2f7bda3b0b1c2bbad7c.zip |
implement lvalue to rvalue conversion for ocuvector components. We can now compile stuff
like this:
typedef __attribute__(( ocu_vector_type(4) )) float float4;
float4 test1(float4 V) {
return V.wzyx+V;
}
to:
_test1:
pshufd $27, %xmm0, %xmm1
addps %xmm0, %xmm1
movaps %xmm1, %xmm0
ret
and:
_test1:
mfspr r2, 256
oris r3, r2, 4096
mtspr 256, r3
li r3, lo16(LCPI1_0)
lis r4, ha16(LCPI1_0)
lvx v3, r4, r3
vperm v3, v2, v2, v3
vaddfp v2, v3, v2
mtspr 256, r2
blr
llvm-svn: 40771
-rw-r--r-- | clang/CodeGen/CGExpr.cpp | 26 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 3 |
2 files changed, 28 insertions, 1 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 1a841f9d81d..7d8dc8c33b9 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -282,6 +282,30 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(), "vecext")); } + + // If this is a reference to a subset of the elements of a vector, either + // shuffle the input or extract/insert them as appropriate. + if (LV.isOCUVectorComp()) { + llvm::Value *Vec = Builder.CreateLoad(LV.getOCUVectorAddr(), "tmp"); + unsigned NumElts = cast<VectorType>(ExprType)->getNumElements(); + + // Start out with an undef of the result type. + llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType)); + + unsigned EncFields = LV.getOCUVectorComp(); + + // Extract/Insert each element of the result. + for (unsigned i = 0; i != NumElts; ++i) { + unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(i, EncFields); + llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx); + Elt = Builder.CreateExtractElement(Vec, Elt, "tmp"); + + llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i); + Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp"); + } + + return RValue::get(Result); + } assert(0 && "Bitfield ref not impl!"); } @@ -505,6 +529,8 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) { return EmitLoadOfLValue(E); case Expr::ArraySubscriptExprClass: return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E)); + case Expr::OCUVectorComponentClass: + return EmitLoadOfLValue(E); case Expr::PreDefinedExprClass: case Expr::StringLiteralClass: return RValue::get(EmitLValue(E).getAddress()); diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index 37614e95f06..919e68c91d0 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -141,6 +141,7 @@ public: llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } // ocu vector components. + llvm::Value *getOCUVectorAddr() const { assert(isOCUVectorComp()); return V; } unsigned getOCUVectorComp() const { assert(isOCUVectorComp()); return VectorComp; @@ -164,7 +165,7 @@ public: static LValue MakeOCUVectorComp(llvm::Value *Vec, unsigned Components) { LValue R; - R.LVType = VectorElt; + R.LVType = OCUVectorComp; R.V = Vec; R.VectorComp = Components; return R; |