From 23947489f7075a688df0ca021229290dc17b5e6a Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Wed, 7 Dec 2011 15:25:42 +0400 Subject: [PATCH] Backported llvm3.0 intrinsic patch to ldc1 --- dmd/attrib.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ dmd/idgen.c | 7 +++++ 2 files changed, 81 insertions(+) diff --git a/dmd/attrib.c b/dmd/attrib.c index 3bc9bae8..0e9b52fc 100644 --- a/dmd/attrib.c +++ b/dmd/attrib.c @@ -1174,6 +1174,63 @@ void PragmaDeclaration::semantic(Scope *sc) llvm_internal = LLVMva_arg; } + // pragma(fence) { templdecl(s) } + else if (ident == Id::fence) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMfence; + } + + // pragma(atomic_load) { templdecl(s) } + else if (ident == Id::atomic_load) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMatomic_load; + } + + // pragma(atomic_store) { templdecl(s) } + else if (ident == Id::atomic_store) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMatomic_store; + } + + // pragma(atomic_cmp_xchg) { templdecl(s) } + else if (ident == Id::atomic_cmp_xchg) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + llvm_internal = LLVMatomic_cmp_xchg; + } + + // pragma(atomic_rmw, "string") { templdecl(s) } + else if (ident == Id::atomic_rmw) + { + Expression* expr = (Expression *)args->data[0]; + expr = expr->semantic(sc); + if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) + { + error("requires exactly 1 string literal parameter"); + fatal(); + } + llvm_internal = LLVMatomic_rmw; + } + // pragma(ldc, "string") { templdecl(s) } else if (ident == Id::ldc) { @@ -1286,8 +1343,24 @@ void PragmaDeclaration::semantic(Scope *sc) } break; + case LLVMatomic_rmw: + if (TemplateDeclaration* td = s->isTemplateDeclaration()) + { + td->llvmInternal = llvm_internal; + td->intrinsicName = arg1str; + } + else + { + error("the '%s' pragma is only allowed on template declarations", ident->toChars()); + fatal(); + } + break; + case LLVMva_start: case LLVMva_arg: + case LLVMatomic_load: + case LLVMatomic_store: + case LLVMatomic_cmp_xchg: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim != 1) @@ -1316,6 +1389,7 @@ void PragmaDeclaration::semantic(Scope *sc) case LLVMva_copy: case LLVMva_end: + case LLVMfence: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; diff --git a/dmd/idgen.c b/dmd/idgen.c index 5ef958f0..88d12383 100644 --- a/dmd/idgen.c +++ b/dmd/idgen.c @@ -219,6 +219,7 @@ Msgtable msgtable[] = { "lib" }, { "msg" }, +#if IN_LLVM // LDC pragma's { "intrinsic" }, { "va_intrinsic" }, @@ -232,6 +233,12 @@ Msgtable msgtable[] = { "ldc" }, { "allow_inline" }, { "llvm_inline_asm" }, + { "fence" }, + { "atomic_load" }, + { "atomic_store" }, + { "atomic_cmp_xchg" }, + { "atomic_rmw" }, +#endif // For special functions { "tohash", "toHash" },