# HG changeset patch # User Christian Kamm # Date 1221674077 -7200 # Node ID c7fbcb6b923e94ee7b02f835ffb76a1c321d7b3b # Parent e235b80c92bc92fede2b7763a6112c1ece5aeb94 Add implementations for dmd intrinsics. Fixes #92. diff -r e235b80c92bc -r c7fbcb6b923e runtime/internal/dmdintrinsic.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/internal/dmdintrinsic.d Wed Sep 17 19:54:37 2008 +0200 @@ -0,0 +1,231 @@ + + +// 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. + + Modified by David Friedman, May 2006 + Modified by Christian Kamm, Sep 2008 +*/ + +/** 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. + */ +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 +} + +/** + * 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
+ * bsr(x21) = 5 + */ +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 +} + +/** + * Tests the bit. + */ +int bt(uint *p, uint bitnum) +{ + return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ; +} + +/** + * Tests and complements the bit. + */ +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; +} + +/** + * Tests and resets (sets to 0) the bit. + */ +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; +} + +/** + * 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", btc(array, 35)); + printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); + + printf("btc(array, 35) = %d\n", btc(array, 35)); + printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); + + printf("bts(array, 35) = %d\n", bts(array, 35)); + printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); + + printf("btr(array, 35) = %d\n", btr(array, 35)); + printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); + + printf("bt(array, 1) = %d\n", bt(array, 1)); + printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); + + return 0; +} + * --- + * Output: +
+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
+
+ */ +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; +} + + +/** + * 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. + */ +uint bswap(uint v) +{ + return ((v&0xFF)<<24)|((v&0xFF00)<<8)|((v&0xFF0000)>>>8)|((v&0xFF000000)>>>24); +} + + +// +// Unimplemented functions +// +/+ + +/** + * Reads I/O port at port_address. + */ +ubyte inp(uint port_address); + +/** + * ditto + */ +ushort inpw(uint port_address); + +/** + * ditto + */ +uint inpl(uint port_address); + + +/** + * Writes and returns value to I/O port at port_address. + */ +ubyte outp(uint port_address, ubyte value); + +/** + * ditto + */ +ushort outpw(uint port_address, ushort value); + +/** + * ditto + */ +uint outpl(uint port_address, uint value); + ++/ \ No newline at end of file diff -r e235b80c92bc -r c7fbcb6b923e runtime/internal/llvmdc.mak --- a/runtime/internal/llvmdc.mak Tue Sep 16 16:06:39 2008 +0200 +++ b/runtime/internal/llvmdc.mak Wed Sep 17 19:54:37 2008 +0200 @@ -88,6 +88,7 @@ qsort2.bc \ switch.bc \ invariant.bc \ + dmdintrinsic.bc \ OBJ_UTIL= \ util/console.bc \