Mercurial > hg > graal-compiler
view graal/com.oracle.graal.replacements.aarch64/src/com/oracle/graal/replacements/aarch64/AArch64FloatArithmeticSnippets.java @ 23217:a1bfeec72458
AArch64 Graal Port
author | twisti |
---|---|
date | Thu, 24 Dec 2015 11:43:35 -1000 |
parents | |
children | 2160e7da7fb0 |
line wrap: on
line source
/* * Copyright (c) 2014, 2015, 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.replacements.aarch64; import com.oracle.graal.api.replacements.SnippetReflectionProvider; import com.oracle.graal.compiler.common.type.ArithmeticOpTable; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Rem; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.graph.NodeClass; import com.oracle.graal.graph.spi.CanonicalizerTool; import com.oracle.graal.lir.gen.ArithmeticLIRGeneratorTool; import com.oracle.graal.nodeinfo.NodeInfo; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.BinaryArithmeticNode; import com.oracle.graal.nodes.calc.RemNode; import com.oracle.graal.nodes.spi.LoweringTool; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; import com.oracle.graal.phases.util.Providers; import com.oracle.graal.replacements.Snippet; import com.oracle.graal.replacements.SnippetTemplate; import com.oracle.graal.replacements.Snippets; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.JavaKind; /** * AArch64 does not have a remainder operation. We use <code>n % d == n - Truncate(n / d) * d</code> * for it instead. This is not correct for some edge cases, so we have to fix it up using these * snippets. */ public class AArch64FloatArithmeticSnippets extends SnippetTemplate.AbstractTemplates implements Snippets { private final SnippetTemplate.SnippetInfo drem; private final SnippetTemplate.SnippetInfo frem; public AArch64FloatArithmeticSnippets(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { super(providers, snippetReflection, target); drem = snippet(AArch64FloatArithmeticSnippets.class, "dremSnippet"); frem = snippet(AArch64FloatArithmeticSnippets.class, "fremSnippet"); } public void lower(RemNode node, LoweringTool tool) { // assert node.kind() == JavaKind.Float || node.kind() == JavaKind.Double; // if (node instanceof SafeNode) { // // We already introduced the necessary checks, nothing to do. // return; // } // SnippetTemplate.SnippetInfo snippet = node.kind() == Kind.Double ? drem : frem; // SnippetTemplate.Arguments args = new SnippetTemplate.Arguments(snippet, // node.graph().getGuardsStage()); // args.add("x", node.x()); // args.add("y", node.y()); // args.add("isStrictFP", node.isStrictFP()); // template(args).instantiate(providers.getMetaAccess(), node, // SnippetTemplate.DEFAULT_REPLACER, // tool, args); throw JVMCIError.unimplemented(node + ", " + tool); } @Snippet public static double dremSnippet(double x, double y, @Snippet.ConstantParameter boolean isStrictFP) { if (Double.isInfinite(x) || y == 0.0 || Double.isNaN(y)) { return Double.NaN; } // -0.0 % 5.0 will result in 0.0 and not -0.0 if we don't check here. if (Double.isInfinite(y) || x == 0.0) { return x; } return safeRem(JavaKind.Double, x, y, isStrictFP); } @Snippet public static float fremSnippet(float x, float y, @Snippet.ConstantParameter boolean isStrictFP) { if (Float.isInfinite(x) || y == 0.0f || Float.isNaN(y)) { return Float.NaN; } // -0.0 % 5.0 will result in 0.0 and not -0.0 if we don't check here. if (Float.isInfinite(y) || x == 0.0f) { return x; } return safeRem(JavaKind.Float, x, y, isStrictFP); } @NodeIntrinsic(SafeFloatRemNode.class) private static native double safeRem(@Node.ConstantNodeParameter JavaKind kind, double x, double y, @Node.ConstantNodeParameter boolean isStrictFP); @NodeIntrinsic(SafeFloatRemNode.class) private static native float safeRem(@Node.ConstantNodeParameter JavaKind kind, float x, float y, @Node.ConstantNodeParameter boolean isStrictFP); // Marker interface to distinguish untreated nodes from ones where we have installed the // additional checks private interface SafeNode { } @NodeInfo // static class SafeFloatRemNode extends FloatRemNode implements SafeNode { static class SafeFloatRemNode extends BinaryArithmeticNode<Rem> implements SafeNode { public static final NodeClass<SafeFloatRemNode> TYPE = NodeClass.create(SafeFloatRemNode.class); @SuppressWarnings("unused") public SafeFloatRemNode(JavaKind kind, ValueNode x, ValueNode y, boolean isStrictFP) { super(TYPE, ArithmeticOpTable::getRem, x, y); } public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) { throw JVMCIError.unimplemented(); } public void generate(NodeLIRBuilderTool generator) { throw JVMCIError.unimplemented(); } public Node canonical(CanonicalizerTool tool) { throw JVMCIError.unimplemented(); } } }