From 100907ffa264de38bd0129ae605a624fd4e8e6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Sun, 5 Aug 2012 18:51:49 +0200 Subject: [PATCH] Added pragma shufflevector. --- dmd2/idgen.c | 1 + gen/pragma.cpp | 23 +++++++++++++++++++++++ gen/pragma.h | 1 + gen/toir.cpp | 22 +++++++++++++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/dmd2/idgen.c b/dmd2/idgen.c index 2e40fbce..41f52ab7 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -272,6 +272,7 @@ Msgtable msgtable[] = { "no_typeinfo" }, { "no_moduleinfo" }, { "Alloca", "alloca" }, + { "Shufflevector", "shufflevector" }, { "vastart", "va_start" }, { "vacopy", "va_copy" }, { "vaend", "va_end" }, diff --git a/gen/pragma.cpp b/gen/pragma.cpp index d9270c59..0681a6af 100644 --- a/gen/pragma.cpp +++ b/gen/pragma.cpp @@ -106,6 +106,17 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) return LLVMalloca; } + // pragma(shufflevector) { funcdecl(s) } + else if (ident == Id::Shufflevector) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + return LLVMshufflevector; + } + // pragma(va_start) { templdecl(s) } else if (ident == Id::vastart) { @@ -356,6 +367,18 @@ void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, } break; + case LLVMshufflevector: + if (FuncDeclaration* fd = s->isFuncDeclaration()) + { + fd->llvmInternal = llvm_internal; + } + else + { + error("the '%s' pragma must only be used on function declarations.", ident->toChars()); + fatal(); + } + break; + case LLVMinline_asm: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { diff --git a/gen/pragma.h b/gen/pragma.h index cd53239a..fc4322c1 100644 --- a/gen/pragma.h +++ b/gen/pragma.h @@ -14,6 +14,7 @@ enum Pragma LLVMno_typeinfo, LLVMno_moduleinfo, LLVMalloca, + LLVMshufflevector, LLVMva_start, LLVMva_copy, LLVMva_end, diff --git a/gen/toir.cpp b/gen/toir.cpp index 4133cae6..37e4a200 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -947,8 +947,28 @@ DValue* CallExp::toElem(IRState* p) if (expv->getType()->toBasetype()->ty != Tint32) expv = DtoCast(loc, expv, Type::tint32); return new DImValue(type, p->ir->CreateAlloca(LLType::getInt8Ty(gIR->context()), expv->getRVal(), ".alloca")); + } + // shufflevector + else if (fndecl->llvmInternal == LLVMshufflevector) { + llvm::SmallVector mask; + for(int i = 2, n = arguments->dim; i < n; i++){ + Expression* exp = static_cast(arguments->data[i]); + if(exp->op != TOKint64){ + error("Function %s was declared with pragma shufflevector. Because of that all of its arguments except the first two must be integer literals.", f->toChars()); + fatal(); + } + IntegerExp* iexp = static_cast(arguments->data[i]); + mask.push_back(iexp->toConstElem(p)); + } + LLValue* maskVal = llvm::ConstantVector::get(mask); + Expression* exp1 = static_cast(arguments->data[0]); + Expression* exp2 = static_cast(arguments->data[1]); + LLValue* v1 = exp1->toElem(p)->getRVal(); + LLValue* v2 = exp2->toElem(p)->getRVal(); + return new DImValue(type, p->ir->CreateShuffleVector(v1, v2, maskVal)); + } // fence instruction - } else if (fndecl->llvmInternal == LLVMfence) { + else if (fndecl->llvmInternal == LLVMfence) { if (arguments->dim != 1) { error("fence instruction expects 1 arguments"); return NULL;