mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +03:00
Removed tango from the repository and instead added a runtime dir with the files needed to patch and build tango from svn.
Reworked the LLVMDC specific pragmas.
This commit is contained in:
parent
8f14ece3af
commit
07cfb67178
534 changed files with 1502 additions and 258956 deletions
|
@ -1,4 +1,4 @@
|
|||
|
||||
[Environment]
|
||||
|
||||
DFLAGS=-I%@P%/../tango -L-L%@P%/../lib -R%@P%/../lib
|
||||
DFLAGS=-I%@P%/../tango -I%@P%/../tango/lib/common -I%@P%/../import -L-L%@P%/../lib -R%@P%/../lib
|
||||
|
|
221
dmd/attrib.c
221
dmd/attrib.c
|
@ -702,6 +702,20 @@ const char *AnonDeclaration::kind()
|
|||
|
||||
/********************************* PragmaDeclaration ****************************/
|
||||
|
||||
static bool parseStringExp(Expression* e, std::string& res)
|
||||
{
|
||||
StringExp *s = NULL;
|
||||
|
||||
e = e->optimize(WANTvalue);
|
||||
if (e->op == TOKstring && (s = (StringExp *)e))
|
||||
{
|
||||
char* str = (char*)s->string;
|
||||
res = str;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
|
@ -725,7 +739,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||
|
||||
#if IN_LLVM
|
||||
int llvm_internal = 0;
|
||||
char* llvm_str1 = NULL;
|
||||
std::string arg1str;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -813,82 +827,93 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||
goto Lnodecl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// LLVMDC
|
||||
#if IN_LLVM
|
||||
else if (ident == Id::LLVM_internal)
|
||||
{
|
||||
if (!args || args->dim < 1 || args->dim > 2)
|
||||
error("needs 1-3 parameters");
|
||||
else if (!decl || decl->dim < 1)
|
||||
error("must apply to at least one declaration");
|
||||
else
|
||||
{
|
||||
Expression *e;
|
||||
StringExp *s = NULL;
|
||||
|
||||
e = (Expression *)args->data[0];
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue);
|
||||
if (e->op == TOKstring && (s = (StringExp *)e))
|
||||
// pragma(intrinsic, dotExpS) { funcdecl(s) }
|
||||
else if (ident == Id::intrinsic)
|
||||
{
|
||||
char* str = (char*)s->string;
|
||||
if (strcmp(str,"intrinsic")==0) {
|
||||
Expression* expr = (Expression *)args->data[0];
|
||||
expr = expr->semantic(sc);
|
||||
if (!args || args->dim != 1 || !parseStringExp(expr, arg1str))
|
||||
{
|
||||
error("pragma intrinsic requires exactly 1 string literal parameter");
|
||||
fatal();
|
||||
}
|
||||
llvm_internal = LLVMintrinsic;
|
||||
assert(args->dim == 2);
|
||||
}
|
||||
else if (strcmp(str,"va_start")==0) {
|
||||
llvm_internal = LLVMva_start;
|
||||
assert(args->dim == 1);
|
||||
}
|
||||
else if (strcmp(str,"va_arg")==0) {
|
||||
llvm_internal = LLVMva_arg;
|
||||
assert(args->dim == 1);
|
||||
}
|
||||
else if (strcmp(str,"va_intrinsic")==0) {
|
||||
llvm_internal = LLVMva_intrinsic;
|
||||
assert(args->dim == 2);
|
||||
}
|
||||
else if (strcmp(str,"notypeinfo")==0) {
|
||||
llvm_internal = LLVMnotypeinfo;
|
||||
assert(args->dim == 1);
|
||||
}
|
||||
else if (strcmp(str,"alloca")==0) {
|
||||
llvm_internal = LLVMalloca;
|
||||
assert(args->dim == 1);
|
||||
}
|
||||
else {
|
||||
error("unknown pragma command: %s", str);
|
||||
}
|
||||
}
|
||||
else
|
||||
error("1st argument must be a string");
|
||||
|
||||
if (llvm_internal)
|
||||
switch (llvm_internal)
|
||||
// pragma(va_intrinsic, dotExpS) { funcdecl(s) }
|
||||
else if (ident == Id::va_intrinsic)
|
||||
{
|
||||
case LLVMintrinsic:
|
||||
case LLVMva_intrinsic:
|
||||
e = (Expression *)args->data[1];
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue);
|
||||
if (e->op == TOKstring && (s = (StringExp *)e)) {
|
||||
llvm_str1 = (char*)s->string;
|
||||
Expression* expr = (Expression *)args->data[0];
|
||||
expr = expr->semantic(sc);
|
||||
if (!args || args->dim != 1 || !parseStringExp(expr, arg1str))
|
||||
{
|
||||
error("pragma va_intrinsic requires exactly 1 string literal parameter");
|
||||
fatal();
|
||||
}
|
||||
llvm_internal = LLVMva_intrinsic;
|
||||
}
|
||||
else
|
||||
error("2nd argument must be a string");
|
||||
break;
|
||||
|
||||
case LLVMva_arg:
|
||||
case LLVMva_start:
|
||||
case LLVMnotypeinfo:
|
||||
case LLVMalloca:
|
||||
break;
|
||||
// pragma(notypeinfo) { typedecl(s) }
|
||||
else if (ident == Id::no_typeinfo)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("pragma no_typeinfo takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
llvm_internal = LLVMno_typeinfo;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
// pragma(nomoduleinfo) ;
|
||||
else if (ident == Id::no_moduleinfo)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("pragma no_moduleinfo takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
llvm_internal = LLVMno_moduleinfo;
|
||||
}
|
||||
|
||||
// pragma(alloca) { funcdecl(s) }
|
||||
else if (ident == Id::alloca)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("pragma alloca takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
#endif
|
||||
llvm_internal = LLVMalloca;
|
||||
}
|
||||
|
||||
// pragma(va_start) { templdecl(s) }
|
||||
else if (ident == Id::va_start)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("pragma va_start takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
llvm_internal = LLVMva_start;
|
||||
}
|
||||
|
||||
// pragma(va_arg) { templdecl(s) }
|
||||
else if (ident == Id::va_arg)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("pragma va_arg takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
llvm_internal = LLVMva_arg;
|
||||
}
|
||||
|
||||
#endif // LLVMDC
|
||||
|
||||
else if (global.params.ignoreUnsupportedPragmas)
|
||||
{
|
||||
if (global.params.verbose)
|
||||
|
@ -927,59 +952,83 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||
|
||||
s->semantic(sc);
|
||||
|
||||
// LLVMDC
|
||||
#if IN_LLVM
|
||||
|
||||
if (llvm_internal)
|
||||
{
|
||||
if (s->llvmInternal)
|
||||
{
|
||||
error("multiple LLVMDC specific pragmas not allowed not affect the same declaration (%s at '%s')", s->toChars(), s->loc.toChars());
|
||||
fatal();
|
||||
}
|
||||
switch(llvm_internal)
|
||||
{
|
||||
case LLVMintrinsic:
|
||||
case LLVMva_intrinsic:
|
||||
if (FuncDeclaration* fd = s->isFuncDeclaration()) {
|
||||
if (FuncDeclaration* fd = s->isFuncDeclaration())
|
||||
{
|
||||
fd->llvmInternal = llvm_internal;
|
||||
fd->llvmInternal1 = llvm_str1;
|
||||
fd->intrinsicName = arg1str;
|
||||
}
|
||||
else {
|
||||
error("may only be used on function declarations");
|
||||
assert(0);
|
||||
else
|
||||
{
|
||||
error("intrinsic pragmas are only allowed to affect function declarations");
|
||||
fatal();
|
||||
}
|
||||
break;
|
||||
|
||||
case LLVMva_start:
|
||||
case LLVMva_arg:
|
||||
if (TemplateDeclaration* td = s->isTemplateDeclaration()) {
|
||||
td->llvmInternal = llvm_internal;
|
||||
assert(td->parameters->dim == 1);
|
||||
assert(!td->overnext);
|
||||
assert(!td->overroot);
|
||||
assert(td->onemember);
|
||||
Logger::println("template->onemember = %s", td->onemember->toChars());
|
||||
if (TemplateDeclaration* td = s->isTemplateDeclaration())
|
||||
{
|
||||
if (td->parameters->dim != 1)
|
||||
{
|
||||
error("the %s pragma template must have exactly one template parameter", ident->toChars());
|
||||
fatal();
|
||||
}
|
||||
else {
|
||||
error("can only be used on templates");
|
||||
assert(0);
|
||||
else if (!td->onemember)
|
||||
{
|
||||
error("the %s pragma template must have exactly one member", ident->toChars());
|
||||
fatal();
|
||||
}
|
||||
else if (td->overnext || td->overroot)
|
||||
{
|
||||
error("the %s pragma template must not be overloaded", ident->toChars());
|
||||
fatal();
|
||||
}
|
||||
td->llvmInternal = llvm_internal;
|
||||
}
|
||||
else
|
||||
{
|
||||
error("the %s pragma is only allowed on template declarations", ident->toChars());
|
||||
fatal();
|
||||
}
|
||||
break;
|
||||
|
||||
case LLVMnotypeinfo:
|
||||
case LLVMno_typeinfo:
|
||||
s->llvmInternal = llvm_internal;
|
||||
break;
|
||||
|
||||
case LLVMalloca:
|
||||
if (FuncDeclaration* fd = s->isFuncDeclaration()) {
|
||||
if (FuncDeclaration* fd = s->isFuncDeclaration())
|
||||
{
|
||||
fd->llvmInternal = llvm_internal;
|
||||
}
|
||||
else {
|
||||
error("may only be used on function declarations");
|
||||
assert(0);
|
||||
else
|
||||
{
|
||||
error("the %s pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars());
|
||||
fatal();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0 && "invalid LLVM_internal pragma got through :/");
|
||||
warning("LLVMDC specific pragma %s not yet implemented, ignoring", ident->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // LLVMDC
|
||||
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "dsymbol.h"
|
||||
#include "lexer.h"
|
||||
|
@ -639,6 +640,7 @@ struct FuncDeclaration : Declaration
|
|||
|
||||
// llvmdc stuff
|
||||
std::set<VarDeclaration*> nestedVars;
|
||||
std::string intrinsicName;
|
||||
|
||||
// we keep our own table of label statements as LabelDsymbolS
|
||||
// don't always carry their corresponding statement along ...
|
||||
|
|
|
@ -45,8 +45,6 @@ Dsymbol::Dsymbol()
|
|||
this->comment = NULL;
|
||||
|
||||
this->llvmInternal = LLVMnone;
|
||||
this->llvmInternal1 = NULL;
|
||||
this->llvmInternal2 = NULL;
|
||||
}
|
||||
|
||||
Dsymbol::Dsymbol(Identifier *ident)
|
||||
|
@ -61,8 +59,6 @@ Dsymbol::Dsymbol(Identifier *ident)
|
|||
this->comment = NULL;
|
||||
|
||||
this->llvmInternal = LLVMnone;
|
||||
this->llvmInternal1 = NULL;
|
||||
this->llvmInternal2 = NULL;
|
||||
}
|
||||
|
||||
int Dsymbol::equals(Object *o)
|
||||
|
|
|
@ -223,8 +223,6 @@ struct Dsymbol : Object
|
|||
|
||||
// llvm stuff
|
||||
int llvmInternal;
|
||||
char* llvmInternal1;
|
||||
char* llvmInternal2;
|
||||
|
||||
IrDsymbol ir;
|
||||
};
|
||||
|
|
|
@ -90,6 +90,10 @@ Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
|
|||
f->fensure = fensure ? fensure->syntaxCopy() : NULL;
|
||||
f->fbody = fbody ? fbody->syntaxCopy() : NULL;
|
||||
assert(!fthrows); // deprecated
|
||||
|
||||
// LLVMDC
|
||||
f->intrinsicName = intrinsicName;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
20
dmd/id.c
20
dmd/id.c
|
@ -167,11 +167,15 @@ Identifier *Id::aaRehash;
|
|||
Identifier *Id::lib;
|
||||
Identifier *Id::msg;
|
||||
Identifier *Id::GNU_asm;
|
||||
Identifier *Id::LLVM_intrinsic;
|
||||
Identifier *Id::LLVM_internal;
|
||||
Identifier *Id::intrinsic;
|
||||
Identifier *Id::va_intrinsic;
|
||||
Identifier *Id::no_typeinfo;
|
||||
Identifier *Id::no_moduleinfo;
|
||||
Identifier *Id::alloca;
|
||||
Identifier *Id::va_start;
|
||||
Identifier *Id::va_arg;
|
||||
Identifier *Id::tohash;
|
||||
Identifier *Id::tostring;
|
||||
Identifier *Id::alloca;
|
||||
Identifier *Id::main;
|
||||
Identifier *Id::WinMain;
|
||||
Identifier *Id::DllMain;
|
||||
|
@ -342,11 +346,15 @@ void Id::initialize()
|
|||
lib = Lexer::idPool("lib");
|
||||
msg = Lexer::idPool("msg");
|
||||
GNU_asm = Lexer::idPool("GNU_asm");
|
||||
LLVM_intrinsic = Lexer::idPool("LLVM_intrinsic");
|
||||
LLVM_internal = Lexer::idPool("LLVM_internal");
|
||||
intrinsic = Lexer::idPool("intrinsic");
|
||||
va_intrinsic = Lexer::idPool("va_intrinsic");
|
||||
no_typeinfo = Lexer::idPool("no_typeinfo");
|
||||
no_moduleinfo = Lexer::idPool("no_moduleinfo");
|
||||
alloca = Lexer::idPool("alloca");
|
||||
va_start = Lexer::idPool("va_start");
|
||||
va_arg = Lexer::idPool("va_arg");
|
||||
tohash = Lexer::idPool("toHash");
|
||||
tostring = Lexer::idPool("toString");
|
||||
alloca = Lexer::idPool("alloca");
|
||||
main = Lexer::idPool("main");
|
||||
WinMain = Lexer::idPool("WinMain");
|
||||
DllMain = Lexer::idPool("DllMain");
|
||||
|
|
10
dmd/id.h
10
dmd/id.h
|
@ -169,11 +169,15 @@ struct Id
|
|||
static Identifier *lib;
|
||||
static Identifier *msg;
|
||||
static Identifier *GNU_asm;
|
||||
static Identifier *LLVM_intrinsic;
|
||||
static Identifier *LLVM_internal;
|
||||
static Identifier *intrinsic;
|
||||
static Identifier *va_intrinsic;
|
||||
static Identifier *no_typeinfo;
|
||||
static Identifier *no_moduleinfo;
|
||||
static Identifier *alloca;
|
||||
static Identifier *va_start;
|
||||
static Identifier *va_arg;
|
||||
static Identifier *tohash;
|
||||
static Identifier *tostring;
|
||||
static Identifier *alloca;
|
||||
static Identifier *main;
|
||||
static Identifier *WinMain;
|
||||
static Identifier *DllMain;
|
||||
|
|
13
dmd/idgen.c
13
dmd/idgen.c
|
@ -212,15 +212,22 @@ Msgtable msgtable[] =
|
|||
{ "lib" },
|
||||
{ "msg" },
|
||||
{ "GNU_asm" },
|
||||
{ "LLVM_intrinsic" },
|
||||
{ "LLVM_internal" },
|
||||
|
||||
// LLVMDC pragma's
|
||||
{ "intrinsic" },
|
||||
{ "va_intrinsic" },
|
||||
{ "no_typeinfo" },
|
||||
{ "no_moduleinfo" },
|
||||
{ "alloca" },
|
||||
{ "va_start" },
|
||||
{ "va_arg" },
|
||||
|
||||
// For toHash/toString
|
||||
{ "tohash", "toHash" },
|
||||
{ "tostring", "toString" },
|
||||
|
||||
// Special functions
|
||||
{ "alloca" },
|
||||
//{ "alloca" },
|
||||
{ "main" },
|
||||
{ "WinMain" },
|
||||
{ "DllMain" },
|
||||
|
|
|
@ -2,9 +2,10 @@ enum
|
|||
{
|
||||
LLVMnone,
|
||||
LLVMintrinsic,
|
||||
LLVMva_arg,
|
||||
LLVMva_start,
|
||||
LLVMva_intrinsic,
|
||||
LLVMnotypeinfo,
|
||||
LLVMalloca
|
||||
LLVMno_typeinfo,
|
||||
LLVMno_moduleinfo,
|
||||
LLVMalloca,
|
||||
LLVMva_start,
|
||||
LLVMva_arg
|
||||
};
|
||||
|
|
|
@ -253,7 +253,7 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
|
|||
assert(fn);
|
||||
}
|
||||
else if (fdecl->llvmInternal == LLVMva_intrinsic) {
|
||||
fn = gIR->module->getOrInsertFunction(fdecl->llvmInternal1, fty);
|
||||
fn = gIR->module->getOrInsertFunction(fdecl->intrinsicName, fty);
|
||||
assert(fn);
|
||||
}
|
||||
else
|
||||
|
@ -405,9 +405,9 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
}
|
||||
|
||||
// mangled name
|
||||
char* mangled_name;
|
||||
const char* mangled_name;
|
||||
if (fdecl->llvmInternal == LLVMintrinsic)
|
||||
mangled_name = fdecl->llvmInternal1;
|
||||
mangled_name = fdecl->intrinsicName.c_str();
|
||||
else
|
||||
mangled_name = fdecl->mangle();
|
||||
|
||||
|
|
|
@ -361,7 +361,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
|||
gIR->structs.pop_back();
|
||||
|
||||
// emit typeinfo
|
||||
if (sd->getModule() == gIR->dmodule && sd->llvmInternal != LLVMnotypeinfo)
|
||||
if (sd->getModule() == gIR->dmodule && sd->llvmInternal != LLVMno_typeinfo)
|
||||
DtoTypeInfoOf(sd->type, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -758,8 +758,11 @@ DValue* CallExp::toElem(IRState* p)
|
|||
FuncDeclaration* fndecl = dfnval->func;
|
||||
// va_start instruction
|
||||
if (fndecl->llvmInternal == LLVMva_start) {
|
||||
// TODO
|
||||
assert(0 && "va_start not yet implemented");
|
||||
// llvm doesn't need the second param hence the override
|
||||
Expression* exp = (Expression*)arguments->data[0];
|
||||
DValue* expv = exp->toElem(p);
|
||||
LLValue* arg = DtoBitCast(expv->getLVal(), getVoidPtrType());
|
||||
return new DImValue(type, gIR->ir->CreateCall(GET_INTRINSIC_DECL(vastart), arg, ""));
|
||||
}
|
||||
// va_arg instruction
|
||||
else if (fndecl->llvmInternal == LLVMva_arg) {
|
||||
|
|
29
import/llvmdc/cstdarg.di
Normal file
29
import/llvmdc/cstdarg.di
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* vararg support for extern(C) functions
|
||||
*/
|
||||
|
||||
module llvmdc.cstdarg;
|
||||
|
||||
// Check for the right compiler
|
||||
version(LLVMDC)
|
||||
{
|
||||
// OK
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "This module is only valid for LLVMDC");
|
||||
}
|
||||
|
||||
alias void* va_list;
|
||||
|
||||
pragma(va_start)
|
||||
void va_start(T)(va_list ap, ref T);
|
||||
|
||||
pragma(va_arg)
|
||||
T va_arg(T)(va_list ap);
|
||||
|
||||
pragma(va_intrinsic, "llvm.va_end")
|
||||
void va_end(va_list args);
|
||||
|
||||
pragma(va_intrinsic, "llvm.va_copy")
|
||||
void va_copy(va_list dst, va_list src);
|
267
import/llvmdc/intrinsics.di
Normal file
267
import/llvmdc/intrinsics.di
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* This module holds declarations to LLVM intrinsics.
|
||||
*
|
||||
* See the LLVM language reference for more information:
|
||||
*
|
||||
* - http://llvm.org/docs/LangRef.html#intrinsics
|
||||
*
|
||||
*/
|
||||
|
||||
module llvmdc.intrinsics;
|
||||
|
||||
// Check for the right compiler
|
||||
version(LLVMDC)
|
||||
{
|
||||
// OK
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "This module is only valid for LLVMDC");
|
||||
}
|
||||
|
||||
//
|
||||
// CODE GENERATOR INTRINSICS
|
||||
//
|
||||
|
||||
|
||||
// The 'llvm.returnaddress' intrinsic attempts to compute a target-specific value indicating the return address of the current function or one of its callers.
|
||||
|
||||
pragma(intrinsic, "llvm.returnaddress")
|
||||
void* llvm_returnaddress(uint level);
|
||||
|
||||
|
||||
// The 'llvm.frameaddress' intrinsic attempts to return the target-specific frame pointer value for the specified stack frame.
|
||||
|
||||
pragma(intrinsic, "llvm.frameaddress")
|
||||
void* llvm_frameaddress(uint level);
|
||||
|
||||
|
||||
// The 'llvm.stacksave' intrinsic is used to remember the current state of the function stack, for use with llvm.stackrestore. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
|
||||
|
||||
pragma(intrinsic, "llvm.stacksave")
|
||||
void* llvm_stacksave();
|
||||
|
||||
|
||||
// The 'llvm.stackrestore' intrinsic is used to restore the state of the function stack to the state it was in when the corresponding llvm.stacksave intrinsic executed. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
|
||||
|
||||
pragma(intrinsic, "llvm.stackrestore")
|
||||
void llvm_stackrestore(void* ptr);
|
||||
|
||||
|
||||
// The 'llvm.prefetch' intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a noop. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
|
||||
|
||||
pragma(intrinsic, "llvm.prefetch")
|
||||
void llvm_prefetch(void* ptr, uint rw, uint locality);
|
||||
|
||||
|
||||
// The 'llvm.pcmarker' intrinsic is a method to export a Program Counter (PC) in a region of code to simulators and other tools. The method is target specific, but it is expected that the marker will use exported symbols to transmit the PC of the marker. The marker makes no guarantees that it will remain with any specific instruction after optimizations. It is possible that the presence of a marker will inhibit optimizations. The intended use is to be inserted after optimizations to allow correlations of simulation runs.
|
||||
|
||||
pragma(intrinsic, "llvm.pcmarker")
|
||||
void llvm_pcmarker(uint id);
|
||||
|
||||
|
||||
// The 'llvm.readcyclecounter' intrinsic provides access to the cycle counter register (or similar low latency, high accuracy clocks) on those targets that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC. As the backing counters overflow quickly (on the order of 9 seconds on alpha), this should only be used for small timings.
|
||||
|
||||
pragma(intrinsic, "llvm.readcyclecounter")
|
||||
ulong readcyclecounter();
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// STANDARD C LIBRARY INTRINSICS
|
||||
//
|
||||
|
||||
|
||||
// The 'llvm.memcpy.*' intrinsics copy a block of memory from the source location to the destination location.
|
||||
// Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do not return a value, and takes an extra alignment argument.
|
||||
|
||||
pragma(intrinsic, "llvm.memcpy.i32")
|
||||
void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment);
|
||||
pragma(intrinsic, "llvm.memcpy.i64")
|
||||
void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment);
|
||||
|
||||
|
||||
// The 'llvm.memmove.*' intrinsics move a block of memory from the source location to the destination location. It is similar to the 'llvm.memcpy' intrinsic but allows the two memory locations to overlap.
|
||||
// Note that, unlike the standard libc function, the llvm.memmove.* intrinsics do not return a value, and takes an extra alignment argument.
|
||||
|
||||
pragma(intrinsic, "llvm.memmove.i32")
|
||||
void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment);
|
||||
pragma(intrinsic, "llvm.memmove.i64")
|
||||
void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment);
|
||||
|
||||
|
||||
// The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte value.
|
||||
// Note that, unlike the standard libc function, the llvm.memset intrinsic does not return a value, and takes an extra alignment argument.
|
||||
|
||||
pragma(intrinsic, "llvm.memset.i32")
|
||||
void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment);
|
||||
pragma(intrinsic, "llvm.memset.i64")
|
||||
void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment);
|
||||
|
||||
|
||||
// The 'llvm.sqrt' intrinsics return the sqrt of the specified operand, returning the same value as the libm 'sqrt' functions would. Unlike sqrt in libm, however, llvm.sqrt has undefined behavior for negative numbers other than -0.0 (which allows for better optimization, because there is no need to worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like IEEE sqrt.
|
||||
|
||||
pragma(intrinsic, "llvm.sqrt.f32")
|
||||
float llvm_sqrt_f32(float val);
|
||||
pragma(intrinsic, "llvm.sqrt.f64")
|
||||
double llvm_sqrt_f64(double val);
|
||||
version(LLVM_X86_FP80)
|
||||
{
|
||||
pragma(intrinsic, "llvm.sqrt.f80")
|
||||
real llvm_sqrt_f80(real val);
|
||||
}
|
||||
|
||||
|
||||
// The 'llvm.sin.*' intrinsics return the sine of the operand.
|
||||
|
||||
pragma(intrinsic, "llvm.sin.f32")
|
||||
float llvm_sin_f32(float val);
|
||||
pragma(intrinsic, "llvm.sin.f64")
|
||||
double llvm_sin_f64(double val);
|
||||
version(LLVM_X86_FP80)
|
||||
{
|
||||
pragma(intrinsic, "llvm.sin.f80")
|
||||
real llvm_sin_f80(real val);
|
||||
}
|
||||
|
||||
|
||||
// The 'llvm.cos.*' intrinsics return the cosine of the operand.
|
||||
|
||||
pragma(intrinsic, "llvm.cos.f32")
|
||||
float llvm_cos_f32(float val);
|
||||
pragma(intrinsic, "llvm.cos.f64")
|
||||
double llvm_cos_f64(double val);
|
||||
version(LLVM_X86_FP80)
|
||||
{
|
||||
pragma(intrinsic, "llvm.cos.f80")
|
||||
real llvm_cos_f80(real val);
|
||||
}
|
||||
|
||||
|
||||
// The 'llvm.powi.*' intrinsics return the first operand raised to the specified (positive or negative) power. The order of evaluation of multiplications is not defined. When a vector of floating point type is used, the second argument remains a scalar integer value.
|
||||
|
||||
pragma(intrinsic, "llvm.powi.f32")
|
||||
float llvm_powi_f32(float val, int power);
|
||||
|
||||
pragma(intrinsic, "llvm.powi.f64")
|
||||
double llvm_powi_f64(double val, int power);
|
||||
version(LLVM_X86_FP80)
|
||||
{
|
||||
pragma(intrinsic, "llvm.powi.f80")
|
||||
real llvm_powi_f80(real val, int power);
|
||||
}
|
||||
|
||||
|
||||
// The 'llvm.pow.*' intrinsics return the first operand raised to the specified (positive or negative) power.
|
||||
|
||||
pragma(intrinsic, "llvm.pow.f32")
|
||||
float llvm_pow_f32(float val, float power);
|
||||
|
||||
pragma(intrinsic, "llvm.pow.f64")
|
||||
double llvm_pow_f64(double val, double power);
|
||||
version(LLVM_X86_FP80)
|
||||
{
|
||||
pragma(intrinsic, "llvm.pow.f80")
|
||||
real llvm_pow_f80(real val, real power);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// BIT MANIPULATION INTRINSICS
|
||||
//
|
||||
|
||||
// The 'llvm.bswap' family of intrinsics is used to byte swap integer values with an even number of bytes (positive multiple of 16 bits). These are useful for performing operations on data that is not in the target's native byte order.
|
||||
|
||||
pragma(intrinsic, "llvm.bswap.i16.i16")
|
||||
ushort llvm_bswap_i16(ushort val);
|
||||
|
||||
pragma(intrinsic, "llvm.bswap.i32.i32")
|
||||
uint llvm_bswap_i32(uint val);
|
||||
|
||||
pragma(intrinsic, "llvm.bswap.i64.i64")
|
||||
ulong llvm_bswap_i64(ulong val);
|
||||
|
||||
|
||||
// The 'llvm.ctpop' family of intrinsics counts the number of bits set in a value.
|
||||
|
||||
pragma(intrinsic, "llvm.ctpop.i8")
|
||||
ubyte llvm_ctpop_i8(ubyte src);
|
||||
|
||||
pragma(intrinsic, "llvm.ctpop.i16")
|
||||
ushort llvm_ctpop_i16(ushort src);
|
||||
|
||||
pragma(intrinsic, "llvm.ctpop.i32")
|
||||
uint llvm_ctpop_i32(uint src);
|
||||
|
||||
pragma(intrinsic, "llvm.ctpop.i64")
|
||||
ulong llvm_ctpop_i64(ulong src);
|
||||
|
||||
|
||||
// The 'llvm.ctlz' family of intrinsic functions counts the number of leading zeros in a variable.
|
||||
|
||||
pragma(intrinsic, "llvm.ctlz.i8")
|
||||
ubyte llvm_ctlz_i8(ubyte src);
|
||||
|
||||
pragma(intrinsic, "llvm.ctlz.i16")
|
||||
ushort llvm_ctlz_i16(ushort src);
|
||||
|
||||
pragma(intrinsic, "llvm.ctlz.i32")
|
||||
uint llvm_ctlz_i32(uint src);
|
||||
|
||||
pragma(intrinsic, "llvm.ctlz.i64")
|
||||
ulong llvm_ctlz_i64(ulong src);
|
||||
|
||||
|
||||
// The 'llvm.cttz' family of intrinsic functions counts the number of trailing zeros.
|
||||
|
||||
pragma(intrinsic, "llvm.cttz.i8")
|
||||
ubyte llvm_cttz_i8(ubyte src);
|
||||
|
||||
pragma(intrinsic, "llvm.cttz.i16")
|
||||
ushort llvm_cttz_i16(ushort src);
|
||||
|
||||
pragma(intrinsic, "llvm.cttz.i32")
|
||||
uint llvm_cttz_i32(uint src);
|
||||
|
||||
pragma(intrinsic, "llvm.cttz.i64")
|
||||
ulong llvm_cttz_i64(ulong src);
|
||||
|
||||
|
||||
// The 'llvm.part.select' family of intrinsic functions selects a range of bits from an integer value and returns them in the same bit width as the original value.
|
||||
|
||||
pragma(intrinsic, "llvm.part.select.i8")
|
||||
ubyte llvm_part_select_i(ubyte val, uint loBit, uint hiBit);
|
||||
|
||||
pragma(intrinsic, "llvm.part.select.i16")
|
||||
ushort llvm_part_select_i(ushort val, uint loBit, uint hiBit);
|
||||
|
||||
pragma(intrinsic, "llvm.part.select.i32")
|
||||
uint llvm_part_select_i(uint val, uint loBit, uint hiBit);
|
||||
|
||||
pragma(intrinsic, "llvm.part.select.i64")
|
||||
ulong llvm_part_select_i(ulong val, uint loBit, uint hiBit);
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// ATOMIC OPERATIONS AND SYNCHRONIZATION INTRINSICS
|
||||
//
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// GENERAL INTRINSICS
|
||||
//
|
||||
|
||||
|
||||
// This intrinsics is lowered to the target dependent trap instruction. If the target does not have a trap instruction, this intrinsic will be lowered to the call of the abort() function.
|
||||
|
||||
pragma(intrinsic, "llvm.trap")
|
||||
void llvm_trap();
|
|
@ -13,7 +13,7 @@ noversion=DigitalMars
|
|||
noversion=GNU
|
||||
testversion=linux
|
||||
testversion=Unix
|
||||
version=Posix
|
||||
testversion=Posix
|
||||
testversion=Windows
|
||||
testversion=Win32
|
||||
testversion=Win64
|
||||
|
@ -29,6 +29,7 @@ testversion=D_InlineAsm_PPC64
|
|||
testversion=LittleEndian
|
||||
testversion=BigEndian
|
||||
testversion=LLVM64
|
||||
textversion=LLVM_X86_FP80
|
||||
|
||||
|
||||
[compile]
|
||||
|
|
|
@ -362,6 +362,50 @@
|
|||
<path>tests/dstress/ifeq__.c</path>
|
||||
<path>tests/dstress/return__.c</path>
|
||||
<path>e2ir.c</path>
|
||||
<path>tango-llvmdc</path>
|
||||
<path>tango-llvmdc/lib</path>
|
||||
<path>tango-llvmdc/lib/common</path>
|
||||
<path>tango-llvmdc/lib/common/tango</path>
|
||||
<path>tango-llvmdc/lib/common/tango/stdc</path>
|
||||
<path>tango-llvmdc/lib/common/tango/stdc/wrap.c</path>
|
||||
<path>tango-llvmdc/lib/compiler</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/complex.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/critical.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/deh.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/mars.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/dmd/monitor.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/gen_config1.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/gen_math.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/gen_unix.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/config/makestruct.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/critical.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/deh.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/aix_float.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_fdset.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_math.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_stdio.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/gcc/cbridge_time.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/mars.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/memory_dyld.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/memory_freebsd.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/gdc/monitor.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc/critical.c</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc/mars.h</path>
|
||||
<path>tango-llvmdc/lib/compiler/llvmdc/monitor.c</path>
|
||||
<path>tango-llvmdc/patches</path>
|
||||
<path>tango-llvmdc/patches/proposals</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/dmd</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/dmd/monitor.c</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc</path>
|
||||
<path>tango-llvmdc/patches/proposals/integrated_locks/lib/compiler/gdc/monitor.c</path>
|
||||
</blacklist>
|
||||
<build>
|
||||
<buildtool>make</buildtool>
|
||||
|
|
11
runtime/README
Normal file
11
runtime/README
Normal file
|
@ -0,0 +1,11 @@
|
|||
1) Do a checkout of tango trunk in the llvmdc root dir (along dmd, gen, runtime etc).
|
||||
|
||||
* svn co http://svn.dsource.org/projects/tango/trunk ../tango
|
||||
|
||||
2) Patch the runtime
|
||||
|
||||
* sh patch-tango.sh
|
||||
|
||||
3) Compile the runtime
|
||||
|
||||
* sh build.sh
|
17
runtime/build.sh
Executable file
17
runtime/build.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
# I'm no good bash scripter ...
|
||||
|
||||
# copy imports
|
||||
cp -u internal/llvmdc/bitmanip.d ../import/llvmdc/bitmanip.di
|
||||
cp -u internal/llvmdc/vararg.d ../import/llvmdc/vararg.di
|
||||
|
||||
# make the runtime
|
||||
cp -Ru lib ../tango
|
||||
cd ../tango/lib
|
||||
make -f llvmdc-posix.mak clean
|
||||
make -f llvmdc-posix.mak
|
||||
|
||||
# install the runtime
|
||||
rm -f ../../lib/libtango-base-llvmdc-native.a
|
||||
cp -s `pwd`/libtango-base-llvmdc-native.a ../../lib
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000-2007 by Digital Mars, www.digitalmars.com
|
||||
* Copyright (C) 2000-2008 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
|
@ -54,12 +54,13 @@ private
|
|||
|
||||
static size_t[] prime_list = [
|
||||
97UL, 389UL,
|
||||
1543UL, 6151UL,
|
||||
24593UL, 98317UL,
|
||||
393241UL, 1572869UL,
|
||||
6291469UL, 25165843UL,
|
||||
100663319UL, 402653189UL,
|
||||
1610612741UL, 4294967291UL
|
||||
1_543UL, 6_151UL,
|
||||
24_593UL, 98_317UL,
|
||||
393_241UL, 1_572_869UL,
|
||||
6_291_469UL, 25_165_843UL,
|
||||
100_663_319UL, 402_653_189UL,
|
||||
1_610_612_741UL, 4_294_967_291UL,
|
||||
// 8_589_934_513UL, 17_179_869_143UL
|
||||
];
|
||||
|
||||
// This is the type of the return value for dynamic arrays.
|
||||
|
@ -82,6 +83,7 @@ struct BB
|
|||
{
|
||||
aaA*[] b;
|
||||
size_t nodes; // total number of aaA nodes
|
||||
TypeInfo keyti; // TODO: replace this with TypeInfo_AssociativeArray when available in _aaGet()
|
||||
}
|
||||
|
||||
/* This is the type actually seen by the programmer, although
|
||||
|
@ -248,6 +250,7 @@ body
|
|||
if (!*aa_arg)
|
||||
*aa_arg = new BB();
|
||||
auto aa = *aa_arg;
|
||||
aa.keyti = keyti;
|
||||
|
||||
if (!aa.b.length)
|
||||
{
|
||||
|
@ -277,11 +280,7 @@ body
|
|||
// Not found, create new elem
|
||||
//printf("create new one\n");
|
||||
size_t size = aaA.sizeof + keysize + valuesize;
|
||||
uint bits = keysize < (void*).sizeof &&
|
||||
keysize > (void).sizeof &&
|
||||
valuesize < (void*).sizeof &&
|
||||
valuesize > (void).sizeof ? BlkAttr.NO_SCAN : 0;
|
||||
e = cast(aaA *) gc_calloc(size, bits);
|
||||
e = cast(aaA *) gc_calloc(size);
|
||||
memcpy(e + 1, pkey, keysize);
|
||||
e.hash = key_hash;
|
||||
*pe = e;
|
||||
|
@ -434,8 +433,8 @@ void _aaDel(AA aa, TypeInfo keyti, void *pkey)
|
|||
}
|
||||
|
||||
aa.nodes--;
|
||||
gc_free(e);
|
||||
|
||||
// Should notify GC that e can be free'd now
|
||||
break;
|
||||
}
|
||||
pe = (c < 0) ? &e.left : &e.right;
|
||||
|
@ -484,8 +483,7 @@ body
|
|||
{
|
||||
a.length = _aaLen(aa);
|
||||
a.ptr = cast(byte*) gc_malloc(a.length * valuesize,
|
||||
valuesize < (void*).sizeof &&
|
||||
valuesize > (void).sizeof ? BlkAttr.NO_SCAN : 0);
|
||||
valuesize < (void*).sizeof ? BlkAttr.NO_SCAN : 0);
|
||||
resi = 0;
|
||||
foreach (e; aa.b)
|
||||
{
|
||||
|
@ -575,6 +573,7 @@ body
|
|||
}
|
||||
len = prime_list[i];
|
||||
newb.b = new aaA*[len];
|
||||
newb.keyti = keyti;
|
||||
|
||||
foreach (e; aa.b)
|
||||
{
|
||||
|
@ -621,8 +620,7 @@ Array _aaKeys(AA aa, size_t keysize)
|
|||
if (!len)
|
||||
return Array();
|
||||
res = (cast(byte*) gc_malloc(len * keysize,
|
||||
keysize < (void*).sizeof &&
|
||||
keysize > (void).sizeof ? BlkAttr.NO_SCAN : 0))[0 .. len * keysize];
|
||||
!(aa.keyti.flags() & 1) ? BlkAttr.NO_SCAN : 0)) [0 .. len * keysize];
|
||||
resi = 0;
|
||||
foreach (e; aa.b)
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
private import llvm.intrinsic;
|
||||
private import llvmdc.intrinsics;
|
||||
|
||||
extern(C):
|
||||
|
|
@ -91,9 +91,11 @@ void _d_criticalInit()
|
|||
_STI_critical_init();
|
||||
}
|
||||
|
||||
alias void delegate( Exception ) ExceptionHandler;
|
||||
|
||||
// this is here so users can manually initialize the runtime
|
||||
// for example, when there is no main function etc.
|
||||
extern (C) bool rt_init( void delegate( Exception ) dg = null )
|
||||
extern (C) bool rt_init( ExceptionHandler dg = null )
|
||||
{
|
||||
_d_criticalInit();
|
||||
|
||||
|
@ -124,7 +126,7 @@ void _d_criticalTerm()
|
|||
|
||||
// this is here so users can manually terminate the runtime
|
||||
// for example, when there is no main function etc.
|
||||
extern (C) bool rt_term( void delegate( Exception ) dg = null )
|
||||
extern (C) bool rt_term( ExceptionHandler dg = null )
|
||||
{
|
||||
try
|
||||
{
|
|
@ -79,6 +79,9 @@ private
|
|||
{
|
||||
PAGESIZE = 4096
|
||||
}
|
||||
|
||||
alias bool function(Object) CollectHandler;
|
||||
CollectHandler collectHandler = null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -435,6 +438,18 @@ extern (C) void _d_delmemory(void* p)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
extern (C) void _d_callinterfacefinalizer(void *p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
Interface *pi = **cast(Interface ***)p;
|
||||
Object o = cast(Object)(p - pi.offset);
|
||||
rt_finalize(cast(void*)o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -445,6 +460,14 @@ extern (C) void _d_callfinalizer(void* p)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
extern (C) void rt_setCollectHandler(CollectHandler h)
|
||||
{
|
||||
collectHandler = h;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -462,7 +485,7 @@ extern (C) void rt_finalize(void* p, bool det = true)
|
|||
|
||||
try
|
||||
{
|
||||
if (det || onCollectResource(cast(Object)p))
|
||||
if (det || collectHandler is null || collectHandler(cast(Object)p))
|
||||
{
|
||||
do
|
||||
{
|
|
@ -74,7 +74,7 @@ OBJ_BASE= \
|
|||
aApply.bc \
|
||||
aApplyR.bc \
|
||||
adi.bc \
|
||||
arrays.bc \
|
||||
arrayInit.bc \
|
||||
cast.bc \
|
||||
dmain2.bc \
|
||||
eh.bc \
|
||||
|
@ -90,6 +90,10 @@ OBJ_UTIL= \
|
|||
util/string.bc \
|
||||
util/utf.bc
|
||||
|
||||
OBJ_LLVMDC= \
|
||||
llvmdc/bitmanip.bc \
|
||||
llvmdc/vararg.bc
|
||||
|
||||
OBJ_TI= \
|
||||
typeinfo/ti_AC.bc \
|
||||
typeinfo/ti_Acdouble.bc \
|
||||
|
@ -130,7 +134,8 @@ OBJ_TI= \
|
|||
ALL_OBJS= \
|
||||
$(OBJ_BASE) \
|
||||
$(OBJ_UTIL) \
|
||||
$(OBJ_TI)
|
||||
$(OBJ_TI) \
|
||||
$(OBJ_LLVMDC)
|
||||
|
||||
######################################################
|
||||
|
81
runtime/internal/llvmdc/bitmanip.d
Normal file
81
runtime/internal/llvmdc/bitmanip.d
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* D phobos intrinsics for LLVMDC
|
||||
*
|
||||
* From GDC ... public domain!
|
||||
*/
|
||||
module llvmdc.bitmanip;
|
||||
|
||||
// Check for the right compiler
|
||||
version(LLVMDC)
|
||||
{
|
||||
// OK
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "This module is only valid for LLVMDC");
|
||||
}
|
||||
|
||||
int bsf(uint v)
|
||||
{
|
||||
uint m = 1;
|
||||
uint i;
|
||||
for (i = 0; i < 32; i++,m<<=1) {
|
||||
if (v&m)
|
||||
return i;
|
||||
}
|
||||
return i; // supposed to be undefined
|
||||
}
|
||||
|
||||
int bsr(uint v)
|
||||
{
|
||||
uint m = 0x80000000;
|
||||
uint i;
|
||||
for (i = 32; i ; i--,m>>>=1) {
|
||||
if (v&m)
|
||||
return i-1;
|
||||
}
|
||||
return i; // supposed to be undefined
|
||||
}
|
||||
|
||||
int bt(uint *p, uint bitnum)
|
||||
{
|
||||
return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
|
||||
}
|
||||
|
||||
int btc(uint *p, uint bitnum)
|
||||
{
|
||||
uint * q = p + (bitnum / (uint.sizeof*8));
|
||||
uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
|
||||
int result = *q & mask;
|
||||
*q ^= mask;
|
||||
return result ? -1 : 0;
|
||||
}
|
||||
|
||||
int btr(uint *p, uint bitnum)
|
||||
{
|
||||
uint * q = p + (bitnum / (uint.sizeof*8));
|
||||
uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
|
||||
int result = *q & mask;
|
||||
*q &= ~mask;
|
||||
return result ? -1 : 0;
|
||||
}
|
||||
|
||||
int bts(uint *p, uint bitnum)
|
||||
{
|
||||
uint * q = p + (bitnum / (uint.sizeof*8));
|
||||
uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
|
||||
int result = *q & mask;
|
||||
*q |= mask;
|
||||
return result ? -1 : 0;
|
||||
}
|
||||
|
||||
pragma(intrinsic, "llvm.bswap.i32")
|
||||
uint bswap(uint val);
|
||||
|
||||
ubyte inp(uint p) { return 0; }
|
||||
ushort inpw(uint p) { return 0; }
|
||||
uint inpl(uint p) { return 0; }
|
||||
|
||||
ubyte outp(uint p, ubyte v) { return v; }
|
||||
ushort outpw(uint p, ushort v) { return v; }
|
||||
uint outpl(uint p, uint v) { return v; }
|
43
runtime/internal/llvmdc/vararg.d
Normal file
43
runtime/internal/llvmdc/vararg.d
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This module holds the implementation of special vararg templates for D style var args.
|
||||
*
|
||||
* Provides the functions tango.core.Vararg expects to be present!
|
||||
*/
|
||||
|
||||
module llvmdc.Vararg;
|
||||
|
||||
// Check for the right compiler
|
||||
version(LLVMDC)
|
||||
{
|
||||
// OK
|
||||
}
|
||||
else
|
||||
{
|
||||
static assert(false, "This module is only valid for LLVMDC");
|
||||
}
|
||||
|
||||
alias void* va_list;
|
||||
|
||||
void va_start(T) ( out va_list ap, inout T parmn )
|
||||
{
|
||||
// not needed !
|
||||
}
|
||||
|
||||
T va_arg(T)(ref va_list vp)
|
||||
{
|
||||
T* arg = cast(T*) vp;
|
||||
// llvmdc always aligns to size_t.sizeof in vararg lists
|
||||
vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
|
||||
return *arg;
|
||||
}
|
||||
|
||||
void va_end( va_list ap )
|
||||
{
|
||||
// not needed !
|
||||
}
|
||||
|
||||
void va_copy( out va_list dst, va_list src )
|
||||
{
|
||||
// seems pretty useless !
|
||||
dst = src;
|
||||
}
|
|
@ -72,6 +72,7 @@ typedef struct Exception
|
|||
|
||||
size_t line;
|
||||
|
||||
struct Interface *info;
|
||||
struct Exception *next;
|
||||
} Exception;
|
||||
|
|
@ -43,7 +43,7 @@ private
|
|||
}
|
||||
version(LLVMDC)
|
||||
{
|
||||
pragma(LLVM_internal, "intrinsic", "llvm.frameaddress")
|
||||
pragma(intrinsic, "llvm.frameaddress")
|
||||
{
|
||||
void* llvm_frameaddress(uint level=0);
|
||||
}
|
|
@ -31,6 +31,7 @@
|
|||
typedef struct Monitor
|
||||
{
|
||||
void* impl; // for user-level monitors
|
||||
Array devt; // for internal monitors
|
||||
|
||||
#if _WIN32
|
||||
CRITICAL_SECTION mon;
|
|
@ -30,8 +30,7 @@ class TypeInfo_C : TypeInfo
|
|||
hash_t getHash(void *p)
|
||||
{
|
||||
Object o = *cast(Object*)p;
|
||||
assert(o);
|
||||
return o.toHash();
|
||||
return o ? o.toHash() : 0;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
|
@ -18,7 +18,7 @@ LIB_NAME_NATIVE=libtango-base-llvmdc-native
|
|||
LIB_TARGET_NATIVE=$(LIB_NAME_NATIVE).a
|
||||
|
||||
DIR_CC=./common/tango
|
||||
DIR_RT=./compiler/llvmdc
|
||||
DIR_RT=../../runtime/internal
|
||||
DIR_GC=./gc/basic
|
||||
#DIR_GC=./gc/stub
|
||||
|
||||
|
@ -34,7 +34,8 @@ LLVMLINK=llvm-link
|
|||
LLC=llc
|
||||
|
||||
ADD_CFLAGS=
|
||||
ADD_DFLAGS=
|
||||
#ADD_DFLAGS=
|
||||
ADD_DFLAGS=-I`pwd`/common -I`pwd`/.. -I`pwd`/compiler/llvmdc
|
||||
|
||||
targets : nativelib doc
|
||||
all : nativelib lib doc
|
672
runtime/llvmdc.diff
Normal file
672
runtime/llvmdc.diff
Normal file
|
@ -0,0 +1,672 @@
|
|||
Index: object.di
|
||||
===================================================================
|
||||
--- object.di (revision 3819)
|
||||
+++ object.di (working copy)
|
||||
@@ -150,6 +150,9 @@
|
||||
void function() dtor;
|
||||
void function() unitTest;
|
||||
|
||||
+ void* xgetMembers;
|
||||
+ void function() ictor;
|
||||
+
|
||||
static int opApply( int delegate( inout ModuleInfo ) );
|
||||
}
|
||||
|
||||
Index: lib/common/tango/core/BitManip.d
|
||||
===================================================================
|
||||
--- lib/common/tango/core/BitManip.d (revision 3819)
|
||||
+++ lib/common/tango/core/BitManip.d (working copy)
|
||||
@@ -171,6 +171,10 @@
|
||||
*/
|
||||
uint outpl( uint port_address, uint value );
|
||||
}
|
||||
+else version( LLVMDC )
|
||||
+{
|
||||
+ public import llvmdc.bitmanip;
|
||||
+}
|
||||
else
|
||||
{
|
||||
public import std.intrinsic;
|
||||
Index: lib/common/tango/core/Thread.d
|
||||
===================================================================
|
||||
--- lib/common/tango/core/Thread.d (revision 3819)
|
||||
+++ lib/common/tango/core/Thread.d (working copy)
|
||||
@@ -244,10 +244,33 @@
|
||||
}
|
||||
body
|
||||
{
|
||||
- version( D_InlineAsm_X86 )
|
||||
+ version( LLVMDC )
|
||||
{
|
||||
+ // put registers on the stack
|
||||
+ version(D_InlineAsm_X86)
|
||||
+ {
|
||||
+ uint _eax, _ecx, _edx, _ebx, _esp, _ebp, _esi, _edi;
|
||||
asm
|
||||
{
|
||||
+ mov _eax, EAX;
|
||||
+ mov _ecx, ECX;
|
||||
+ mov _edx, EDX;
|
||||
+ mov _ebx, EBX;
|
||||
+ mov _esp, ESP;
|
||||
+ mov _ebp, EBP;
|
||||
+ mov _esi, ESI;
|
||||
+ mov _edi, EDI;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // FIXME
|
||||
+ }
|
||||
+ }
|
||||
+ else version( D_InlineAsm_X86 )
|
||||
+ {
|
||||
+ asm
|
||||
+ {
|
||||
pushad;
|
||||
}
|
||||
}
|
||||
@@ -297,8 +320,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
- version( D_InlineAsm_X86 )
|
||||
+ version( LLVMDC )
|
||||
{
|
||||
+ // nothing to do
|
||||
+ }
|
||||
+ else version( D_InlineAsm_X86 )
|
||||
+ {
|
||||
asm
|
||||
{
|
||||
popad;
|
||||
@@ -2266,8 +2293,12 @@
|
||||
|
||||
private
|
||||
{
|
||||
- version( D_InlineAsm_X86 )
|
||||
+ version( LLVMDC )
|
||||
{
|
||||
+
|
||||
+ }
|
||||
+ else version( D_InlineAsm_X86 )
|
||||
+ {
|
||||
version( X86_64 )
|
||||
{
|
||||
|
||||
Index: lib/gc/basic/gcx.d
|
||||
===================================================================
|
||||
--- lib/gc/basic/gcx.d (revision 3819)
|
||||
+++ lib/gc/basic/gcx.d (working copy)
|
||||
@@ -2178,6 +2178,28 @@
|
||||
__builtin_unwind_init();
|
||||
sp = & sp;
|
||||
}
|
||||
+ else version(LLVMDC)
|
||||
+ {
|
||||
+ version(D_InlineAsm_X86)
|
||||
+ {
|
||||
+ uint _eax, _ecx, _edx, _ebx, _ebp, _esi, _edi;
|
||||
+ asm
|
||||
+ {
|
||||
+ mov _eax, EAX;
|
||||
+ mov _ecx, ECX;
|
||||
+ mov _edx, EDX;
|
||||
+ mov _ebx, EBX;
|
||||
+ mov _ebp, EBP;
|
||||
+ mov _esi, ESI;
|
||||
+ mov _edi, EDI;
|
||||
+ mov sp, ESP;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // FIXME
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
{
|
||||
asm
|
||||
@@ -2191,6 +2213,10 @@
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
+ else version(LLVMDC)
|
||||
+ {
|
||||
+ // nothing to do
|
||||
+ }
|
||||
else
|
||||
{
|
||||
asm
|
||||
Index: lib/gc/basic/gcbits.d
|
||||
===================================================================
|
||||
--- lib/gc/basic/gcbits.d (revision 3819)
|
||||
+++ lib/gc/basic/gcbits.d (working copy)
|
||||
@@ -39,6 +39,10 @@
|
||||
{
|
||||
// use the unoptimized version
|
||||
}
|
||||
+else version(LLVMDC)
|
||||
+{
|
||||
+ // ditto
|
||||
+}
|
||||
else version (D_InlineAsm_X86)
|
||||
{
|
||||
version = Asm86;
|
||||
Index: tango/text/convert/Layout.d
|
||||
===================================================================
|
||||
--- tango/text/convert/Layout.d (revision 3819)
|
||||
+++ tango/text/convert/Layout.d (working copy)
|
||||
@@ -47,6 +47,12 @@
|
||||
alias void* Arg;
|
||||
alias va_list ArgList;
|
||||
}
|
||||
+else version(LLVMDC)
|
||||
+ {
|
||||
+ private import tango.core.Vararg;
|
||||
+ alias void* Arg;
|
||||
+ alias va_list ArgList;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
alias void* Arg;
|
||||
@@ -197,9 +203,18 @@
|
||||
assert (formatStr, "null format specifier");
|
||||
assert (arguments.length < 64, "too many args in Layout.convert");
|
||||
|
||||
- version (GNU)
|
||||
+ version (LLVMDC)
|
||||
{
|
||||
Arg[64] arglist = void;
|
||||
+ foreach (i, arg; arguments)
|
||||
+ {
|
||||
+ arglist[i] = args;
|
||||
+ args += (arg.tsize + size_t.sizeof - 1) & ~ (size_t.sizeof - 1);
|
||||
+ }
|
||||
+ }
|
||||
+ else version (GNU)
|
||||
+ {
|
||||
+ Arg[64] arglist = void;
|
||||
int[64] intargs = void;
|
||||
byte[64] byteargs = void;
|
||||
long[64] longargs = void;
|
||||
Index: tango/core/Vararg.d
|
||||
===================================================================
|
||||
--- tango/core/Vararg.d (revision 3819)
|
||||
+++ tango/core/Vararg.d (working copy)
|
||||
@@ -15,6 +15,10 @@
|
||||
{
|
||||
public import std.stdarg;
|
||||
}
|
||||
+else version( LLVMDC )
|
||||
+{
|
||||
+ public import llvmdc.vararg;
|
||||
+}
|
||||
else
|
||||
{
|
||||
/**
|
||||
Index: tango/math/Math.d
|
||||
===================================================================
|
||||
--- tango/math/Math.d (revision 3819)
|
||||
+++ tango/math/Math.d (working copy)
|
||||
@@ -76,7 +76,77 @@
|
||||
version = DigitalMars_D_InlineAsm_X86;
|
||||
}
|
||||
}
|
||||
+else version(LLVMDC)
|
||||
+{
|
||||
+ private
|
||||
+ {
|
||||
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f32")
|
||||
+ float llvm_sqrt(float);
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f64")
|
||||
+ double llvm_sqrt(double);
|
||||
+
|
||||
+ version(LLVM_X86_FP80)
|
||||
+ {
|
||||
+ alias tango.stdc.math.tanl llvm_tan;
|
||||
+ alias tango.stdc.math.acosl llvm_acos;
|
||||
+ alias tango.stdc.math.asinl llvm_asin;
|
||||
+ alias tango.stdc.math.atanl llvm_atan;
|
||||
+ alias tango.stdc.math.atan2l llvm_atan2;
|
||||
+ alias tango.stdc.math.coshl llvm_cosh;
|
||||
+ alias tango.stdc.math.sinhl llvm_sinh;
|
||||
+ alias tango.stdc.math.tanhl llvm_tanh;
|
||||
+ alias tango.stdc.math.cbrtl llvm_cbrt;
|
||||
+ alias tango.stdc.math.expl llvm_exp;
|
||||
+ alias tango.stdc.math.exp1ml llvm_exp1m;
|
||||
+ alias tango.stdc.math.exp2l llvm_exp2;
|
||||
+ alias tango.stdc.math.logl llvm_log;
|
||||
+ alias tango.stdc.math.log1pl llvm_log1p;
|
||||
+ alias tango.stdc.math.log2l llvm_log2;
|
||||
+ alias tango.stdc.math.log10l llvm_log10;
|
||||
+ alias tango.stdc.math.powl llvm_pow;
|
||||
+ alias tango.stdc.math.lrintl llvm_lrint;
|
||||
+ alias tango.stdc.math.llrintl llvm_llrint;
|
||||
+
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.cos.f80")
|
||||
+ real llvm_cos(real);
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.sin.f80")
|
||||
+ real llvm_sin(real);
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f80")
|
||||
+ real llvm_sqrt(real);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ alias tango.stdc.math.tan llvm_tan;
|
||||
+ alias tango.stdc.math.acos llvm_acos;
|
||||
+ alias tango.stdc.math.asin llvm_asin;
|
||||
+ alias tango.stdc.math.atan llvm_atan;
|
||||
+ alias tango.stdc.math.atan2 llvm_atan2;
|
||||
+ alias tango.stdc.math.cosh llvm_cosh;
|
||||
+ alias tango.stdc.math.sinh llvm_sinh;
|
||||
+ alias tango.stdc.math.tanh llvm_tanh;
|
||||
+ alias tango.stdc.math.cbrt llvm_cbrt;
|
||||
+ alias tango.stdc.math.exp llvm_exp;
|
||||
+ alias tango.stdc.math.exp1m llvm_exp1m;
|
||||
+ alias tango.stdc.math.exp2 llvm_exp2;
|
||||
+ alias tango.stdc.math.log llvm_log;
|
||||
+ alias tango.stdc.math.log1p llvm_log1p;
|
||||
+ alias tango.stdc.math.log2 llvm_log2;
|
||||
+ alias tango.stdc.math.log10 llvm_log10;
|
||||
+ alias tango.stdc.math.pow llvm_pow;
|
||||
+ alias tango.stdc.math.lrint llvm_lrint;
|
||||
+ alias tango.stdc.math.llrint llvm_llrint;
|
||||
+
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.cos.f64")
|
||||
+ real llvm_cos(real);
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.sin.f64")
|
||||
+ real llvm_sin(real);
|
||||
+ pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f64")
|
||||
+ real llvm_sqrt(real);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
@@ -300,6 +370,10 @@
|
||||
*/
|
||||
real cos(real x) /* intrinsic */
|
||||
{
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_cos(x);
|
||||
+ }
|
||||
version(D_InlineAsm_X86)
|
||||
{
|
||||
asm
|
||||
@@ -335,6 +409,10 @@
|
||||
*/
|
||||
real sin(real x) /* intrinsic */
|
||||
{
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_sin(x);
|
||||
+ }
|
||||
version(D_InlineAsm_X86)
|
||||
{
|
||||
asm
|
||||
@@ -374,6 +452,9 @@
|
||||
{
|
||||
version (GNU) {
|
||||
return tanl(x);
|
||||
+ }
|
||||
+ else version(LLVMDC) {
|
||||
+ return llvm_tan(x);
|
||||
} else {
|
||||
asm
|
||||
{
|
||||
@@ -576,7 +657,14 @@
|
||||
*/
|
||||
real acos(real x)
|
||||
{
|
||||
- return tango.stdc.math.acosl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_acos(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.acosl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -599,7 +687,14 @@
|
||||
*/
|
||||
real asin(real x)
|
||||
{
|
||||
- return tango.stdc.math.asinl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_asin(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.asinl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -621,7 +716,14 @@
|
||||
*/
|
||||
real atan(real x)
|
||||
{
|
||||
- return tango.stdc.math.atanl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_atan(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.atanl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -658,7 +760,14 @@
|
||||
*/
|
||||
real atan2(real y, real x)
|
||||
{
|
||||
- return tango.stdc.math.atan2l(y,x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_atan2(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.atan2l(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -707,7 +816,14 @@
|
||||
*/
|
||||
real cosh(real x)
|
||||
{
|
||||
- return tango.stdc.math.coshl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_cosh(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.coshl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -728,7 +844,14 @@
|
||||
*/
|
||||
real sinh(real x)
|
||||
{
|
||||
- return tango.stdc.math.sinhl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_sinh(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.sinhl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -749,7 +872,14 @@
|
||||
*/
|
||||
real tanh(real x)
|
||||
{
|
||||
- return tango.stdc.math.tanhl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_tanh(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.tanhl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -949,8 +1079,12 @@
|
||||
*/
|
||||
float sqrt(float x) /* intrinsic */
|
||||
{
|
||||
- version(D_InlineAsm_X86)
|
||||
+ version(LLVMDC)
|
||||
{
|
||||
+ return llvm_sqrt_f32(x);
|
||||
+ }
|
||||
+ else version(D_InlineAsm_X86)
|
||||
+ {
|
||||
asm
|
||||
{
|
||||
fld x;
|
||||
@@ -965,8 +1099,12 @@
|
||||
|
||||
double sqrt(double x) /* intrinsic */ /// ditto
|
||||
{
|
||||
- version(D_InlineAsm_X86)
|
||||
+ version(LLVMDC)
|
||||
{
|
||||
+ return llvm_sqrt_f64(x);
|
||||
+ }
|
||||
+ else version(D_InlineAsm_X86)
|
||||
+ {
|
||||
asm
|
||||
{
|
||||
fld x;
|
||||
@@ -981,8 +1119,12 @@
|
||||
|
||||
real sqrt(real x) /* intrinsic */ /// ditto
|
||||
{
|
||||
- version(D_InlineAsm_X86)
|
||||
+ version(LLVMDC)
|
||||
{
|
||||
+ return llvm_sqrt_f80(x);
|
||||
+ }
|
||||
+ else version(D_InlineAsm_X86)
|
||||
+ {
|
||||
asm
|
||||
{
|
||||
fld x;
|
||||
@@ -1045,7 +1187,14 @@
|
||||
*/
|
||||
real cbrt(real x)
|
||||
{
|
||||
- return tango.stdc.math.cbrtl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_cbrt(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.cbrtl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -1067,7 +1216,14 @@
|
||||
*/
|
||||
real exp(real x)
|
||||
{
|
||||
- return tango.stdc.math.expl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_exp(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.expl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1093,7 +1249,14 @@
|
||||
*/
|
||||
real expm1(real x)
|
||||
{
|
||||
- return tango.stdc.math.expm1l(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_expm1(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.expm1l(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1115,7 +1278,14 @@
|
||||
*/
|
||||
real exp2(real x)
|
||||
{
|
||||
- return tango.stdc.math.exp2l(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_exp2(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.exp2l(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1141,7 +1311,14 @@
|
||||
*/
|
||||
real log(real x)
|
||||
{
|
||||
- return tango.stdc.math.logl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_log(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.logl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1167,7 +1344,14 @@
|
||||
*/
|
||||
real log1p(real x)
|
||||
{
|
||||
- return tango.stdc.math.log1pl(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_log1p(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.log1pl(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1190,7 +1374,14 @@
|
||||
*/
|
||||
real log2(real x)
|
||||
{
|
||||
- return tango.stdc.math.log2l(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_log2(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.log2l(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1212,7 +1403,14 @@
|
||||
*/
|
||||
real log10(real x)
|
||||
{
|
||||
- return tango.stdc.math.log10l(x);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_log10(x);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.log10l(x);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1477,7 +1675,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
- return tango.stdc.math.powl(x, y);
|
||||
+ version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_pow(x, y);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ return tango.stdc.math.powl(x, y);
|
||||
+ }
|
||||
}
|
||||
|
||||
debug(UnitTest) {
|
||||
@@ -1823,6 +2028,10 @@
|
||||
}
|
||||
return n;
|
||||
}
|
||||
+ else version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_lrint(x);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
return tango.stdc.math.lrintl(x);
|
||||
@@ -1842,6 +2051,10 @@
|
||||
}
|
||||
return n;
|
||||
}
|
||||
+ else version(LLVMDC)
|
||||
+ {
|
||||
+ return llvm_llrint(x);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
return tango.stdc.math.llrintl(x);
|
||||
Index: tango/stdc/stdlib.d
|
||||
===================================================================
|
||||
--- tango/stdc/stdlib.d (revision 3819)
|
||||
+++ tango/stdc/stdlib.d (working copy)
|
||||
@@ -94,6 +94,11 @@
|
||||
{
|
||||
void* alloca(size_t size);
|
||||
}
|
||||
+else version( LLVMDC )
|
||||
+{
|
||||
+ pragma(alloca)
|
||||
+ void* alloca(size_t size);
|
||||
+}
|
||||
else version( GNU )
|
||||
{
|
||||
private import gcc.builtins;
|
||||
Index: tango/stdc/stdarg.d
|
||||
===================================================================
|
||||
--- tango/stdc/stdarg.d (revision 3819)
|
||||
+++ tango/stdc/stdarg.d (working copy)
|
||||
@@ -13,6 +13,10 @@
|
||||
{
|
||||
public import std.c.stdarg;
|
||||
}
|
||||
+else version( LLVMDC )
|
||||
+{
|
||||
+ public import llvmdc.cstdarg;
|
||||
+}
|
||||
else
|
||||
{
|
||||
alias void* va_list;
|
4
runtime/patch-tango.sh
Executable file
4
runtime/patch-tango.sh
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd ../tango
|
||||
patch -p0 < ../runtime/llvmdc.diff
|
|
@ -1,24 +0,0 @@
|
|||
Tango is Open Source software, distributed by a group of developers which has been set up for the purpose of providing a vendor-neutral owner of Tango intellectual property. The goals of all Tango licensing decisions are to:
|
||||
|
||||
* Encourage adoption
|
||||
* Discourage political contention
|
||||
* Encourage collaboration and integration with other projects
|
||||
* Be transparent
|
||||
|
||||
Tango is dual-licensed:
|
||||
* Academic Free License v2.1 (http://opensource.org/licenses/afl-2.1.php)
|
||||
* BSD License (http://opensource.org/licenses/bsd-license.php) [1]
|
||||
|
||||
The preferred license is the Academic Free License v2.1. All Tango projects release their code under the terms of this license. Both licenses:
|
||||
|
||||
* Allow commercial use without encumbrance
|
||||
* Provide broad rights to make new products and derivative works
|
||||
* Place no requirement on users to contribute back (although we appreciate it if you do)
|
||||
|
||||
Users who wish to include Tango with software licensed under the (L)GPL will want to use Tango under the terms of the BSD License. [1] Tango projects may request a variance from the developers to release their projects under additional licenses in conjunction with the AFL.
|
||||
|
||||
If you have further questions regarding Tango licensing, please do not hesitate to contact us (http://dsource.org/projects/tango/wiki/Contact).
|
||||
|
||||
|
||||
[1] The advertising clause has not been a part of the BSD License since July 22, 1999. (ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change)
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
For a guide to install Tango see the online installation reference:
|
||||
|
||||
http://dsource.org/projects/tango/wiki/TopicInstallTango
|
||||
|
||||
The license can be found at
|
||||
|
||||
http://dsource.org/projects/tango/wiki/LibraryLicense
|
|
@ -1,10 +0,0 @@
|
|||
This version of Tango is modified to work with LLVMDC
|
||||
by Tomas Lindquist Olsen, 2008
|
||||
|
||||
Much has been removed as this is not intended to work with other compilers.
|
||||
Hopefully in time, this will go away and the required changes merged into the
|
||||
mainline Tango repository.
|
||||
|
||||
For more information on LLVMDC, check the site at:
|
||||
|
||||
http://www.dsource.org/projects/llvmdc
|
|
@ -1,83 +0,0 @@
|
|||
name = tango
|
||||
|
||||
[tango/core]
|
||||
postinstall=install tango/core/BitManip.di $INCLUDE_PREFIX/tango/core ; \
|
||||
install tango/core/Exception.di $INCLUDE_PREFIX/tango/core ; \
|
||||
install tango/core/Memory.di $INCLUDE_PREFIX/tango/core ; \
|
||||
install tango/core/Runtime.di $INCLUDE_PREFIX/tango/core ; \
|
||||
install tango/core/Thread.di $INCLUDE_PREFIX/tango/core
|
||||
version (GNU) {
|
||||
prebuild = $DSSS_BUILD -obj -explicit lib/common/tango/core/BitManip.d -fintfc-file=tango/core/BitManip.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Exception.d -fintfc-file=tango/core/Exception.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Memory.d -fintfc-file=tango/core/Memory.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Runtime.d -fintfc-file=tango/core/Runtime.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Thread.d -fintfc-file=tango/core/Thread.di ;
|
||||
} else version (DigitalMars) {
|
||||
prebuild = $DSSS_BUILD -obj -explicit lib/common/tango/core/BitManip.d -Hftango/core/BitManip.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Exception.d -Hftango/core/Exception.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Memory.d -Hftango/core/Memory.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Runtime.d -Hftango/core/Runtime.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Thread.d -Hftango/core/Thread.di ;
|
||||
}
|
||||
else version (LLVMDC) {
|
||||
prebuild = $DSSS_BUILD -obj -explicit lib/common/tango/core/BitManip.d -Hftango/core/BitManip.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Exception.d -Hftango/core/Exception.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Memory.d -Hftango/core/Memory.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Runtime.d -Hftango/core/Runtime.di ; \
|
||||
$DSSS_BUILD -obj -explicit lib/common/tango/core/Thread.d -Hftango/core/Thread.di ;
|
||||
}
|
||||
|
||||
version(LLVMDC) {
|
||||
[tango/stdc]
|
||||
} else {
|
||||
|
||||
[tango/io]
|
||||
|
||||
[tango/math]
|
||||
|
||||
[tango/net]
|
||||
|
||||
[tango/stdc]
|
||||
version (Windows) {
|
||||
exclude = tango/stdc/posix
|
||||
}
|
||||
|
||||
[tango/sys]
|
||||
exclude = tango/sys/linux/* tango/sys/darwin/* tango/sys/win32/*
|
||||
exclude += tango/sys/TimeConverter.d
|
||||
|
||||
version (linux) {
|
||||
[tango/sys/linux]
|
||||
}
|
||||
|
||||
version (darwin) {
|
||||
[tango/sys/darwin]
|
||||
}
|
||||
|
||||
version (Windows) {
|
||||
[+tango/sys/win32]
|
||||
preinstall = install tango/sys/win32/Macros.di $INCLUDE_PREFIX/tango/sys/win32 ; \
|
||||
install tango/sys/win32/Process.di $INCLUDE_PREFIX/tango/sys/win32 ; \
|
||||
install tango/sys/win32/Types.di $INCLUDE_PREFIX/tango/sys/win32 ; \
|
||||
install tango/sys/win32/UserGdi.di $INCLUDE_PREFIX/tango/sys/win32
|
||||
}
|
||||
|
||||
[tango/text]
|
||||
|
||||
[tango/text/locale]
|
||||
version (!linux) {
|
||||
exclude += tango/text/locale/Linux.d
|
||||
}
|
||||
version (!Windows) {
|
||||
exclude += tango/text/locale/Win32.d
|
||||
}
|
||||
|
||||
[tango/util]
|
||||
|
||||
[tango/time]
|
||||
|
||||
[tango/group]
|
||||
|
||||
[+std]
|
||||
preinstall = installdir std $INCLUDE_PREFIX/std
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
public import tango.net.cluster.NetworkCall;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
a Task function
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
real add (real x, real y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
a Task function
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
int divide (int x, int y)
|
||||
{
|
||||
return x / y;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
a verbose Task message
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
class Subtract : NetworkCall
|
||||
{
|
||||
double a,
|
||||
b,
|
||||
result;
|
||||
|
||||
double opCall (double a, double b, IChannel channel = null)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
send (channel);
|
||||
return result;
|
||||
}
|
||||
|
||||
override void execute ()
|
||||
{
|
||||
result = a - b;
|
||||
}
|
||||
|
||||
override void read (IReader input) {input (a)(b)(result);}
|
||||
|
||||
override void write (IWriter output) {output (a)(b)(result);}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
private import tango.core.Thread;
|
||||
|
||||
private import tango.util.log.Configurator;
|
||||
|
||||
private import tango.net.cluster.NetworkAlert;
|
||||
|
||||
private import tango.net.cluster.tina.Cluster;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
How to send and recieve Alert messages using tango.net.cluster
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main()
|
||||
{
|
||||
// hook into the cluster
|
||||
auto cluster = (new Cluster).join;
|
||||
|
||||
// hook into the Alert layer
|
||||
auto alert = new NetworkAlert (cluster, "my.kind.of.alert");
|
||||
|
||||
// listen for the broadcast (on this channel)
|
||||
alert.createConsumer (delegate void (IEvent event)
|
||||
{event.log.info ("Recieved alert on channel " ~ event.channel.name);}
|
||||
);
|
||||
|
||||
// say what's going on
|
||||
alert.log.info ("broadcasting alert");
|
||||
|
||||
// and send everyone an empty alert (on this channel)
|
||||
alert.broadcast;
|
||||
|
||||
// wait for it to arrive ...
|
||||
Thread.sleep(1);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import tango.io.Stdout;
|
||||
|
||||
import tango.time.StopWatch;
|
||||
|
||||
import tango.util.log.Configurator;
|
||||
|
||||
import tango.net.cluster.NetworkCache;
|
||||
|
||||
import tango.net.cluster.tina.Cluster;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
StopWatch w;
|
||||
|
||||
if (args.length > 1)
|
||||
{
|
||||
auto cluster = (new Cluster).join (args[1..$]);
|
||||
auto cache = new NetworkCache (cluster, "my.cache.channel");
|
||||
|
||||
while (true)
|
||||
{
|
||||
w.start;
|
||||
for (int i=10000; i--;)
|
||||
cache.put ("key", cache.EmptyMessage);
|
||||
|
||||
Stdout.formatln ("{} put/s", 10000/w.stop);
|
||||
|
||||
w.start;
|
||||
for (int i=10000; i--;)
|
||||
cache.get ("key");
|
||||
|
||||
Stdout.formatln ("{} get/s", 10000/w.stop);
|
||||
}
|
||||
}
|
||||
else
|
||||
Stdout.formatln ("usage: cache cachehost:port ...");
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import tango.io.Console;
|
||||
|
||||
import tango.net.InternetAddress;
|
||||
|
||||
import tango.net.cluster.tina.CmdParser,
|
||||
tango.net.cluster.tina.CacheServer;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
auto arg = new CmdParser ("cache.server");
|
||||
|
||||
// default number of cache entries
|
||||
arg.size = 8192;
|
||||
|
||||
if (args.length > 1)
|
||||
arg.parse (args[1..$]);
|
||||
|
||||
if (arg.help)
|
||||
Cout ("usage: cacheserver -port=number -size=cachesize -log[=trace, info, warn, error, fatal, none]").newline;
|
||||
else
|
||||
(new CacheServer(new InternetAddress(arg.port), arg.log, arg.size)).start;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
private import tango.core.Thread;
|
||||
|
||||
private import tango.util.log.Configurator;
|
||||
|
||||
private import tango.net.cluster.tina.Cluster;
|
||||
|
||||
private import tango.net.cluster.QueuedCache,
|
||||
tango.net.cluster.CacheInvalidatee,
|
||||
tango.net.cluster.CacheInvalidator;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Demonstrates how to invalidate cache entries across a cluster
|
||||
via a channel
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main()
|
||||
{
|
||||
// access the cluster
|
||||
auto cluster = (new Cluster).join;
|
||||
|
||||
// wrap a cache instance with a network listener
|
||||
auto dst = new CacheInvalidatee (cluster, "my.cache.channel", new QueuedCache!(char[], IMessage)(101));
|
||||
|
||||
// connect an invalidator to that cache channel
|
||||
auto src = new CacheInvalidator (cluster, "my.cache.channel");
|
||||
|
||||
// stuff something in the local cache
|
||||
dst.cache.put ("key", dst.EmptyMessage);
|
||||
|
||||
// get it removed via a network broadcast
|
||||
src.log.info ("invalidating 'key' across the cluster");
|
||||
src.invalidate ("key");
|
||||
|
||||
// wait for it to arrive ...
|
||||
Thread.sleep (1);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import tango.io.Stdout;
|
||||
|
||||
import tango.time.StopWatch;
|
||||
|
||||
import tango.util.log.Configurator;
|
||||
|
||||
import tango.net.cluster.NetworkQueue;
|
||||
|
||||
import tango.net.cluster.tina.Cluster;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
StopWatch w;
|
||||
|
||||
auto cluster = (new Cluster).join;
|
||||
auto queue = new NetworkQueue (cluster, "my.queue.channel");
|
||||
|
||||
while (true)
|
||||
{
|
||||
w.start;
|
||||
for (int i=10000; i--;)
|
||||
queue.put (queue.EmptyMessage);
|
||||
|
||||
Stdout.formatln ("{} put/s", 10000/w.stop);
|
||||
|
||||
uint count;
|
||||
w.start;
|
||||
while (queue.get !is null)
|
||||
++count;
|
||||
|
||||
Stdout.formatln ("{} get/s", count/w.stop);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
private import tango.core.Thread;
|
||||
|
||||
private import tango.util.log.Configurator;
|
||||
|
||||
private import tango.net.cluster.NetworkQueue;
|
||||
|
||||
private import tango.net.cluster.tina.Cluster;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Illustrates how to setup and use a Queue in asynchronous mode
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main ()
|
||||
{
|
||||
void listen (IEvent event)
|
||||
{
|
||||
while (event.get)
|
||||
event.log.info ("received asynch msg on channel " ~ event.channel.name);
|
||||
}
|
||||
|
||||
|
||||
// join the cluster
|
||||
auto cluster = (new Cluster).join;
|
||||
|
||||
// access a queue of the specified name
|
||||
auto queue = new NetworkQueue (cluster, "my.queue.channel");
|
||||
|
||||
// listen for messages placed in my queue, via a delegate
|
||||
queue.createConsumer (&listen);
|
||||
|
||||
// stuff something into the queue
|
||||
queue.log.info ("sending three messages to the queue");
|
||||
queue.put (queue.EmptyMessage);
|
||||
queue.put (queue.EmptyMessage);
|
||||
queue.put (queue.EmptyMessage);
|
||||
|
||||
// wait for asynchronous msgs to arrive ...
|
||||
Thread.sleep (1);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
private import tango.util.log.Configurator;
|
||||
|
||||
private import tango.net.cluster.NetworkQueue;
|
||||
|
||||
private import tango.net.cluster.tina.Cluster;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Illustrates how to setup and use a Queue in synchronous mode
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main ()
|
||||
{
|
||||
// join the cluster
|
||||
auto cluster = (new Cluster).join;
|
||||
|
||||
// access a queue of the specified name
|
||||
auto queue = new NetworkQueue (cluster, "my.queue.channel");
|
||||
|
||||
// stuff something into the queue
|
||||
queue.log.info ("sending three messages to the queue");
|
||||
queue.put (queue.EmptyMessage);
|
||||
queue.put (queue.EmptyMessage);
|
||||
queue.put (queue.EmptyMessage);
|
||||
|
||||
// retreive synchronously
|
||||
while (queue.get)
|
||||
queue.log.info ("retrieved msg");
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import tango.io.Console;
|
||||
|
||||
import tango.net.InternetAddress;
|
||||
|
||||
import tango.net.cluster.tina.CmdParser,
|
||||
tango.net.cluster.tina.QueueServer;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
auto arg = new CmdParser ("queue.server");
|
||||
|
||||
if (args.length > 1)
|
||||
arg.parse (args[1..$]);
|
||||
|
||||
if (arg.help)
|
||||
Cout ("usage: queueserver -port=number -log[=trace, info, warn, error, fatal, none]").newline;
|
||||
else
|
||||
(new QueueServer(new InternetAddress(arg.port), arg.log)).start;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
private import tango.core.Thread;
|
||||
|
||||
private import tango.util.log.Configurator;
|
||||
|
||||
private import tango.net.cluster.tina.Cluster;
|
||||
|
||||
private import tango.net.cluster.NetworkQueue;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main()
|
||||
{
|
||||
// open the cluster and a queue channel. Note that the queue has
|
||||
// been configured with a reply listener ...
|
||||
auto cluster = (new Cluster).join;
|
||||
auto queue = new NetworkQueue (cluster, "message.channel",
|
||||
(IEvent event){event.log.info ("Received reply");}
|
||||
);
|
||||
|
||||
void recipient (IEvent event)
|
||||
{
|
||||
auto msg = event.get;
|
||||
|
||||
event.log.info ("Replying to message on channel "~msg.reply);
|
||||
event.reply (event.replyChannel(msg), queue.EmptyMessage);
|
||||
}
|
||||
|
||||
// setup a listener to recieve and reply
|
||||
queue.createConsumer (&recipient);
|
||||
|
||||
// toss a message out to the cluster
|
||||
queue.put (queue.EmptyMessage);
|
||||
|
||||
// wait for completion ...
|
||||
Thread.sleep (1);
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Illustrates usage of cluster tasks
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import Add, tango.io.Stdout, tango.net.cluster.tina.ClusterTask;
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
scope add = new NetCall!(add);
|
||||
|
||||
Stdout.formatln ("cluster expression of 3.0 + 4.0 = {}", add(3, 4));
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import Add;
|
||||
|
||||
import tango.io.Stdout;
|
||||
|
||||
import tango.time.StopWatch;
|
||||
|
||||
import tango.util.log.Configurator;
|
||||
|
||||
import tango.net.cluster.tina.ClusterTask;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
// an implicit task instance
|
||||
auto add = new NetCall!(add);
|
||||
|
||||
// an explicit task instance
|
||||
auto sub = new Subtract;
|
||||
|
||||
StopWatch w;
|
||||
while (true)
|
||||
{
|
||||
w.start;
|
||||
for (int i=10000; i--;)
|
||||
{
|
||||
// both task types are used in the same manner
|
||||
add (1, 2);
|
||||
sub (3, 4);
|
||||
}
|
||||
Stdout.formatln ("{} calls/s", 20000/w.stop);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
import tango.io.Console;
|
||||
|
||||
import tango.net.InternetAddress;
|
||||
|
||||
import tango.net.cluster.tina.CmdParser,
|
||||
tango.net.cluster.tina.TaskServer;
|
||||
|
||||
import Add;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
void main (char[][] args)
|
||||
{
|
||||
auto arg = new CmdParser ("task.server");
|
||||
|
||||
if (args.length > 1)
|
||||
arg.parse (args[1..$]);
|
||||
|
||||
if (arg.help)
|
||||
Cout ("usage: taskserver -port=number -log[=trace, info, warn, error, fatal, none]").newline;
|
||||
else
|
||||
{
|
||||
auto server = new TaskServer (new InternetAddress(arg.port), arg.log);
|
||||
server.enroll (new NetCall!(add));
|
||||
server.enroll (new Subtract);
|
||||
server.start;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue