changeset 13837:ed3a1471e133

Add the Graal Native Function Interface
author Matthias Grimmer <grimmer@ssw.jku.at>
date Thu, 30 Jan 2014 09:19:45 +0100
parents 64c77f0577bb
children beb735d1e5c3
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/ArrayPointerTest.java graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/LibCallTest.java graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/MathLibCallTest.java graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/StdLibCallTest.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionHandle.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionInterface.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionPointer.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeLibraryHandle.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/node/AMD64RawNativeCallNode.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/InstallUtil.java graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/NativeCallStubGraphBuilder.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java mx/projects src/share/vm/graal/graalCompilerToVM.cpp
diffstat 27 files changed, 1498 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+/**
+ * The function handle of a native foreign function.
+ * 
+ */
+public interface NativeFunctionHandle {
+
+    /**
+     * Calls the native foreign function.
+     * 
+     * @param args the arguments that will be passed to the native foreign function
+     */
+    Object call(Object[] args);
+
+    /**
+     * Returns the installed code of the call stub for the native foreign function call.
+     * 
+     * @return the installed code of the native call stub
+     */
+    InstalledCode getCallStub();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+/**
+ * Interface to resolve pointers to native foreign functions.
+ * 
+ */
+public interface NativeFunctionInterface {
+
+    /**
+     * Resolves and returns a library handle.
+     * 
+     * @param libPath the absolute path to the library
+     * @return the resolved library handle
+     */
+    NativeLibraryHandle getLibraryHandle(String libPath);
+
+    /**
+     * Resolves the <code>NativeFunctionHandle</code> of a native function that can be called.
+     * 
+     * @param libraryHandle the handle to a resolved library
+     * @param functionName the name of the function to be resolved
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native foreign function
+     */
+    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle libraryHandle, String functionName, Class returnType, Class[] argumentTypes);
+
+    /**
+     * Resolves the <code>NativeFunctionHandle</code> of a native function that can be called.
+     * 
+     * @param functionPointer the function pointer
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native foreign function
+     */
+    NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes);
+
+    /**
+     * Resolves the function pointer <code>NativeFunctionPointer</code> of a native function.
+     * 
+     * @param libraryHandles the handles to a various resolved library, the first library containing
+     *            the method wins
+     * @param functionName the name of the function to be resolved
+     * @return the function handle of the native foreign function
+     */
+    NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraryHandles, String functionName);
+
+    /**
+     * Resolves the <code>NativeFunctionHandle</code> of a native function that can be called.
+     * 
+     * @param libraryHandles the handles to a various resolved library, the first library containing
+     *            the method wins
+     * @param functionName the name of the function to be resolved
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native foreign function
+     */
+    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraryHandles, String functionName, Class returnType, Class[] argumentTypes);
+
+    /**
+     * Resolves the <code>NativeFunctionHandle</code> of a native function that can be called.
+     * 
+     * @param functionName the name of the function to be resolved
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native foreign function
+     */
+    NativeFunctionHandle getFunctionHandle(String functionName, Class returnType, Class[] argumentTypes);
+
+    /**
+     * Creates <code>NativeFunctionPointer</code> from raw value.
+     * 
+     * @param rawValue Raw pointer value
+     * @return <code>NativeFunctionPointer</code> of the raw pointer
+     */
+    NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+public interface NativeFunctionPointer {
+
+    /**
+     * Returns whether the pointer is valid.
+     * 
+     * @return true if the pointer is valid
+     */
+    boolean isValid();
+
+    /**
+     * Returns function pointer as raw value.
+     * 
+     * @return raw value of function pointer
+     */
+    long asRawValue();
+
+    /**
+     * Returns the name of the function.
+     * 
+     * @return name of the function
+     */
+    String getFunctionName();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+/**
+ * The library handle of the native library.
+ */
+public interface NativeLibraryHandle {
+
+    /**
+     * Returns whether the handle is valid.
+     * 
+     * @return true if the handle is valid
+     */
+    boolean isValid();
+
+    /**
+     * Returns function pointer as raw value.
+     * 
+     * @return raw value of function pointer
+     */
+    long asRawValue();
+}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Jan 30 09:19:45 2014 +0100
@@ -899,6 +899,8 @@
         }
     }
 
+    public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments);
+
     @Override
     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
         long maxOffset = linkage.getMaxCallTargetOffset();
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Thu Jan 30 09:19:45 2014 +0100
@@ -63,6 +63,8 @@
         return providers.getCodeCache().getTarget();
     }
 
+    public abstract NativeFunctionInterface getNativeFunctionInterface();
+
     public abstract FrameMap newFrameMap();
 
     public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/ArrayPointerTest.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+
+public class ArrayPointerTest extends LibCallTest {
+
+    @Test
+    public void arrayPointerTest01() {
+        byte[] str = new byte[]{'A', 'B', 'C', '\0'};
+        NativeFunctionHandle handle = ffi.getFunctionHandle("puts", int.class, new Class[]{byte[].class});
+        Object[] args = new Object[]{str};
+        int result = (int) handle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/LibCallTest.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.test;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.runtime.*;
+
+public class LibCallTest {
+
+    protected static final Unsafe unsafe = getUnsafe();
+    public static final RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
+    public static final NativeFunctionInterface ffi = runtimeProvider.getHostBackend().getNativeFunctionInterface();
+
+    @Test
+    public void test() {
+        Long str = unsafe.allocateMemory(4);
+        unsafe.putByte(str, (byte) 'A');
+        unsafe.putByte(str + 1, (byte) 'B');
+        unsafe.putByte(str + 2, (byte) 'C');
+        unsafe.putByte(str + 3, (byte) '\0');
+        NativeFunctionHandle handle = ffi.getFunctionHandle("puts", int.class, new Class[]{long.class});
+        Object[] args = new Object[]{str};
+        int result = (int) handle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+
+    protected long getDouble(double val) {
+        Long d = unsafe.allocateMemory(8);
+        unsafe.putDouble(d, val);
+        return d;
+    }
+
+    protected long getLong(long val) {
+        Long d = unsafe.allocateMemory(8);
+        unsafe.putLong(d, val);
+        return d;
+    }
+
+    protected long getInt(int val) {
+        Long d = unsafe.allocateMemory(4);
+        unsafe.putInt(d, val);
+        return d;
+    }
+
+    protected void free(long p) {
+        unsafe.freeMemory(p);
+    }
+
+    private static Unsafe getUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/MathLibCallTest.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+
+public class MathLibCallTest extends LibCallTest {
+
+    static final Object[] args = new Object[]{Double.doubleToLongBits(3), Double.doubleToLongBits(5.5)};
+    static final NativeFunctionHandle handle = ffi.getFunctionHandle("pow", double.class, new Class[]{double.class, double.class});
+
+    @Test
+    public void powTest() {
+        double result = (double) handle.call(args);
+        Assert.assertEquals(Math.pow(3, 5.5), result, 0);
+    }
+
+    @Test
+    public void compilePowTest() {
+        double result = 0;
+        for (int i = 0; i < 100000; i++) {
+            result = callPow();
+        }
+        Assert.assertEquals(Math.pow(3, 5.5), result, 0);
+
+    }
+
+    private static double callPow() {
+        return (double) handle.call(args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/StdLibCallTest.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+
+public class StdLibCallTest extends LibCallTest {
+
+    @Test
+    public void mallocTest() {
+        Object[] args = new Object[]{6};
+        NativeFunctionHandle mallocHandle = ffi.getFunctionHandle("malloc", long.class, new Class[]{int.class});
+
+        long p = (long) mallocHandle.call(args);
+        unsafe.putByte(p, (byte) 'G');
+        unsafe.putByte(p + 1, (byte) 'R');
+        unsafe.putByte(p + 2, (byte) 'A');
+        unsafe.putByte(p + 3, (byte) 'A');
+        unsafe.putByte(p + 4, (byte) 'L');
+        unsafe.putByte(p + 5, (byte) '\0');
+
+        NativeFunctionHandle putsHandle = ffi.getFunctionHandle("puts", int.class, new Class[]{long.class});
+        Object[] args2 = new Object[]{p};
+        int result = (int) putsHandle.call(args2);
+        Assert.assertTrue(0 < result);
+        Assert.assertEquals(unsafe.getByte(p) & 0xFF, 'G');
+        Assert.assertEquals(unsafe.getByte(p + 1) & 0xFF, 'R');
+        Assert.assertEquals(unsafe.getByte(p + 2) & 0xFF, 'A');
+        Assert.assertEquals(unsafe.getByte(p + 3) & 0xFF, 'A');
+        Assert.assertEquals(unsafe.getByte(p + 4) & 0xFF, 'L');
+        Assert.assertEquals(unsafe.getByte(p + 5) & 0xFF, '\0');
+
+        NativeFunctionHandle freeHandle = ffi.getFunctionHandle("free", void.class, new Class[]{long.class});
+        freeHandle.call(args2);
+    }
+
+    @Test
+    public void printfSimpleTest() {
+        long str = unsafe.allocateMemory(8);
+        unsafe.putByte(str, (byte) 'A');
+        unsafe.putByte(str + 1, (byte) 'B');
+        unsafe.putByte(str + 2, (byte) ' ');
+        unsafe.putByte(str + 3, (byte) '%');
+        unsafe.putByte(str + 4, (byte) 'f');
+        unsafe.putByte(str + 5, (byte) '%');
+        unsafe.putByte(str + 6, (byte) 'f');
+        unsafe.putByte(str + 7, (byte) '\0');
+
+        Object[] args = new Object[]{str, Double.doubleToRawLongBits(1.0), Double.doubleToRawLongBits(1.0)};
+        NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new Class[]{long.class, double.class, double.class});
+
+        int result = (int) printfHandle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+
+    @Test
+    public void putsSimpleTest() {
+        long str = unsafe.allocateMemory(6);
+        unsafe.putByte(str, (byte) 'A');
+        unsafe.putByte(str + 1, (byte) 'B');
+        unsafe.putByte(str + 2, (byte) 'B');
+        unsafe.putByte(str + 3, (byte) 'B');
+        unsafe.putByte(str + 4, (byte) '\0');
+
+        Object[] args = new Object[]{str};
+        NativeFunctionHandle printfHandle = ffi.getFunctionHandle("puts", int.class, new Class[]{long.class});
+
+        int result = (int) printfHandle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+
+    @Test
+    public void printfTest() {
+        long str = unsafe.allocateMemory(25);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        unsafe.putByte(str + 24, (byte) '\0');
+
+        Object[] args = new Object[]{str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11]};
+        NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new Class[]{long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class});
+
+        int result = (int) printfHandle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+
+    @Test
+    public void printfTest2() {
+        long str = unsafe.allocateMemory(49);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        double[] dval = new double[12];
+        for (int i = 12; i < 24; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
+            dval[i - 12] = i + 0.5;
+        }
+        unsafe.putByte(str + 48, (byte) '\0');
+
+        Object[] args = new Object[]{str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2], dval[3], dval[4], dval[5],
+                        dval[6], dval[7], dval[8], dval[9], dval[10], dval[11]};
+
+        NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new Class[]{long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
+                        double.class, double.class, double.class});
+
+        int result = (int) printfHandle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+
+    @Test
+    public void printfTest3() {
+        long str = unsafe.allocateMemory(73);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        double[] dval = new double[12];
+        for (int i = 12; i < 24; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
+            dval[i - 12] = i + 0.5;
+        }
+        char[] cval = new char[12];
+        for (int i = 24; i < 36; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'c');
+            cval[i - 24] = (char) ('a' + (i - 24));
+        }
+        unsafe.putByte(str + 72, (byte) '\0');
+
+        Object[] args = new Object[]{str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2], dval[3], dval[4], dval[5],
+                        dval[6], dval[7], dval[8], dval[9], dval[10], dval[11], cval[0], cval[1], cval[2], cval[3], cval[4], cval[5], cval[6], cval[7], cval[8], cval[9], cval[10], cval[11]};
+
+        NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new Class[]{long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
+                        double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class,
+                        char.class});
+
+        int result = (int) printfHandle.call(args);
+        Assert.assertTrue(0 < result);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionHandle.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.ffi.amd64.util.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+
+public class AMD64NativeFunctionHandle implements NativeFunctionHandle {
+
+    private final InstalledCode code;
+    private final String functionName;
+
+    protected final HotSpotProviders providers;
+    protected final Backend backend;
+
+    public AMD64NativeFunctionHandle(HotSpotProviders providers, Backend backend, AMD64NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) {
+        this.providers = providers;
+        this.backend = backend;
+        this.functionName = functionPointer.getFunctionName();
+        StructuredGraph graph = NativeCallStubGraphBuilder.getGraph(providers, functionPointer, returnType, argumentTypes);
+        InstallUtil installer = new InstallUtil(providers, backend);
+        this.code = installer.install(graph);
+    }
+
+    @Override
+    public Object call(Object[] args) {
+        try {
+            return code.execute(args, null, null);
+        } catch (InvalidInstalledCodeException e) {
+            throw GraalInternalError.shouldNotReachHere("Execution of GNFI Callstub failed: " + functionName);
+        }
+    }
+
+    public InstalledCode getCallStub() {
+        return code;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionInterface.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64;
+
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.meta.*;
+
+public class AMD64NativeFunctionInterface implements NativeFunctionInterface {
+
+    private static final Class LOOKUP_FUNCTION_RETURNTYPE = long.class;
+    private static final Class[] LOOKUP_FUNCTION_SIGNATURE = new Class[]{long.class, long.class};
+
+    private static final Unsafe unsafe = getUnsafe();
+
+    private static final int STD_BUFFER_SIZE = 1024;
+
+    protected final HotSpotProviders providers;
+    protected final Backend backend;
+    protected final AMD64NativeLibraryHandle rtldDefault;
+    protected final AMD64NativeFunctionPointer libraryLoadFunctionPointer;
+    protected final AMD64NativeFunctionPointer functionLookupFunctionPointer;
+
+    public AMD64NativeFunctionInterface(HotSpotProviders providers, Backend backend, AMD64NativeFunctionPointer libraryLoadFunctionPointer, AMD64NativeFunctionPointer functionLookUpFunctionPointer,
+                    AMD64NativeLibraryHandle rtldDefault) {
+        this.rtldDefault = rtldDefault;
+        this.providers = providers;
+        this.backend = backend;
+        this.libraryLoadFunctionPointer = libraryLoadFunctionPointer;
+        this.functionLookupFunctionPointer = functionLookUpFunctionPointer;
+    }
+
+    @Override
+    public AMD64NativeLibraryHandle getLibraryHandle(String libPath) {
+        AMD64NativeFunctionHandle libraryLookupFunctionHandle = new AMD64NativeFunctionHandle(providers, backend, libraryLoadFunctionPointer, long.class,
+                        new Class[]{long.class, long.class, int.class});
+
+        long allocatedMemory = -1;
+        try {
+            allocatedMemory = unsafe.allocateMemory(STD_BUFFER_SIZE);
+        } catch (OutOfMemoryError e) {
+            throw new AssertionError();
+        }
+
+        Object[] args = new Object[]{copyStringToMemory(libPath), allocatedMemory, STD_BUFFER_SIZE};
+        long libraryHandle = (long) libraryLookupFunctionHandle.call(args);
+        unsafe.freeMemory(allocatedMemory);
+        return new AMD64NativeLibraryHandle(libraryHandle);
+    }
+
+    @Override
+    public AMD64NativeFunctionHandle getFunctionHandle(NativeLibraryHandle libraryHandle, String functionName, Class returnType, Class[] argumentTypes) {
+        AMD64NativeFunctionPointer functionPointer = lookupFunctionPointer(functionName, libraryHandle);
+        if (!functionPointer.isValid()) {
+            throw new IllegalStateException(functionName + " not found!");
+        }
+        return getFunctionHandle(functionPointer, returnType, argumentTypes);
+    }
+
+    @Override
+    public AMD64NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraryHandles, String functionName, Class returnType, Class[] argumentTypes) {
+        AMD64NativeFunctionPointer functionPointer = null;
+        for (NativeLibraryHandle libraryHandle : libraryHandles) {
+            functionPointer = lookupFunctionPointer(functionName, libraryHandle);
+            if (functionPointer.isValid()) {
+                return new AMD64NativeFunctionHandle(providers, backend, functionPointer, returnType, argumentTypes);
+            }
+        }
+        return getFunctionHandle(functionName, returnType, argumentTypes);
+    }
+
+    @Override
+    public AMD64NativeFunctionHandle getFunctionHandle(String functionName, Class returnType, Class[] argumentTypes) {
+        if (rtldDefault.asRawValue() == AMD64NativeLibraryHandle.INVALID_HANDLE) {
+            throw new AssertionError("No library provided or RTLD_DEFAULT not supported!");
+        }
+        return getFunctionHandle(rtldDefault, functionName, returnType, argumentTypes);
+    }
+
+    private AMD64NativeFunctionPointer lookupFunctionPointer(String functionName, NativeLibraryHandle handle) {
+
+        if (!functionLookupFunctionPointer.isValid()) {
+            throw new IllegalStateException("no dlsym function pointer");
+        }
+        AMD64NativeFunctionHandle dllLookupFunctionHandle = new AMD64NativeFunctionHandle(providers, backend, functionLookupFunctionPointer, LOOKUP_FUNCTION_RETURNTYPE, LOOKUP_FUNCTION_SIGNATURE);
+        long allocatedMemory = copyStringToMemory(functionName);
+        Object[] args = new Object[]{handle, allocatedMemory};
+        long functionPointer = (long) dllLookupFunctionHandle.call(args);
+        unsafe.freeMemory(allocatedMemory);
+        return new AMD64NativeFunctionPointer(functionPointer, functionName);
+    }
+
+    private static long copyStringToMemory(String str) {
+        int size = str.length();
+        long ptr = unsafe.allocateMemory(size + 1);
+        for (int i = 0; i < size; i++) {
+            unsafe.putByte(ptr + i, (byte) str.charAt(i));
+        }
+        unsafe.putByte(ptr + size, (byte) '\0');
+        return ptr;
+    }
+
+    private static Unsafe getUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (IllegalArgumentException | SecurityException | NoSuchFieldException | IllegalAccessException e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+
+    @Override
+    public AMD64NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) {
+        if (functionPointer instanceof AMD64NativeFunctionPointer) {
+            if (!((AMD64NativeFunctionPointer) functionPointer).isValid()) {
+                throw new IllegalStateException("Function Symbol not found");
+            }
+        } else {
+            throw new IllegalStateException("AMD64 function pointer required!");
+        }
+        return new AMD64NativeFunctionHandle(providers, backend, (AMD64NativeFunctionPointer) functionPointer, returnType, argumentTypes);
+    }
+
+    @Override
+    public AMD64NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraryHandles, String functionName) {
+        for (NativeLibraryHandle libraryHandle : libraryHandles) {
+            AMD64NativeFunctionPointer functionPointer = lookupFunctionPointer(functionName, libraryHandle);
+            if (functionPointer.isValid()) {
+                return functionPointer;
+            }
+        }
+        throw new LinkageError("Function not found: " + functionName);
+    }
+
+    @Override
+    public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) {
+        return new AMD64NativeFunctionPointer(rawValue, null);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionPointer.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64;
+
+import com.oracle.graal.api.code.*;
+
+public class AMD64NativeFunctionPointer implements NativeFunctionPointer {
+
+    private final long functionPointer;
+    private final String functionName;
+
+    public AMD64NativeFunctionPointer(long functionPointer, String functionName) {
+        this.functionPointer = functionPointer;
+        this.functionName = functionName;
+    }
+
+    public boolean isValid() {
+        return functionPointer != 0;
+    }
+
+    @Override
+    public long asRawValue() {
+        return functionPointer;
+    }
+
+    public String getFunctionName() {
+        return functionName;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeLibraryHandle.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64;
+
+import com.oracle.graal.api.code.*;
+
+public class AMD64NativeLibraryHandle implements NativeLibraryHandle {
+
+    private final long handle;
+    public static final long INVALID_HANDLE = 0xDEADFACE;
+
+    public AMD64NativeLibraryHandle(long handle) {
+        this.handle = handle;
+    }
+
+    public long asRawValue() {
+        return handle;
+    }
+
+    public boolean isValid() {
+        return handle != 0 && handle != INVALID_HANDLE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/node/AMD64RawNativeCallNode.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.node;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.amd64.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+public class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRGenLowerable {
+
+    private final Constant functionPointer;
+    @Input private final NodeInputList<ValueNode> args;
+
+    public AMD64RawNativeCallNode(Kind returnType, Constant functionPointer, ValueNode[] args) {
+        super(StampFactory.forKind(returnType));
+        this.functionPointer = functionPointer;
+        this.args = new NodeInputList<>(this, args);
+    }
+
+    @Override
+    public void generate(LIRGenerator generator) {
+        if (generator instanceof AMD64LIRGenerator) {
+            AMD64LIRGenerator amd64gen = (AMD64LIRGenerator) generator;
+            Value[] parameter = new Value[args.count()];
+            JavaType[] parameterTypes = new JavaType[args.count()];
+            for (int i = 0; i < args.count(); i++) {
+                parameter[i] = generator.operand(args.get(i));
+                parameterTypes[i] = args.get(i).stamp().javaType(amd64gen.getMetaAccess());
+            }
+            ResolvedJavaType returnType = stamp().javaType(amd64gen.getMetaAccess());
+            CallingConvention cc = generator.getCodeCache().getRegisterConfig().getCallingConvention(Type.NativeCall, returnType, parameterTypes, generator.target(), false);
+            amd64gen.emitCCall(functionPointer.asLong(), cc, parameter, countFloatingTypeArguments(args));
+            if (this.kind() != Kind.Void) {
+                generator.setResult(this, amd64gen.emitMove(cc.getReturn()));
+            }
+        } else {
+            throw GraalInternalError.shouldNotReachHere("GNFI Native call only supported with AMD64LIR Generator");
+        }
+    }
+
+    private static int countFloatingTypeArguments(NodeInputList<ValueNode> args) {
+        int count = 0;
+        for (ValueNode n : args) {
+            if (n.kind() == Kind.Double || n.kind() == Kind.Float) {
+                count++;
+            }
+        }
+        if (count > 8) {
+            return 8;
+        }
+        return count;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/InstallUtil.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.util;
+
+import static com.oracle.graal.api.code.CodeUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.printer.*;
+
+/**
+ * Utility to install the code of the native call stub.
+ * 
+ */
+public class InstallUtil {
+
+    protected final HotSpotProviders providers;
+    protected final Backend backend;
+
+    public InstallUtil(HotSpotProviders providers, Backend backend) {
+        DebugEnvironment.initialize(System.out);
+        this.providers = providers;
+        this.backend = backend;
+    }
+
+    /**
+     * Attaches a graph to a method libCall. Compiles the graph and installs it.
+     * 
+     * @param g the graph to be attached to a method and compiled
+     * @return returns the installed code that also holds a copy of graph g
+     */
+    public InstalledCode install(final StructuredGraph g) {
+        try {
+            Suites suites = providers.getSuites().createSuites();
+            PhaseSuite<HighTierContext> phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
+            CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, g.method(), false);
+            CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), null, phaseSuite, OptimisticOptimizations.ALL,
+                            DefaultProfilingInfo.get(TriState.UNKNOWN), new SpeculationLog(), suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default);
+            InstalledCode installedCode;
+            try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) {
+                installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null);
+            }
+
+            return installedCode;
+        } catch (SecurityException e) {
+            throw GraalInternalError.shouldNotReachHere("Installation of GNFI Callstub failed.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/NativeCallStubGraphBuilder.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.ffi.amd64.util;
+
+import java.util.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.ffi.amd64.*;
+import com.oracle.graal.ffi.amd64.node.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.word.phases.*;
+
+/**
+ * Utility that creates a Graal graph. The graph represents the native call stub for a foreign
+ * target function.
+ * 
+ */
+public class NativeCallStubGraphBuilder {
+
+    private static final ResolvedJavaType integerJavaType = HotSpotResolvedObjectType.fromClass(Integer.class);
+    private static final ResolvedJavaField[] integerInstanceFields = integerJavaType.getInstanceFields(false);
+    private static final ResolvedJavaField integerValueField = getValueField(integerInstanceFields);
+
+    private static final ResolvedJavaType longJavaType = HotSpotResolvedObjectType.fromClass(Long.class);
+    private static final ResolvedJavaField[] longInstanceFields = longJavaType.getInstanceFields(false);
+    private static final ResolvedJavaField longValueField = getValueField(longInstanceFields);
+
+    private static final ResolvedJavaType charJavaType = HotSpotResolvedObjectType.fromClass(Character.class);
+    private static final ResolvedJavaField[] charInstanceFields = charJavaType.getInstanceFields(false);
+    private static final ResolvedJavaField charValueField = getValueField(charInstanceFields);
+
+    private static final ResolvedJavaType byteJavaType = HotSpotResolvedObjectType.fromClass(Byte.class);
+    private static final ResolvedJavaField[] byteInstanceFields = byteJavaType.getInstanceFields(false);
+    private static final ResolvedJavaField byteValueField = getValueField(byteInstanceFields);
+
+    private static final ResolvedJavaType floatJavaType = HotSpotResolvedObjectType.fromClass(Float.class);
+    private static final ResolvedJavaField[] floatInstanceFields = floatJavaType.getInstanceFields(false);
+    private static final ResolvedJavaField floatValueField = getValueField(floatInstanceFields);
+
+    private static final ResolvedJavaType doubleJavaType = HotSpotResolvedObjectType.fromClass(Double.class);
+    private static final ResolvedJavaField[] doubleInstanceFields = doubleJavaType.getInstanceFields(false);
+    private static final ResolvedJavaField doubleValueField = getValueField(doubleInstanceFields);
+
+    private static ResolvedJavaField getValueField(ResolvedJavaField[] fields) {
+        for (ResolvedJavaField field : fields) {
+            if (field.getName().equals("value")) {
+                return field;
+            }
+        }
+        throw new AssertionError("value field not found!");
+    }
+
+    /**
+     * Creates a Graal graph that represents the call stub for a foreign target function.
+     * 
+     * @param providers the HotSpot providers
+     * @param functionPointer a function pointer that points to the foreign target function
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the graph that represents the call stub
+     */
+    public static StructuredGraph getGraph(HotSpotProviders providers, AMD64NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) {
+        ResolvedJavaMethod method;
+        try {
+            method = providers.getMetaAccess().lookupJavaMethod(NativeCallStubGraphBuilder.class.getMethod("libCall", Object.class, Object.class, Object.class));
+            StructuredGraph g = new StructuredGraph(method);
+            ParameterNode arg0 = g.unique(new ParameterNode(0, StampFactory.forKind(Kind.Object)));
+            ParameterNode arg1 = g.unique(new ParameterNode(1, StampFactory.forKind(Kind.Object)));
+            ParameterNode arg2 = g.unique(new ParameterNode(2, StampFactory.forKind(Kind.Object)));
+            FrameState frameState = g.add(new FrameState(method, 0, Arrays.asList(new ValueNode[]{arg0, arg1, arg2}), 3, 0, false, false, new ArrayList<MonitorIdNode>(),
+                            new ArrayList<EscapeObjectState>()));
+            g.start().setStateAfter(frameState);
+            List<ValueNode> parameters = new ArrayList<>();
+            FixedWithNextNode fixedWithNext = getParameters(g, arg0, argumentTypes.length, argumentTypes, parameters, providers);
+            Constant functionPointerNode = Constant.forLong(functionPointer.asRawValue());
+
+            ValueNode[] arguments = new ValueNode[parameters.size()];
+
+            for (int i = 0; i < arguments.length; i++) {
+                arguments[i] = parameters.get(i);
+            }
+
+            AMD64RawNativeCallNode callNode = g.add(new AMD64RawNativeCallNode(getKind(returnType), functionPointerNode, arguments));
+
+            if (fixedWithNext == null) {
+                g.start().setNext(callNode);
+            } else {
+                fixedWithNext.setNext(callNode);
+            }
+
+            // box result
+            BoxNode boxedResult;
+            if (callNode.kind() != Kind.Void) {
+                ResolvedJavaType type = getResolvedJavaType(callNode.kind());
+                boxedResult = new BoxNode(callNode, type, callNode.kind());
+            } else {
+                boxedResult = new BoxNode(ConstantNode.forLong(0, g), longJavaType, Kind.Long);
+            }
+
+            // box result:
+            BoxNode boxNode = g.unique(boxedResult);
+
+            ReturnNode returnNode = g.add(new ReturnNode(boxNode));
+            callNode.setNext(returnNode);
+            (new WordTypeRewriterPhase(providers.getMetaAccess(), Kind.Long)).apply(g);
+            return g;
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw GraalInternalError.shouldNotReachHere("Call Stub method not found");
+        }
+    }
+
+    private static FixedWithNextNode getParameters(StructuredGraph g, ParameterNode argumentsArray, int numArgs, Class[] argumentClass, List<ValueNode> args, HotSpotProviders providers) {
+        assert numArgs == argumentClass.length;
+        FixedWithNextNode fixedWithNext = null;
+        for (int i = 0; i < numArgs; i++) {
+            // load boxed array element:
+            LoadIndexedNode boxedElement = g.add(new LoadIndexedNode(argumentsArray, ConstantNode.forInt(i, g), Kind.Object));
+            if (i == 0) {
+                g.start().setNext(boxedElement);
+                fixedWithNext = boxedElement;
+            } else {
+                fixedWithNext.setNext(boxedElement);
+                fixedWithNext = boxedElement;
+            }
+            if (getKind(argumentClass[i]) == Kind.Object) {
+                // array value
+                Kind arrayElementKind = getArrayValuesKind(argumentClass[i]);
+                LocationIdentity locationIdentity = NamedLocationIdentity.getArrayLocation(arrayElementKind);
+                IndexedLocationNode locationNode = IndexedLocationNode.create(locationIdentity, arrayElementKind, HotSpotGraalRuntime.getArrayBaseOffset(arrayElementKind), ConstantNode.forInt(0, g),
+                                g, HotSpotGraalRuntime.getArrayIndexScale(arrayElementKind));
+                ComputeAddressNode arrayAddress = g.unique(new ComputeAddressNode(boxedElement, locationNode, StampFactory.forKind(providers.getCodeCache().getTarget().wordKind)));
+                args.add(arrayAddress);
+            } else {
+                // boxed primitive value
+                LoadFieldNode loadFieldNode = g.add(new LoadFieldNode(boxedElement, getResolvedJavaField(argumentClass[i])));
+                fixedWithNext.setNext(loadFieldNode);
+                fixedWithNext = loadFieldNode;
+                args.add(loadFieldNode);
+            }
+        }
+        return fixedWithNext;
+    }
+
+    public static int getArrayValuesObjectOffset(Class clazz) {
+        if (clazz == int[].class) {
+            return Unsafe.ARRAY_INT_BASE_OFFSET;
+        } else if (clazz == long[].class) {
+            return Unsafe.ARRAY_LONG_BASE_OFFSET;
+        } else if (clazz == char[].class) {
+            return Unsafe.ARRAY_CHAR_BASE_OFFSET;
+        } else if (clazz == byte[].class) {
+            return Unsafe.ARRAY_BYTE_BASE_OFFSET;
+        } else if (clazz == float[].class) {
+            return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+        } else if (clazz == double[].class) {
+            return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+        } else {
+            throw new IllegalArgumentException("Array Type not supported: " + clazz);
+        }
+    }
+
+    public static Kind getArrayValuesKind(Class clazz) {
+        if (clazz == int[].class) {
+            return Kind.Int;
+        } else if (clazz == long[].class) {
+            return Kind.Long;
+        } else if (clazz == char[].class) {
+            return Kind.Char;
+        } else if (clazz == byte[].class) {
+            return Kind.Byte;
+        } else if (clazz == float[].class) {
+            return Kind.Float;
+        } else if (clazz == double[].class) {
+            return Kind.Double;
+        } else {
+            throw new IllegalArgumentException("Array Type not supported: " + clazz);
+        }
+    }
+
+    private static Kind getKind(Class clazz) {
+        if (clazz == int.class || clazz == Integer.class) {
+            return Kind.Int;
+        } else if (clazz == long.class || clazz == Long.class) {
+            return Kind.Long;
+        } else if (clazz == char.class || clazz == Character.class) {
+            return Kind.Char;
+        } else if (clazz == byte.class || clazz == Byte.class) {
+            return Kind.Byte;
+        } else if (clazz == float.class || clazz == Float.class) {
+            return Kind.Float;
+        } else if (clazz == double.class || clazz == Double.class) {
+            return Kind.Double;
+        } else if (clazz == int[].class || clazz == long[].class || clazz == char[].class || clazz == byte[].class || clazz == float[].class || clazz == double[].class) {
+            return Kind.Object;
+        } else if (clazz == void.class) {
+            return Kind.Void;
+        } else {
+            throw new IllegalArgumentException("Type not supported: " + clazz);
+        }
+    }
+
+    private static ResolvedJavaField getResolvedJavaField(Class containerClass) {
+        if (containerClass == int.class || containerClass == Integer.class) {
+            return integerValueField;
+        } else if (containerClass == long.class || containerClass == Long.class) {
+            return longValueField;
+        } else if (containerClass == char.class || containerClass == Character.class) {
+            return charValueField;
+        } else if (containerClass == byte.class || containerClass == Byte.class) {
+            return byteValueField;
+        } else if (containerClass == float.class || containerClass == Float.class) {
+            return floatValueField;
+        } else if (containerClass == double.class || containerClass == Double.class) {
+            return doubleValueField;
+        } else {
+            throw new IllegalArgumentException("Type not supported: " + containerClass);
+        }
+    }
+
+    private static ResolvedJavaType getResolvedJavaType(Kind kind) {
+        if (kind == Kind.Int) {
+            return integerJavaType;
+        } else if (kind == Kind.Long) {
+            return longJavaType;
+        } else if (kind == Kind.Char) {
+            return charJavaType;
+        } else if (kind == Kind.Byte) {
+            return byteJavaType;
+        } else if (kind == Kind.Float) {
+            return floatJavaType;
+        } else if (kind == Kind.Double) {
+            return doubleJavaType;
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static Object libCall(Object argLoc, Object unused1, Object unused2) {
+        throw GraalInternalError.shouldNotReachHere("GNFI Callstub method must not be called!");
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Jan 30 09:19:45 2014 +0100
@@ -40,6 +40,7 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.ffi.amd64.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -306,4 +307,15 @@
             }
         }
     }
+
+    @Override
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        AMD64NativeFunctionPointer libraryLoadPointer = new AMD64NativeFunctionPointer(getRuntime().getConfig().libraryLoadAddress, "GNFI_UTIL_LOADLIBRARY");
+        AMD64NativeFunctionPointer functionLookupPointer = new AMD64NativeFunctionPointer(getRuntime().getConfig().functionLookupAddress, "GNFI_UTIL_FUNCTIONLOOKUP");
+        AMD64NativeLibraryHandle rtldDefault = new AMD64NativeLibraryHandle(getRuntime().getConfig().rtldDefault);
+        if (!libraryLoadPointer.isValid() || !functionLookupPointer.isValid()) {
+            throw new AssertionError("Lookup Pointers null");
+        }
+        return new AMD64NativeFunctionInterface(this.getProviders(), this, libraryLoadPointer, functionLookupPointer, rtldDefault);
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Jan 30 09:19:45 2014 +0100
@@ -350,6 +350,22 @@
     }
 
     @Override
+    public void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments) {
+        Value[] argLocations = new Value[args.length];
+        frameMap.callsMethod(nativeCallingConvention);
+        AllocatableValue numberOfFloatingPointArgumentsRegister = AMD64.rax.asValue();
+        emitMove(numberOfFloatingPointArgumentsRegister, Constant.forInt(numberOfFloatingPointArguments));
+        for (int i = 0; i < args.length; i++) {
+            Value arg = args[i];
+            AllocatableValue loc = nativeCallingConvention.getArgument(i);
+            emitMove(loc, arg);
+            argLocations[i] = loc;
+        }
+        Value ptr = emitMove(Constant.forLong(address));
+        append(new AMD64CCall(nativeCallingConvention.getReturn(), ptr, numberOfFloatingPointArgumentsRegister, argLocations));
+    }
+
+    @Override
     protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
         InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
         if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Thu Jan 30 09:19:45 2014 +0100
@@ -414,4 +414,9 @@
         codeBuffer.emitString0("};");
         codeBuffer.emitString("");
     }
+
+    @Override
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        throw GraalInternalError.unimplemented("No NativeFunctionInterface of HSAIL");
+    }
 }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Thu Jan 30 09:19:45 2014 +0100
@@ -484,4 +484,10 @@
 
     private static native int getAvailableProcessors0();
 
+
+    @Override
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        throw GraalInternalError.unimplemented("No NativeFunctionInterface of PTX");
+    }
+
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Thu Jan 30 09:19:45 2014 +0100
@@ -227,4 +227,9 @@
             SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
         }
     }
+
+    @Override
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        throw GraalInternalError.unimplemented("No NativeFunctionInterface of SPARC");
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Jan 30 09:19:45 2014 +0100
@@ -840,6 +840,10 @@
     @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset;
     @HotSpotVMField(name = "JavaThread::_graal_counters[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset;
 
+    @HotSpotVMConstant(name = "libraryLoadAddress") @Stable public long libraryLoadAddress;
+    @HotSpotVMConstant(name = "functionLookupAddress") @Stable public long functionLookupAddress;
+    @HotSpotVMConstant(name = "rtldDefault") @Stable public long rtldDefault;
+
     /**
      * This field is used to pass exception objects into and out of the runtime system during
      * exception handling for compiled code.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Jan 30 17:53:27 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Jan 30 09:19:45 2014 +0100
@@ -718,4 +718,14 @@
             throw new GraalInternalError(e);
         }
     }
+
+    @Fold
+    public static long dllLoad() {
+        return config().libraryLoadAddress;
+    }
+
+    @Fold
+    public static long dllLookup() {
+        return config().functionLookupAddress;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java	Thu Jan 30 09:19:45 2014 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.amd64;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.asm.*;
+
+public class AMD64CCall extends AMD64LIRInstruction {
+
+    @Def({REG, ILLEGAL}) protected Value result;
+    @Use({REG, STACK}) protected Value[] parameters;
+    @Use({REG}) protected Value functionPtr;
+    @Use({REG}) protected Value numberOfFloatingPointArguments;
+
+    public AMD64CCall(Value result, Value functionPtr, Value numberOfFloatingPointArguments, Value[] parameters) {
+        this.result = result;
+        this.functionPtr = functionPtr;
+        this.parameters = parameters;
+        this.numberOfFloatingPointArguments = numberOfFloatingPointArguments;
+    }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        directCall(masm);
+    }
+
+    private void directCall(AMD64MacroAssembler masm) {
+        Register reg = ValueUtil.asRegister(functionPtr);
+        masm.call(reg);
+        masm.ensureUniquePC();
+    }
+
+    @Override
+    public boolean destroysCallerSavedRegisters() {
+        return true;
+    }
+
+}
--- a/mx/projects	Thu Jan 30 17:53:27 2014 -0800
+++ b/mx/projects	Thu Jan 30 09:19:45 2014 +0100
@@ -184,7 +184,7 @@
 # graal.hotspot.amd64
 project@com.oracle.graal.hotspot.amd64@subDir=graal
 project@com.oracle.graal.hotspot.amd64@sourceDirs=src
-project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.replacements.amd64
+project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.ffi.amd64,com.oracle.graal.replacements.amd64
 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor
 project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7
@@ -651,6 +651,22 @@
 project@com.oracle.graal.asm.sparc@javaCompliance=1.7
 project@com.oracle.graal.asm.sparc@workingSets=Graal,Assembler,SPARC
 
+# graal.ffi.amd64
+project@com.oracle.graal.ffi.amd64@subDir=graal
+project@com.oracle.graal.ffi.amd64@sourceDirs=src
+project@com.oracle.graal.ffi.amd64@dependencies=com.oracle.graal.compiler.amd64,com.oracle.graal.hotspot
+project@com.oracle.graal.ffi.amd64@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.ffi.amd64@javaCompliance=1.7
+project@com.oracle.graal.ffi.amd64.test@workingSets=Graal,AMD64
+
+# graal.ffi.amd64.test
+project@com.oracle.graal.ffi.amd64.test@subDir=graal
+project@com.oracle.graal.ffi.amd64.test@sourceDirs=test
+project@com.oracle.graal.ffi.amd64.test@dependencies=JUNIT,com.oracle.graal.runtime
+project@com.oracle.graal.ffi.amd64.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.ffi.amd64.test@javaCompliance=1.7
+project@com.oracle.graal.ffi.amd64.test@workingSets=Graal,AMD64,Test
+
 # truffle.api
 project@com.oracle.truffle.api@subDir=graal
 project@com.oracle.truffle.api@sourceDirs=src
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Thu Jan 30 17:53:27 2014 -0800
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Jan 30 09:19:45 2014 +0100
@@ -554,7 +554,17 @@
   //------------------------------------------------------------------------------------------------
 
   set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset()));
-  set_int("graalCountersSize", (jint) GraalCounterSize);
+  set_int("graalCountersSize", (jint) GraalCounterSize);\
+
+  //------------------------------------------------------------------------------------------------
+
+  set_long("libraryLoadAddress", (jlong) os::dll_load);
+  set_long("functionLookupAddress", (jlong) os::dll_lookup);
+  #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux)
+  set_long("rtldDefault", (jlong) RTLD_DEFAULT);
+  #else 
+  set_long("rtldDefault", (jlong) 0xDEADFACE); //TODO(mg): will crash on java side, not supported!  
+  #endif
 
 #undef set_boolean
 #undef set_int