mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-12 06:49:02 +02:00
Merge pull request #177 from jerro/extractelement
extractelement and insertelement pragmas.
This commit is contained in:
@@ -230,6 +230,8 @@ Msgtable msgtable[] =
|
||||
{ "no_moduleinfo" },
|
||||
{ "Alloca", "alloca" },
|
||||
{ "Shufflevector", "shufflevector" },
|
||||
{ "Extractelement", "extractelement" },
|
||||
{ "Insertelement", "insertelement" },
|
||||
{ "vastart", "va_start" },
|
||||
{ "vacopy", "va_copy" },
|
||||
{ "vaend", "va_end" },
|
||||
|
||||
@@ -274,6 +274,8 @@ Msgtable msgtable[] =
|
||||
{ "no_moduleinfo" },
|
||||
{ "Alloca", "alloca" },
|
||||
{ "Shufflevector", "shufflevector" },
|
||||
{ "Extractelement", "extractelement" },
|
||||
{ "Insertelement", "insertelement" },
|
||||
{ "vastart", "va_start" },
|
||||
{ "vacopy", "va_copy" },
|
||||
{ "vaend", "va_end" },
|
||||
|
||||
@@ -116,6 +116,17 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str)
|
||||
return LLVMshufflevector;
|
||||
}
|
||||
|
||||
// pragma(extractelement or insertelement) { funcdecl(s) }
|
||||
else if (ident == Id::Extractelement || ident == Id::Insertelement)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return ident == Id::Extractelement ? LLVMextractelement : LLVMinsertelement;
|
||||
}
|
||||
|
||||
// pragma(va_start) { templdecl(s) }
|
||||
else if (ident == Id::vastart)
|
||||
{
|
||||
@@ -375,6 +386,19 @@ void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s,
|
||||
}
|
||||
break;
|
||||
|
||||
case LLVMextractelement:
|
||||
case LLVMinsertelement:
|
||||
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())
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@ enum Pragma
|
||||
LLVMno_moduleinfo,
|
||||
LLVMalloca,
|
||||
LLVMshufflevector,
|
||||
LLVMextractelement,
|
||||
LLVMinsertelement,
|
||||
LLVMva_start,
|
||||
LLVMva_copy,
|
||||
LLVMva_end,
|
||||
|
||||
32
gen/toir.cpp
32
gen/toir.cpp
@@ -994,8 +994,8 @@ DValue* CallExp::toElem(IRState* p)
|
||||
llvm::SmallVector<llvm::Constant*, 32> mask;
|
||||
for(int i = 2, n = arguments->dim; i < n; i++){
|
||||
Expression* exp = static_cast<Expression*>(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.", fndecl->toChars());
|
||||
if(exp->op != TOKint64 || exp->type->ty != Tint32){
|
||||
error("Function %s was declared with pragma shufflevector. Because of that all of its arguments except for the first two must be int literals.", fndecl->toChars());
|
||||
fatal();
|
||||
}
|
||||
IntegerExp* iexp = static_cast<IntegerExp*>(arguments->data[i]);
|
||||
@@ -1007,7 +1007,33 @@ 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<Expression*>(arguments->data[1]);
|
||||
if(exp2->op != TOKint64 || exp2->type->ty != Tint32){
|
||||
error("Function %s was declared with pragma extractelement. Because of that its second argument must be an int literal.", fndecl->toChars());
|
||||
fatal();
|
||||
}
|
||||
LLValue* idx = exp2->toElem(p)->getRVal();
|
||||
Expression* exp1 = static_cast<Expression*>(arguments->data[0]);
|
||||
LLValue* vec = exp1->toElem(p)->getRVal();
|
||||
return new DImValue(type, p->ir->CreateExtractElement(vec, idx));
|
||||
}
|
||||
// insertelement
|
||||
else if(fndecl->llvmInternal == LLVMinsertelement) {
|
||||
Expression* exp3 = static_cast<Expression*>(arguments->data[2]);
|
||||
if(exp3->op != TOKint64 || exp3->type->ty != Tint32){
|
||||
error("Function %s was declared with pragma insertelement. Because of that its third argument must be an int literal.", fndecl->toChars());
|
||||
fatal();
|
||||
}
|
||||
LLValue* idx = exp3->toElem(p)->getRVal();
|
||||
Expression* exp1 = static_cast<Expression*>(arguments->data[0]);
|
||||
LLValue* vec = exp1->toElem(p)->getRVal();
|
||||
Expression* exp2 = static_cast<Expression*>(arguments->data[1]);
|
||||
LLValue* scal = exp2->toElem(p)->getRVal();
|
||||
return new DImValue(type, p->ir->CreateInsertElement(vec, scal, idx));
|
||||
}
|
||||
// fence instruction
|
||||
else if (fndecl->llvmInternal == LLVMfence) {
|
||||
if (arguments->dim != 1) {
|
||||
|
||||
Reference in New Issue
Block a user