[svn r200] Fixed: removed use of std.intrinsic.

Fixed: module info could potentially be masked by a previous reference, resulting in linking failure.
This commit is contained in:
Tomas Lindquist Olsen
2008-05-07 22:01:59 +02:00
parent 3678dabfd9
commit fa30c42921
10 changed files with 164 additions and 276 deletions

View File

@@ -189,6 +189,7 @@ static llvm::Function* build_module_ctor()
std::vector<const llvm::Type*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
assert(gIR->module->getFunction(name) == NULL);
llvm::Function* fn = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
fn->setCallingConv(llvm::CallingConv::Fast);
@@ -222,6 +223,7 @@ static llvm::Function* build_module_dtor()
std::vector<const llvm::Type*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
assert(gIR->module->getFunction(name) == NULL);
llvm::Function* fn = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
fn->setCallingConv(llvm::CallingConv::Fast);
@@ -255,6 +257,7 @@ static llvm::Function* build_module_unittest()
std::vector<const llvm::Type*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
assert(gIR->module->getFunction(name) == NULL);
llvm::Function* fn = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
fn->setCallingConv(llvm::CallingConv::Fast);
@@ -383,6 +386,7 @@ void Module::genmoduleinfo()
std::string m_name("_D");
m_name.append(mangle());
m_name.append("9__classesZ");
assert(gIR->module->getGlobalVariable(m_name) == NULL);
llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(classArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module);
c = llvm::ConstantExpr::getBitCast(m_gvar, getPtrToType(classArrTy->getElementType()));
c = DtoConstSlice(DtoConstSize_t(classInits.size()), c);
@@ -438,7 +442,10 @@ void Module::genmoduleinfo()
// declare
// flags will be modified at runtime so can't make it constant
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, constMI, MIname, gIR->module);
llvm::GlobalVariable* gvar = gIR->module->getGlobalVariable(MIname);
if (!gvar) gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module);
gvar->setInitializer(constMI);
// declare the appending array
const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(llvm::Type::Int8Ty), 1);

View File

@@ -8,6 +8,7 @@ exeext=
objext=bc
version=LLVM
version=LLVMDC
noversion=DigitalMars
noversion=GNU

View File

@@ -171,6 +171,75 @@ version( DDoc )
*/
uint outpl( uint port_address, uint value );
}
else version( LLVMDC )
{
// From GDC ... public domain!
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(LLVM_internal, "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; }
}
else
{
public import std.intrinsic;

View File

@@ -1,265 +0,0 @@
// written by Walter Bright
// www.digitalmars.com
// Placed into the public domain
/* NOTE: This file has been patched from the original DMD distribution to
work with the GDC compiler.
NOTE: This file has been patched from the original GDC distribution to
work with the LLVMDC compiler.
Modified by David Friedman, May 2006
Modified by Tomas Lindquist Olsen, August 2007
*/
/** These functions are built-in intrinsics to the compiler.
*
Intrinsic functions are functions built in to the compiler,
usually to take advantage of specific CPU features that
are inefficient to handle via external functions.
The compiler's optimizer and code generator are fully
integrated in with intrinsic functions, bringing to bear
their full power on them.
This can result in some surprising speedups.
* Macros:
* WIKI=Phobos/StdIntrinsic
*/
module std.intrinsic;
/**
* Scans the bits in v starting with bit 0, looking
* for the first set bit.
* Returns:
* The bit number of the first bit set.
* The return value is undefined if v is zero.
*/
version (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
}
else
int bsf(uint v);
/**
* Scans the bits in v from the most significant bit
* to the least significant bit, looking
* for the first set bit.
* Returns:
* The bit number of the first bit set.
* The return value is undefined if v is zero.
* Example:
* ---
* import std.intrinsic;
*
* int main()
* {
* uint v;
* int x;
*
* v = 0x21;
* x = bsf(v);
* printf("bsf(x%x) = %d\n", v, x);
* x = bsr(v);
* printf("bsr(x%x) = %d\n", v, x);
* return 0;
* }
* ---
* Output:
* bsf(x21) = 0<br>
* bsr(x21) = 5
*/
version (LLVMDC)
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
}
else
int bsr(uint v);
/**
* Tests the bit.
*/
version (LLVMDC)
int bt(uint *p, uint bitnum)
{
return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
}
else
int bt(uint *p, uint bitnum);
/**
* Tests and complements the bit.
*/
version (LLVMDC)
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;
}
else
int btc(uint *p, uint bitnum);
/**
* Tests and resets (sets to 0) the bit.
*/
version (LLVMDC)
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;
}
else
int btr(uint *p, uint bitnum);
/**
* Tests and sets the bit.
* Params:
* p = a non-NULL pointer to an array of uints.
* index = a bit number, starting with bit 0 of p[0],
* and progressing. It addresses bits like the expression:
---
p[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1)))
---
* Returns:
* A non-zero value if the bit was set, and a zero
* if it was clear.
*
* Example:
* ---
import std.intrinsic;
int main()
{
uint array[2];
array[0] = 2;
array[1] = 0x100;
printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("bts(array, 35) = %d\n", <b>bts</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("btr(array, 35) = %d\n", <b>btr</b>(array, 35));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
printf("bt(array, 1) = %d\n", <b>bt</b>(array, 1));
printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
return 0;
}
* ---
* Output:
<pre>
btc(array, 35) = 0
array = [0]:x2, [1]:x108
btc(array, 35) = -1
array = [0]:x2, [1]:x100
bts(array, 35) = 0
array = [0]:x2, [1]:x108
btr(array, 35) = -1
array = [0]:x2, [1]:x100
bt(array, 1) = -1
array = [0]:x2, [1]:x100
</pre>
*/
version (LLVMDC)
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;
}
else
int bts(uint *p, uint bitnum);
/**
* Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes
byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3
becomes byte 0.
*/
version (LLVMDC)
pragma(LLVM_internal, "intrinsic", "llvm.bswap.i32")
uint bswap(uint val);
else
uint bswap(uint v);
/**
* Reads I/O port at port_address.
*/
version (LLVMDC)
ubyte inp(uint p) { return 0; }
else
ubyte inp(uint port_address);
/**
* ditto
*/
version (LLVMDC)
ushort inpw(uint p) { return 0; }
else
ushort inpw(uint port_address);
/**
* ditto
*/
version (LLVMDC)
uint inpl(uint p) { return 0; }
else
uint inpl(uint port_address);
/**
* Writes and returns value to I/O port at port_address.
*/
version (LLVM)
ubyte outp(uint p, ubyte v) { return v; }
else
ubyte outp(uint port_address, ubyte value);
/**
* ditto
*/
version (LLVM)
ushort outpw(uint p, ushort v) { return v; }
else
ushort outpw(uint port_address, ushort value);
/**
* ditto
*/
version (LLVM)
uint outpl(uint p, uint v) { return v; }
else
uint outpl(uint port_address, uint value);

View File

@@ -13,6 +13,11 @@
*/
module std.intrinsic;
// LLVMDC doesn't use this module!
version( LLVMDC )
{
static assert(0, "LLVMDC does not support the std.intrinsic module with Tango");
}
/**
* Scans the bits in v starting with bit 0, looking

View File

@@ -17,12 +17,76 @@ version (DDoc)
uint outpl(uint port_address, uint value);
}
else
{
version (LLVMDC)
{
int bsf(uint v);
int bsr(uint v);
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(LLVM_internal, "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;
}
}
else
{
public
{
import std.intrinsic;
}
}
}
int popcnt(uint x)
{
x = x - (x >> 1 & 1431655765);

View File

@@ -2,8 +2,8 @@
module tango.core.Exception;
private
{
alias void(* assertHandlerType)(char[] file, size_t line, char[] msg = null);
alias TracedExceptionInfo(* traceHandlerType)(void* ptr = null);
alias void function(char[] file, size_t line, char[] msg = null) assertHandlerType;
alias TracedExceptionInfo function(void* ptr = null) traceHandlerType;
assertHandlerType assertHandler = null;
traceHandlerType traceHandler = null;
}
@@ -247,6 +247,13 @@ void setTraceHandler(traceHandlerType h)
{
traceHandler = h;
}
private
{
extern (C)
{
int printf(char*,...);
}
}
extern (C)
{
void onAssertError(char[] file, size_t line);

View File

@@ -88,7 +88,7 @@ private
{
void gc_removeRange(void* p);
}
alias bool(* collectHandlerType)(Object obj);
alias bool function(Object obj) collectHandlerType;
}
struct GC
{

View File

@@ -6,7 +6,7 @@ private
{
bool rt_isHalting();
}
alias bool(* moduleUnitTesterType)();
alias bool function() moduleUnitTesterType;
}
struct Runtime
{

View File

@@ -33,7 +33,7 @@ version (Win32)
}
extern (Windows)
{
alias uint(* btex_fptr)(void*);
alias uint function(void*) btex_fptr;
}
extern (C)
{
@@ -102,7 +102,7 @@ else
}
class Thread
{
this(void(* fn)(), size_t sz = 0)
this(void function() fn, size_t sz = 0)
in
{
assert(fn);
@@ -267,7 +267,7 @@ else
char[] m_name;
union
{
void(* m_fn)();
void function() m_fn;
void delegate() m_dg;
}
size_t m_sz;
@@ -481,7 +481,7 @@ class ThreadGroup
{
final
{
Thread create(void(* fn)());
Thread create(void function() fn);
}
final
{
@@ -594,7 +594,7 @@ else
}
class Fiber
{
this(void(* fn)(), size_t sz = PAGESIZE)
this(void function() fn, size_t sz = PAGESIZE)
in
{
assert(fn);
@@ -686,7 +686,7 @@ DG,
Call m_call;
union
{
void(* m_fn)();
void function() m_fn;
void delegate() m_dg;
}
bool m_isRunning;