--- /home/urxae/opt/gdc/include/d/4.1.1/std/intrinsic.d	2007-03-06 05:27:06.000000000 +0100
+++ intrinsic.d	2007-05-14 20:17:32.000000000 +0200
@@ -8,6 +8,7 @@
    work with the GDC compiler.
 
    Modified by David Friedman, May 2006
+   Modified by Frits van Bommel, May 2007 (added x86 and x86_64 asm versions)
 */
 
 /** These functions are built-in intrinsics to the compiler.
@@ -24,7 +25,50 @@
  */
 
 module std.intrinsic;
-
+
+version (GNU) {
+    // The asm functions work for both x86 and x86_64, so introduce a common version
+    version (X86)       { version = X86_32_or_64; }
+    version (X86_64)    { version = X86_32_or_64; }
+    
+    // Some helper functions for similar functions:
+    version (X86_32_or_64) {    
+        private template gen_bs_variant(char[] suffix) {
+            const gen_bs_variant = `
+                int bs` ~ suffix ~ `(uint v) {
+                    int retval = void;
+                    asm {"bs` ~ suffix ~ ` %[val], %[result]"
+                        :
+                        [result] "=r" retval
+                        :
+                        [val] "rm" v
+                        ;
+                    }
+                    return retval;
+                }
+                `;
+        }
+        private template gen_bt_variant(char[] suffix, bool locked) {
+            const gen_bt_variant = `
+                bool ` ~ (locked ? "locked_" : "") ~ `bt` ~ suffix ~ `(uint* p, uint bit) {
+                    bool retval = void;
+                    asm {"` ~ (locked ? "lock " : "") ~ `
+                        bt` ~ suffix ~ ` %[bit], (%[addr])
+                        setc %[result]
+                        "
+                        :
+                        [result] "=g" retval
+                        :
+                        [addr] "p" p,
+                        [bit] "rI" bit
+                        ;
+                    }
+                    return retval;
+                }
+                `;
+        }
+    }
+}
 /**
  * Scans the bits in v starting with bit 0, looking
  * for the first set bit.
@@ -33,6 +77,7 @@
  *	The return value is undefined if v is zero.
  */
 version (GNU)
+    version (X86_32_or_64) mixin(gen_bs_variant!("f")); else
     int bsf(uint v)
     {
 	uint m = 1;
@@ -75,6 +120,7 @@
  *  bsr(x21) = 5
  */
 version (GNU)
+    version (X86_32_or_64) mixin(gen_bs_variant!("r")); else
 int bsr(uint v)
 {
     uint m = 0x80000000;
@@ -87,11 +133,12 @@
 }
 else
     int bsr(uint v);
-
+
 /**
  * Tests the bit.
  */
 version (GNU)
+    version (X86_32_or_64) mixin(gen_bt_variant!("", false)); else
 int bt(uint *p, uint bitnum)
 {
     return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
@@ -103,6 +150,7 @@
  * Tests and complements the bit.
  */
 version (GNU)
+    version (X86_32_or_64) mixin(gen_bt_variant!("c", false)); else
 int btc(uint *p, uint bitnum)
 {
     uint * q = p + (bitnum / (uint.sizeof*8));
@@ -118,6 +166,7 @@
  * Tests and resets (sets to 0) the bit.
  */
 version (GNU)
+    version (X86_32_or_64) mixin(gen_bt_variant!("r", false)); else
 int btr(uint *p, uint bitnum)
 {
     uint * q = p + (bitnum / (uint.sizeof*8));
@@ -186,6 +235,7 @@
 </pre>
  */
 version (GNU)
+    version (X86_32_or_64) mixin(gen_bt_variant!("s", false)); else
 int bts(uint *p, uint bitnum)
 {
     uint * q = p + (bitnum / (uint.sizeof*8));
@@ -204,6 +254,13 @@
 	becomes byte 0.
  */
 version (GNU)
+    version (X86_32_or_64)
+        uint bswap(uint v) {
+            uint retval = void;
+            asm {"bswap %[val]" : [val] "=r" retval : "0" v; }
+            return retval;
+        }
+    else
 uint bswap(uint v)
 {
     return ((v&0xFF)<<24)|((v&0xFF00)<<8)|((v&0xFF0000)>>>8)|((v&0xFF000000)>>>24);
@@ -216,7 +273,14 @@
  * Reads I/O port at port_address.
  */
 version (GNU)
-    ubyte  inp(uint p) { return 0; }
+    version (X86_32_or_64)
+        ubyte inp(uint p) {
+            ubyte retval = void;
+            asm {"inb %[port], %[result]" : [result] "=a" retval : [port] "Nd" cast(ushort)p; }
+            return retval;
+        }
+    else
+ubyte  inp(uint p) { return 0; }
 else
     ubyte  inp(uint port_address);
 
@@ -224,6 +288,13 @@
  * ditto
  */
 version (GNU)
+    version (X86_32_or_64)
+        ushort inpw(uint p) {
+            ushort retval = void;
+            asm {"inw %[port], %[result]" : [result] "=a" retval : [port] "Nd" cast(ushort)p; }
+            return retval;
+        }
+    else
     ushort inpw(uint p) { return 0; }
 else
     ushort inpw(uint port_address);
@@ -232,6 +303,13 @@
  * ditto
  */
 version (GNU)
+    version (X86_32_or_64)
+        uint inpl(uint p) {
+            uint retval = void;
+            asm {"inl %[port], %[result]" : [result] "=a" retval : [port] "Nd" cast(ushort)p; }
+            return retval;
+        }
+    else
     uint   inpl(uint p) { return 0; }
 else
     uint   inpl(uint port_address);
@@ -241,6 +319,12 @@
  * Writes and returns value to I/O port at port_address.
  */
 version (GNU)
+    version (X86_32_or_64)
+        ubyte outp(uint p, ubyte v) {
+            asm {"outb %[val], %[port]" : : [port] "Nd" cast(ushort)p, [val] "a" v; }
+            return v;
+        }
+    else
     ubyte  outp(uint p, ubyte v) { return v; }
 else
     ubyte  outp(uint port_address, ubyte value);
@@ -249,6 +333,12 @@
  * ditto
  */
 version (GNU)
+    version (X86_32_or_64)
+        ushort outpw(uint p, ushort v) {
+            asm {"outw %[val], %[port]" : : [port] "Nd" cast(ushort)p, [val] "a" v; }
+            return v;
+        }
+    else
     ushort outpw(uint p, ushort v) { return v; }
 else
     ushort outpw(uint port_address, ushort value);
@@ -257,6 +347,12 @@
  * ditto
  */
 version (GNU)
+    version (X86_32_or_64)
+        uint outpl(uint p, uint v) {
+            asm {"outl %[val], %[port]" : : [port] "Nd" cast(ushort)p, [val] "a" v; }
+            return v;
+        }
+    else
     uint   outpl(uint p, uint v) { return v; }
 else
     uint   outpl(uint port_address, uint value);
