comparison graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64MathIntrinsicNode.java @ 20854:3081a57f95fd

converted @MethodSubstitutions for java.lang.Math to MethodSubstitutionPlugins moved support for AMD64 specific Math intrinsics into AMD64 specific name spaces
author Doug Simon <doug.simon@oracle.com>
date Wed, 08 Apr 2015 22:09:05 +0200
parents graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java@14e703edb2ab
children 93c50cefb9e8
comparison
equal deleted inserted replaced
20853:a74c785068e0 20854:3081a57f95fd
1 /*
2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.graal.replacements.amd64;
24
25 import com.oracle.graal.api.meta.*;
26 import com.oracle.graal.compiler.common.*;
27 import com.oracle.graal.compiler.common.type.*;
28 import com.oracle.graal.graph.*;
29 import com.oracle.graal.graph.spi.*;
30 import com.oracle.graal.lir.amd64.*;
31 import com.oracle.graal.lir.gen.*;
32 import com.oracle.graal.nodeinfo.*;
33 import com.oracle.graal.nodes.*;
34 import com.oracle.graal.nodes.calc.*;
35 import com.oracle.graal.nodes.spi.*;
36
37 @NodeInfo
38 public final class AMD64MathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable {
39
40 public static final NodeClass<AMD64MathIntrinsicNode> TYPE = NodeClass.create(AMD64MathIntrinsicNode.class);
41 protected final Operation operation;
42
43 public enum Operation {
44 LOG,
45 LOG10,
46 SIN,
47 COS,
48 TAN
49 }
50
51 public Operation operation() {
52 return operation;
53 }
54
55 public static ValueNode create(ValueNode value, Operation op) {
56 ValueNode c = tryConstantFold(value, op);
57 if (c != null) {
58 return c;
59 }
60 return new AMD64MathIntrinsicNode(value, op);
61 }
62
63 protected static ValueNode tryConstantFold(ValueNode value, Operation op) {
64 if (value.isConstant()) {
65 double ret = doCompute(value.asJavaConstant().asDouble(), op);
66 return ConstantNode.forDouble(ret);
67 }
68 return null;
69 }
70
71 protected AMD64MathIntrinsicNode(ValueNode value, Operation op) {
72 super(TYPE, StampFactory.forKind(Kind.Double), value);
73 assert value.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp()) == 64;
74 this.operation = op;
75 }
76
77 @Override
78 public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator lirGen) {
79 AMD64ArithmeticLIRGenerator gen = (AMD64ArithmeticLIRGenerator) lirGen;
80 Value input = builder.operand(getValue());
81 Value result;
82 switch (operation()) {
83 case LOG:
84 result = gen.emitMathLog(input, false);
85 break;
86 case LOG10:
87 result = gen.emitMathLog(input, true);
88 break;
89 case SIN:
90 result = gen.emitMathSin(input);
91 break;
92 case COS:
93 result = gen.emitMathCos(input);
94 break;
95 case TAN:
96 result = gen.emitMathTan(input);
97 break;
98 default:
99 throw GraalInternalError.shouldNotReachHere();
100 }
101 builder.setResult(this, result);
102 }
103
104 @Override
105 public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
106 ValueNode c = tryConstantFold(forValue, operation());
107 if (c != null) {
108 return c;
109 }
110 return this;
111 }
112
113 @NodeIntrinsic
114 public static native double compute(double value, @ConstantNodeParameter Operation op);
115
116 private static double doCompute(double value, Operation op) {
117 switch (op) {
118 case LOG:
119 return Math.log(value);
120 case LOG10:
121 return Math.log10(value);
122 case SIN:
123 return Math.sin(value);
124 case COS:
125 return Math.cos(value);
126 case TAN:
127 return Math.tan(value);
128 default:
129 throw new GraalInternalError("unknown op %s", op);
130 }
131 }
132 }