changeset 606:c7fbcb6b923e

Add implementations for dmd intrinsics. Fixes #92.
author Christian Kamm <kamm incasoftware de>
date Wed, 17 Sep 2008 19:54:37 +0200
parents e235b80c92bc
children 9526b29ae342
files runtime/internal/dmdintrinsic.d runtime/internal/llvmdc.mak
diffstat 2 files changed, 232 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /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<br>
+ *  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", <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>
+ */
+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
--- 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 \