From 2cf5d8c2a02f7dec2b089d92dd380be68cb1a359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Tue, 2 Oct 2012 21:37:27 +0200 Subject: [PATCH] Added pragma extractelement --- dmd2/idgen.c | 1 + gen/pragma.cpp | 23 +++++++++++++++++++++++ gen/pragma.h | 1 + gen/toir.cpp | 14 +++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/dmd2/idgen.c b/dmd2/idgen.c index 457220bdd9..96899737db 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -274,6 +274,7 @@ Msgtable msgtable[] = { "no_moduleinfo" }, { "Alloca", "alloca" }, { "Shufflevector", "shufflevector" }, + { "Extractelement", "extractelement" }, { "vastart", "va_start" }, { "vacopy", "va_copy" }, { "vaend", "va_end" }, diff --git a/gen/pragma.cpp b/gen/pragma.cpp index 2ac9485036..0ef0b324e3 100644 --- a/gen/pragma.cpp +++ b/gen/pragma.cpp @@ -116,6 +116,17 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) return LLVMshufflevector; } + // pragma(extractelement) { funcdecl(s) } + else if (ident == Id::Extractelement) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + return LLVMextractelement; + } + // pragma(va_start) { templdecl(s) } else if (ident == Id::vastart) { @@ -375,6 +386,18 @@ void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, } break; + case LLVMextractelement: + 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 fc4322c130..6da358c0b7 100644 --- a/gen/pragma.h +++ b/gen/pragma.h @@ -15,6 +15,7 @@ enum Pragma LLVMno_moduleinfo, LLVMalloca, LLVMshufflevector, + LLVMextractelement, LLVMva_start, LLVMva_copy, LLVMva_end, diff --git a/gen/toir.cpp b/gen/toir.cpp index 3cde74cdbf..474d8004cd 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1007,7 +1007,19 @@ DValue* CallExp::toElem(IRState* p) LLValue* v1 = exp1->toElem(p)->getRVal(); LLValue* v2 = exp2->toElem(p)->getRVal(); return new DImValue(type, p->ir->CreateShuffleVector(v1, v2, maskVal)); - } + } + // extractelement + else if(fndecl->llvmInternal == LLVMextractelement) { + Expression* exp2 = static_cast(arguments->data[1]); + if(exp2->op != TOKint64){ + error("Function %s was declared with pragma extractelement. Because of that its second argument must be an integer literal.", fndecl->toChars()); + fatal(); + } + LLConstant* idx = static_cast(arguments->data[1])->toConstElem(p); + Expression* exp1 = static_cast(arguments->data[0]); + LLValue* vec = exp1->toElem(p)->getRVal(); + return new DImValue(type, p->ir->CreateExtractElement(vec, idx)); + } // fence instruction else if (fndecl->llvmInternal == LLVMfence) { if (arguments->dim != 1) {