/* * 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 testS32SDILDS() { int sCount = 32; Object[] remainingArgs = new Object[]{ // Pairs of , 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("S32SDILDS", getS32SDILDS(), 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 getS32SDILDS(); public static native float _S32SDILDS( 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 S32SDILDS( 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 _S32SDILDS( 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); } }