changeset 11721:e93fb0d17661

8161292: [JVMCI] missing test files from 8159368 Reviewed-by: twisti, kvn
author never
date Tue, 19 Jul 2016 18:11:03 +0000
parents f8e096377840
children 9766576633d2
files src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java test/compiler/jvmci/jdk.vm.ci.code.test/libNativeCallTest.c test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java
diffstat 4 files changed, 494 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Tue Jul 19 13:15:46 2016 +0200
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Tue Jul 19 18:11:03 2016 +0000
@@ -105,7 +105,9 @@
 
     private final RegisterArray javaGeneralParameterRegisters;
     private final RegisterArray nativeGeneralParameterRegisters;
-    private final RegisterArray xmmParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
+    private final RegisterArray javaXMMParameterRegisters;
+    private final RegisterArray nativeXMMParameterRegisters;
+    private final boolean windowsOS;
 
     /*
      * Some ABIs (e.g. Windows) require a so-called "home space", that is a save area on the stack
@@ -143,23 +145,27 @@
         assert callerSaved.size() >= allocatable.size();
     }
 
-    public AMD64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable, boolean windowsOs) {
+    public AMD64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable, boolean windowsOS) {
         this.target = target;
+        this.windowsOS = windowsOS;
 
-        if (windowsOs) {
+        if (windowsOS) {
             javaGeneralParameterRegisters = new RegisterArray(rdx, r8, r9, rdi, rsi, rcx);
             nativeGeneralParameterRegisters = new RegisterArray(rcx, rdx, r8, r9);
+            nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3);
             this.needsNativeStackHomeSpace = true;
         } else {
             javaGeneralParameterRegisters = new RegisterArray(rsi, rdx, rcx, r8, r9, rdi);
             nativeGeneralParameterRegisters = new RegisterArray(rdi, rsi, rdx, rcx, r8, r9);
+            nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
             this.needsNativeStackHomeSpace = false;
         }
+        javaXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
 
         this.allocatable = allocatable;
         Set<Register> callerSaveSet = new HashSet<>();
         allocatable.addTo(callerSaveSet);
-        xmmParameterRegisters.addTo(callerSaveSet);
+        javaXMMParameterRegisters.addTo(callerSaveSet);
         callerSaveSet.addAll(javaGeneralParameterRegisters.asList());
         nativeGeneralParameterRegisters.addTo(callerSaveSet);
         callerSaved = new RegisterArray(callerSaveSet);
@@ -187,11 +193,11 @@
     public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
         HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
         if (type == HotSpotCallingConventionType.NativeCall) {
-            return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
+            return callingConvention(nativeGeneralParameterRegisters, nativeXMMParameterRegisters, windowsOS, returnType, parameterTypes, hotspotType, valueKindFactory);
         }
         // On x64, parameter locations are the same whether viewed
         // from the caller or callee perspective
-        return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
+        return callingConvention(javaGeneralParameterRegisters, javaXMMParameterRegisters, false, returnType, parameterTypes, hotspotType, valueKindFactory);
     }
 
     @Override
@@ -208,14 +214,33 @@
                 return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
             case Float:
             case Double:
-                return xmmParameterRegisters;
+                return hotspotType == HotSpotCallingConventionType.NativeCall ? nativeXMMParameterRegisters : javaXMMParameterRegisters;
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
     }
 
-    private CallingConvention callingConvention(RegisterArray generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
+    /**
+     * Hand out registers matching the calling convention from the {@code generalParameterRegisters}
+     * and {@code xmmParameterRegisters} sets. Normally registers are handed out from each set
+     * individually based on the type of the argument. If the {@code unified} flag is true then hand
+     * out registers in a single sequence, selecting between the sets based on the type. This is to
+     * support the Windows calling convention which only ever passes 4 arguments in registers, no
+     * matter their types.
+     *
+     * @param generalParameterRegisters
+     * @param xmmParameterRegisters
+     * @param unified
+     * @param returnType
+     * @param parameterTypes
+     * @param type
+     * @param valueKindFactory
+     * @return the resulting calling convention
+     */
+    private CallingConvention callingConvention(RegisterArray generalParameterRegisters, RegisterArray xmmParameterRegisters, boolean unified, JavaType returnType, JavaType[] parameterTypes,
+                    HotSpotCallingConventionType type,
                     ValueKindFactory<?> valueKindFactory) {
+        assert !unified || generalParameterRegisters.size() == xmmParameterRegisters.size() : "must be same size in unified mode";
         AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
 
         int currentGeneral = 0;
@@ -240,8 +265,8 @@
                     break;
                 case Float:
                 case Double:
-                    if (currentXMM < xmmParameterRegisters.size()) {
-                        Register register = xmmParameterRegisters.get(currentXMM++);
+                    if ((unified ? currentGeneral : currentXMM) < xmmParameterRegisters.size()) {
+                        Register register = xmmParameterRegisters.get(unified ? currentGeneral++ : currentXMM++);
                         locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
@@ -255,6 +280,7 @@
                 currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
             }
         }
+        assert !unified || currentXMM == 0 : "shouldn't be used in unified mode";
 
         JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
         AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/jvmci/jdk.vm.ci.code.test/libNativeCallTest.c	Tue Jul 19 18:11:03 2016 +0000
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+jfloat JNICALL SS(jfloat f1, jfloat f2) {
+  return f1 + f2;
+}
+
+JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getFF(JNIEnv *env, jclass clazz) {
+  return (jlong)(intptr_t)SS;
+}
+
+JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1FF(JNIEnv *env, jclass clazz, jfloat a, jfloat b) {
+  return SS(a, b);
+}
+
+jfloat JNICALL SDILDS(jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return (jfloat)(a + b + c + d + e + f);
+}
+
+JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getSDILDS(JNIEnv *env, jclass clazz) {
+  return (jlong)(intptr_t)SDILDS;
+}
+
+JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1SDILDS(JNIEnv *env, jclass clazz,
+                                                                          jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return SDILDS(a, b, c, d, e, f);
+}
+
+jfloat JNICALL F32SDILDS(jfloat f00, jfloat f01, jfloat f02, jfloat f03, jfloat f04, jfloat f05, jfloat f06, jfloat f07,
+                         jfloat f08, jfloat f09, jfloat f0a, jfloat f0b, jfloat f0c, jfloat f0d, jfloat f0e, jfloat f0f,
+                         jfloat f10, jfloat f11, jfloat f12, jfloat f13, jfloat f14, jfloat f15, jfloat f16, jfloat f17,
+                         jfloat f18, jfloat f19, jfloat f1a, jfloat f1b, jfloat f1c, jfloat f1d, jfloat f1e, jfloat f1f,
+                         jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return (jfloat)(f00 + f01 + f02 + f03 + f04 + f05 + f06 + f07 +
+                  f08 + f09 + f0a + f0b + f0c + f0d + f0e + f0f +
+                  f10 + f11 + f12 + f13 + f14 + f15 + f16 + f17 +
+                  f18 + f19 + f1a + f1b + f1c + f1d + f1e + f1f +
+                  a +   b +   c +   d +   e + f);
+}
+
+JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getF32SDILDS(JNIEnv *env, jclass clazz) {
+  return (jlong)(intptr_t)F32SDILDS;
+}
+
+JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1F32SDILDS(JNIEnv *env, jclass clazz,
+                                                                             jfloat f00, jfloat f01, jfloat f02, jfloat f03,
+                                                                             jfloat f04, jfloat f05, jfloat f06, jfloat f07,
+                                                                             jfloat f08, jfloat f09, jfloat f0a, jfloat f0b,
+                                                                             jfloat f0c, jfloat f0d, jfloat f0e, jfloat f0f,
+                                                                             jfloat f10, jfloat f11, jfloat f12, jfloat f13,
+                                                                             jfloat f14, jfloat f15, jfloat f16, jfloat f17,
+                                                                             jfloat f18, jfloat f19, jfloat f1a, jfloat f1b,
+                                                                             jfloat f1c, jfloat f1d, jfloat f1e, jfloat f1f,
+                                                                             jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return F32SDILDS(f00, f01, f02, f03, f04, f05, f06, f07,
+                   f08, f09, f0a, f0b, f0c, f0d, f0e, f0f,
+                   f10, f11, f12, f13, f14, f15, f16, f17,
+                   f18, f19, f1a, f1b, f1c, f1d, f1e, f1f,
+                   a,   b,   c,   d,   e,   f);
+}
+
+
+jfloat JNICALL D32SDILDS(jdouble d00, jdouble d01, jdouble d02, jdouble d03, jdouble d04, jdouble d05, jdouble d06, jdouble d07,
+                         jdouble d08, jdouble d09, jdouble d0a, jdouble d0b, jdouble d0c, jdouble d0d, jdouble d0e, jdouble d0f,
+                         jdouble d10, jdouble d11, jdouble d12, jdouble d13, jdouble d14, jdouble d15, jdouble d16, jdouble d17,
+                         jdouble d18, jdouble d19, jdouble d1a, jdouble d1b, jdouble d1c, jdouble d1d, jdouble d1e, jdouble d1f,
+                         jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return (jfloat)(d00 + d01 + d02 + d03 + d04 + d05 + d06 + d07 +
+                  d08 + d09 + d0a + d0b + d0c + d0d + d0e + d0f +
+                  d10 + d11 + d12 + d13 + d14 + d15 + d16 + d17 +
+                  d18 + d19 + d1a + d1b + d1c + d1d + d1e + d1f +
+                  a +   b +   c +   d +   e + f);
+}
+
+JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getD32SDILDS(JNIEnv *env, jclass clazz) {
+  return (jlong)(intptr_t)D32SDILDS;
+}
+
+JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1D32SDILDS(JNIEnv *env, jclass clazz,
+                                                                             jdouble d00, jdouble d01, jdouble d02, jdouble d03,
+                                                                             jdouble d04, jdouble d05, jdouble d06, jdouble d07,
+                                                                             jdouble d08, jdouble d09, jdouble d0a, jdouble d0b,
+                                                                             jdouble d0c, jdouble d0d, jdouble d0e, jdouble d0f,
+                                                                             jdouble d10, jdouble d11, jdouble d12, jdouble d13,
+                                                                             jdouble d14, jdouble d15, jdouble d16, jdouble d17,
+                                                                             jdouble d18, jdouble d19, jdouble d1a, jdouble d1b,
+                                                                             jdouble d1c, jdouble d1d, jdouble d1e, jdouble d1f,
+                                                                             jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return D32SDILDS(d00, d01, d02, d03, d04, d05, d06, d07,
+                   d08, d09, d0a, d0b, d0c, d0d, d0e, d0f,
+                   d10, d11, d12, d13, d14, d15, d16, d17,
+                   d18, d19, d1a, d1b, d1c, d1d, d1e, d1f,
+                   a,   b,   c,   d,   e,   f);
+}
+
+
+jfloat JNICALL I32SDILDS(jint i00, jint i01, jint i02, jint i03, jint i04, jint i05, jint i06, jint i07,
+                         jint i08, jint i09, jint i0a, jint i0b, jint i0c, jint i0d, jint i0e, jint i0f,
+                         jint i10, jint i11, jint i12, jint i13, jint i14, jint i15, jint i16, jint i17,
+                         jint i18, jint i19, jint i1a, jint i1b, jint i1c, jint i1d, jint i1e, jint i1f,
+                         jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return (jfloat)(i00 + i01 + i02 + i03 + i04 + i05 + i06 + i07 +
+                  i08 + i09 + i0a + i0b + i0c + i0d + i0e + i0f +
+                  i10 + i11 + i12 + i13 + i14 + i15 + i16 + i17 +
+                  i18 + i19 + i1a + i1b + i1c + i1d + i1e + i1f +
+                  a +   b +   c +   d +   e + f);
+}
+
+JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getI32SDILDS(JNIEnv *env, jclass clazz) {
+  return (jlong) (intptr_t) I32SDILDS;
+}
+
+JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1I32SDILDS(JNIEnv *env, jclass clazz,
+                                                                             jint i00, jint i01, jint i02, jint i03,
+                                                                             jint i04, jint i05, jint i06, jint i07,
+                                                                             jint i08, jint i09, jint i0a, jint i0b,
+                                                                             jint i0c, jint i0d, jint i0e, jint i0f,
+                                                                             jint i10, jint i11, jint i12, jint i13,
+                                                                             jint i14, jint i15, jint i16, jint i17,
+                                                                             jint i18, jint i19, jint i1a, jint i1b,
+                                                                             jint i1c, jint i1d, jint i1e, jint i1f,
+                                                                             jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return I32SDILDS(i00, i01, i02, i03, i04, i05, i06, i07,
+                   i08, i09, i0a, i0b, i0c, i0d, i0e, i0f,
+                   i10, i11, i12, i13, i14, i15, i16, i17,
+                   i18, i19, i1a, i1b, i1c, i1d, i1e, i1f,
+                   a,   b,   c,   d,   e,   f);
+}
+
+jfloat JNICALL L32SDILDS(jlong l00, jlong l01, jlong l02, jlong l03, jlong l04, jlong l05, jlong l06, jlong l07,
+                         jlong l08, jlong l09, jlong l0a, jlong l0b, jlong l0c, jlong l0d, jlong l0e, jlong l0f,
+                         jlong l10, jlong l11, jlong l12, jlong l13, jlong l14, jlong l15, jlong l16, jlong l17,
+                         jlong l18, jlong l19, jlong l1a, jlong l1b, jlong l1c, jlong l1d, jlong l1e, jlong l1f,
+                         jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return (jfloat)(l00 + l01 + l02 + l03 + l04 + l05 + l06 + l07 +
+                  l08 + l09 + l0a + l0b + l0c + l0d + l0e + l0f +
+                  l10 + l11 + l12 + l13 + l14 + l15 + l16 + l17 +
+                  l18 + l19 + l1a + l1b + l1c + l1d + l1e + l1f +
+                  a +   b +   c +   d +   e + f);
+}
+
+JNIEXPORT jlong JNICALL Java_jdk_vm_ci_code_test_NativeCallTest_getL32SDILDS(JNIEnv *env, jclass clazz) {
+  return (jlong)(intptr_t)L32SDILDS;
+}
+
+JNIEXPORT jfloat JNICALL Java_jdk_vm_ci_code_test_NativeCallTest__1L32SDILDS(JNIEnv *env, jclass clazz,
+                                                                               jlong l00, jlong l01, jlong l02, jlong l03,
+                                                                               jlong l04, jlong l05, jlong l06, jlong l07,
+                                                                               jlong l08, jlong l09, jlong l0a, jlong l0b,
+                                                                               jlong l0c, jlong l0d, jlong l0e, jlong l0f,
+                                                                               jlong l10, jlong l11, jlong l12, jlong l13,
+                                                                               jlong l14, jlong l15, jlong l16, jlong l17,
+                                                                               jlong l18, jlong l19, jlong l1a, jlong l1b,
+                                                                               jlong l1c, jlong l1d, jlong l1e, jlong l1f,
+                                                                               jfloat a, jdouble b, jint c, jlong d, jdouble e, jfloat f) {
+  return L32SDILDS(l00, l01, l02, l03, l04, l05, l06, l07,
+                   l08, l09, l0a, l0b, l0c, l0d, l0e, l0f,
+                   l10, l11, l12, l13, l14, l15, l16, l17,
+                   l18, l19, l1a, l1b, l1c, l1d, l1e, l1f,
+                   a,   b,   c,   d,   e,   f);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java	Tue Jul 19 18:11:03 2016 +0000
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * @test
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /test/lib /testlibrary /
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *          jdk.vm.ci/jdk.vm.ci.code.site
+ *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.common
+ *          jdk.vm.ci/jdk.vm.ci.amd64
+ *          jdk.vm.ci/jdk.vm.ci.sparc
+ * @compile CodeInstallationTest.java TestHotSpotVMConfig.java NativeCallTest.java TestAssembler.java sparc/SPARCTestAssembler.java amd64/AMD64TestAssembler.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI  -Xbootclasspath/a:. jdk.vm.ci.code.test.NativeCallTest
+ */
+package jdk.vm.ci.code.test;
+
+import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.NativeCall;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.meta.JavaType;
+
+public class NativeCallTest extends CodeInstallationTest {
+
+    @BeforeClass
+    public static void beforeClass() {
+        System.loadLibrary("NativeCallTest");
+    }
+
+    @Test
+    public void testFF() {
+        float a = 1.2345678f;
+        float b = 8.7654321f;
+        test("FF", getFF(), float.class, new Class<?>[]{float.class, float.class}, new Object[]{a, b});
+    }
+
+    @Test
+    public void testSDILDS() {
+        float a = 1.2345678f;
+        double b = 3.212434;
+        int c = 43921652;
+        long d = 412435326;
+        double e = .31212333;
+        float f = 8.7654321f;
+        Class<?>[] argClazz = new Class[]{float.class, double.class, int.class, long.class, double.class,
+                        float.class};
+        test("SDILDS", getSDILDS(), float.class, argClazz, new Object[]{a, b, c, d, e, f});
+    }
+
+    @Test
+    public void testF32SDILDS() {
+        int sCount = 32;
+        Object[] remainingArgs = new Object[]{ // Pairs of <Object>, <Class>
+                        1.2345678F, float.class,
+                        3.212434D, double.class,
+                        43921652, int.class,
+                        0xCAFEBABEDEADBEEFL, long.class,
+                        .31212333D, double.class,
+                        8.7654321F, float.class
+        };
+        Class<?>[] argClazz = new Class[sCount + remainingArgs.length / 2];
+        Object[] argValues = new Object[sCount + remainingArgs.length / 2];
+        for (int i = 0; i < sCount; i++) {
+            argValues[i] = (float) i;
+            argClazz[i] = float.class;
+        }
+        for (int i = 0; i < remainingArgs.length; i += 2) {
+            argValues[sCount + i / 2] = remainingArgs[i + 0];
+            argClazz[sCount + i / 2] = (Class<?>) remainingArgs[i + 1];
+        }
+        test("F32SDILDS", getF32SDILDS(), float.class, argClazz, argValues);
+    }
+
+    @Test
+    public void testI32SDILDS() {
+        int sCount = 32;
+        Object[] remainingArgs = new Object[]{ // Pairs of <Object>, <Class>
+                        1.2345678F, float.class,
+                        3.212434D, double.class,
+                        43921652, int.class,
+                        0xCAFEBABEDEADBEEFL, long.class,
+                        .31212333D, double.class,
+                        8.7654321F, float.class
+        };
+        Class<?>[] argClazz = new Class[sCount + remainingArgs.length / 2];
+        Object[] argValues = new Object[sCount + remainingArgs.length / 2];
+        for (int i = 0; i < sCount; i++) {
+            argValues[i] = i;
+            argClazz[i] = int.class;
+        }
+        for (int i = 0; i < remainingArgs.length; i += 2) {
+            argValues[sCount + i / 2] = remainingArgs[i + 0];
+            argClazz[sCount + i / 2] = (Class<?>) remainingArgs[i + 1];
+        }
+        test("I32SDILDS", getI32SDILDS(), float.class, argClazz, argValues);
+    }
+
+    public void test(String name, long addr, Class<?> returnClazz, Class<?>[] types, Object[] values) {
+        try {
+            test(asm -> {
+                JavaType[] argTypes = new JavaType[types.length];
+                int i = 0;
+                for (Class<?> clazz : types) {
+                    argTypes[i++] = metaAccess.lookupJavaType(clazz);
+                }
+                JavaType returnType = metaAccess.lookupJavaType(returnClazz);
+                CallingConvention cc = codeCache.getRegisterConfig().getCallingConvention(NativeCall, returnType, argTypes, asm.valueKindFactory);
+                asm.emitCallPrologue(cc, values);
+                asm.emitCall(addr);
+                asm.emitCallEpilogue(cc);
+                asm.emitFloatRet(((RegisterValue) cc.getReturn()).getRegister());
+            }, getMethod(name, types), values);
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    public static native long getFF();
+
+    public static native float _FF(float a, float b);
+
+    public static float FF(float a, float b) {
+        return _FF(a, b);
+    }
+
+    public static native long getSDILDS();
+
+    public static native float _SDILDS(float a, double b, int c, long d, double e, float f);
+
+    public static float SDILDS(float a, double b, int c, long d, double e, float f) {
+        return _SDILDS(a, b, c, d, e, f);
+    }
+
+    public static native long getF32SDILDS();
+
+    public static native float _F32SDILDS(float f00, float f01, float f02, float f03, float f04, float f05, float f06, float f07,
+                    float f08, float f09, float f0a, float f0b, float f0c, float f0d, float f0e, float f0f,
+                    float f10, float f11, float f12, float f13, float f14, float f15, float f16, float f17,
+                    float f18, float f19, float f1a, float f1b, float f1c, float f1d, float f1e, float f1f,
+                    float a, double b, int c, long d, double e, float f);
+
+    public static float F32SDILDS(float f00, float f01, float f02, float f03, float f04, float f05, float f06, float f07,
+                    float f08, float f09, float f0a, float f0b, float f0c, float f0d, float f0e, float f0f,
+                    float f10, float f11, float f12, float f13, float f14, float f15, float f16, float f17,
+                    float f18, float f19, float f1a, float f1b, float f1c, float f1d, float f1e, float f1f,
+                    float a, double b, int c, long d, double e, float f) {
+        return _F32SDILDS(f00, f01, f02, f03, f04, f05, f06, f07,
+                        f08, f09, f0a, f0b, f0c, f0d, f0e, f0f,
+                        f10, f11, f12, f13, f14, f15, f16, f17,
+                        f18, f19, f1a, f1b, f1c, f1d, f1e, f1f,
+                        a, b, c, d, e, f);
+    }
+
+    public static native long getD32SDILDS();
+
+    public static native float _D32SDILDS(double d00, double d01, double d02, double d03, double d04, double d05, double d06, double d07,
+                    double d08, double d09, double d0a, double d0b, double d0c, double d0d, double d0e, double d0f,
+                    double d10, double d11, double d12, double d13, double d14, double d15, double d16, double d17,
+                    double d18, double d19, double d1a, double d1b, double d1c, double d1d, double d1e, double d1f,
+                    float a, double b, int c, long d, double e, float f);
+
+    public static float D32SDILDS(double d00, double d01, double d02, double d03, double d04, double d05, double d06, double d07,
+                    double d08, double d09, double d0a, double d0b, double d0c, double d0d, double d0e, double d0f,
+                    double d10, double d11, double d12, double d13, double d14, double d15, double d16, double d17,
+                    double d18, double d19, double d1a, double d1b, double d1c, double d1d, double d1e, double d1f,
+                    float a, double b, int c, long d, double e, float f) {
+        return _D32SDILDS(d00, d01, d02, d03, d04, d05, d06, d07,
+                        d08, d09, d0a, d0b, d0c, d0d, d0e, d0d,
+                        d10, d11, d12, d13, d14, d15, d16, d17,
+                        d18, d19, d1a, d1b, d1c, d1d, d1e, d1f,
+                        a, b, c, d, e, f);
+    }
+
+    public static native long getI32SDILDS();
+
+    public static native float _I32SDILDS(int i00, int i01, int i02, int i03, int i04, int i05, int i06, int i07,
+                    int i08, int i09, int i0a, int i0b, int i0c, int i0d, int i0e, int i0f,
+                    int i10, int i11, int i12, int i13, int i14, int i15, int i16, int i17,
+                    int i18, int i19, int i1a, int i1b, int i1c, int i1d, int i1e, int i1f,
+                    float a, double b, int c, long d, double e, float f);
+
+    public static float I32SDILDS(int i00, int i01, int i02, int i03, int i04, int i05, int i06, int i07,
+                    int i08, int i09, int i0a, int i0b, int i0c, int i0d, int i0e, int i0f,
+                    int i10, int i11, int i12, int i13, int i14, int i15, int i16, int i17,
+                    int i18, int i19, int i1a, int i1b, int i1c, int i1d, int i1e, int i1f,
+                    float a, double b, int c, long d, double e, float f) {
+        return _I32SDILDS(i00, i01, i02, i03, i04, i05, i06, i07,
+                        i08, i09, i0a, i0b, i0c, i0d, i0e, i0f,
+                        i10, i11, i12, i13, i14, i15, i16, i17,
+                        i18, i19, i1a, i1b, i1c, i1d, i1e, i1f,
+                        a, b, c, d, e, f);
+    }
+
+    public static native long getL32SDILDS();
+
+    public static native float _L32SDILDS(long l00, long l01, long l02, long l03, long l04, long l05, long l06, long l07,
+                    long l08, long l09, long l0a, long l0b, long l0c, long l0d, long l0e, long l0f,
+                    long l10, long l11, long l12, long l13, long l14, long l15, long l16, long l17,
+                    long l18, long l19, long l1a, long l1b, long l1c, long l1d, long l1e, long l1f,
+                    float a, double b, int c, long d, double e, float f);
+
+    public static float L32SDILDS(long l00, long l01, long l02, long l03, long l04, long l05, long l06, long l07,
+                    long l08, long l09, long l0a, long l0b, long l0c, long l0d, long l0e, long l0f,
+                    long l10, long l11, long l12, long l13, long l14, long l15, long l16, long l17,
+                    long l18, long l19, long l1a, long l1b, long l1c, long l1d, long l1e, long l1f,
+                    float a, double b, int c, long d, double e, float f) {
+        return _L32SDILDS(l00, l01, l02, l03, l04, l05, l06, l07,
+                        l08, l09, l0a, l0b, l0c, l0d, l0e, l0f,
+                        l10, l11, l12, l13, l14, l15, l16, l17,
+                        l18, l19, l1a, l1b, l1c, l1d, l1e, l1f,
+                        a, b, c, d, e, f);
+    }
+}
--- a/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Tue Jul 19 13:15:46 2016 +0200
+++ b/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Tue Jul 19 18:11:03 2016 +0000
@@ -46,6 +46,9 @@
 
 public class AMD64TestAssembler extends TestAssembler {
 
+    private static final Register scratchRegister = AMD64.r12;
+    private static final Register doubleScratch = AMD64.xmm15;
+
     public AMD64TestAssembler(CodeCacheProvider codeCache, TestHotSpotVMConfig config) {
         super(codeCache, config, 16, 16, AMD64Kind.DWORD, AMD64.rax, AMD64.rcx, AMD64.rdi, AMD64.r8, AMD64.r9, AMD64.r10);
     }
@@ -226,6 +229,14 @@
         return ret;
     }
 
+    private int getAdjustedOffset(StackSlot ret) {
+        if (ret.getRawOffset() < 0) {
+            return ret.getRawOffset() + 16;
+        } else {
+            return -(frameSize - ret.getRawOffset()) + 16;
+        }
+    }
+
     @Override
     public StackSlot emitIntToStack(Register a) {
         StackSlot ret = newStackSlot(AMD64Kind.DWORD);
@@ -234,7 +245,7 @@
 
     public StackSlot emitIntToStack(StackSlot ret, Register a) {
         // MOV r/m32,r32
-        emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
+        emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, getAdjustedOffset(ret));
         return ret;
     }
 
@@ -246,7 +257,7 @@
 
     public StackSlot emitLongToStack(StackSlot ret, Register a) {
         // MOV r/m64,r64
-        emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
+        emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, getAdjustedOffset(ret));
         return ret;
     }
 
@@ -262,11 +273,7 @@
         code.emitByte(0x0F);
         code.emitByte(0x11);                               // MOVSS xmm2/m32, xmm1
         code.emitByte(0x85 | ((a.encoding & 0x7) << 3));   // [rbp+offset]
-        if (ret.getRawOffset() < 0) {
-            code.emitInt(ret.getRawOffset() + 16);
-        } else {
-            code.emitInt(-(frameSize - ret.getRawOffset()) + 16);
-        }
+        code.emitInt(getAdjustedOffset(ret));
         return ret;
     }
 
@@ -282,11 +289,7 @@
         code.emitByte(0x0F);
         code.emitByte(0x11);                               // MOVSD xmm2/m32, xmm1
         code.emitByte(0x85 | ((a.encoding & 0x7) << 3));   // [rbp+offset]
-        if (ret.getRawOffset() < 0) {
-            code.emitInt(ret.getRawOffset() + 16);
-        } else {
-            code.emitInt(-(frameSize - ret.getRawOffset()) + 16);
-        }
+        code.emitInt(getAdjustedOffset(ret));
         return ret;
     }
 
@@ -383,15 +386,16 @@
         } else if (av instanceof StackSlot) {
             StackSlot slot = (StackSlot) av;
             if (prim instanceof Float) {
-                emitFloatToStack(slot, emitLoadFloat((Float) prim));
+                emitFloatToStack(slot, emitLoadFloat(doubleScratch, (Float) prim));
             } else if (prim instanceof Double) {
-                emitDoubleToStack(slot, emitLoadDouble((Double) prim));
+                emitDoubleToStack(slot, emitLoadDouble(doubleScratch, (Double) prim));
             } else if (prim instanceof Integer) {
-                emitIntToStack(slot, emitLoadInt((Integer) prim));
+                emitIntToStack(slot, emitLoadInt(scratchRegister, (Integer) prim));
             } else if (prim instanceof Long) {
-                emitLongToStack(slot, emitLoadLong((Long) prim));
+                emitLongToStack(slot, emitLoadLong(scratchRegister, (Long) prim));
+            } else {
+                assert false : "Unimplemented";
             }
-            assert false : "Unimplemented";
         } else {
             throw new IllegalArgumentException("Unknown value " + av);
         }