--- /dev/null 2017-11-16 08:17:56.803999947 +0100 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64X87MathSnippets.java 2019-03-09 03:57:51.637410665 +0100 @@ -0,0 +1,117 @@ +/* + * 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 org.graalvm.compiler.hotspot.amd64; + +import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; + +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; +import org.graalvm.compiler.debug.DebugHandlersFactory; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node.ConstantNodeParameter; +import org.graalvm.compiler.graph.Node.NodeIntrinsic; +import org.graalvm.compiler.nodes.extended.ForeignCallNode; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.phases.util.Providers; +import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; +import org.graalvm.compiler.replacements.SnippetTemplate.Arguments; +import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.Snippets; +import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode; +import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation; + +import jdk.vm.ci.code.TargetDescription; + +public class AMD64X87MathSnippets implements Snippets { + + private static final double PI_4 = Math.PI / 4; + + @Snippet + public static double sin(double input) { + if (Math.abs(input) < PI_4) { + return AMD64X87MathIntrinsicNode.compute(input, UnaryOperation.SIN); + } + return callDouble1(UnaryOperation.SIN.foreignCallDescriptor, input); + } + + @Snippet + public static double cos(double input) { + if (Math.abs(input) < PI_4) { + return AMD64X87MathIntrinsicNode.compute(input, UnaryOperation.COS); + } + return callDouble1(UnaryOperation.COS.foreignCallDescriptor, input); + } + + @Snippet + public static double tan(double input) { + if (Math.abs(input) < PI_4) { + return AMD64X87MathIntrinsicNode.compute(input, UnaryOperation.TAN); + } + return callDouble1(UnaryOperation.TAN.foreignCallDescriptor, input); + } + + @NodeIntrinsic(value = ForeignCallNode.class) + private static native double callDouble1(@ConstantNodeParameter ForeignCallDescriptor descriptor, double value); + + public static class Templates extends AbstractTemplates { + + private final SnippetInfo sin; + private final SnippetInfo cos; + private final SnippetInfo tan; + + public Templates(OptionValues options, Iterable factories, Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { + super(options, factories, providers, snippetReflection, target); + + sin = snippet(AMD64X87MathSnippets.class, "sin"); + cos = snippet(AMD64X87MathSnippets.class, "cos"); + tan = snippet(AMD64X87MathSnippets.class, "tan"); + } + + public void lower(UnaryMathIntrinsicNode mathIntrinsicNode, LoweringTool tool) { + SnippetInfo info; + + switch (mathIntrinsicNode.getOperation()) { + case SIN: + info = sin; + break; + case COS: + info = cos; + break; + case TAN: + info = tan; + break; + default: + throw GraalError.shouldNotReachHere("Snippet not found for math intrinsic " + mathIntrinsicNode.getOperation().name()); + } + + Arguments args = new Arguments(info, mathIntrinsicNode.graph().getGuardsStage(), tool.getLoweringStage()); + args.add("input", mathIntrinsicNode.getValue()); + template(mathIntrinsicNode, args).instantiate(providers.getMetaAccess(), mathIntrinsicNode, DEFAULT_REPLACER, tool, args); + mathIntrinsicNode.safeDelete(); + } + } +}