diff --git a/runtime/internal/dmdintrinsic.d b/runtime/internal/dmdintrinsic.d
new file mode 100644
index 00000000..d9609a8a
--- /dev/null
+++ b/runtime/internal/dmdintrinsic.d
@@ -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 --git a/runtime/internal/llvmdc.mak b/runtime/internal/llvmdc.mak index ba0b0c0b..8a545f9f 100644 --- a/runtime/internal/llvmdc.mak +++ b/runtime/internal/llvmdc.mak @@ -88,6 +88,7 @@ OBJ_BASE= \ qsort2.bc \ switch.bc \ invariant.bc \ + dmdintrinsic.bc \ OBJ_UTIL= \ util/console.bc \