20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 26 package org.graalvm.compiler.core.aarch64; 27 28 import jdk.vm.ci.meta.AllocatableValue; 29 import jdk.vm.ci.meta.JavaKind; 30 import jdk.vm.ci.meta.Value; 31 import jdk.internal.vm.compiler.collections.EconomicMap; 32 import jdk.internal.vm.compiler.collections.Equivalence; 33 import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler; 34 import org.graalvm.compiler.core.common.LIRKind; 35 import org.graalvm.compiler.core.gen.NodeMatchRules; 36 import org.graalvm.compiler.core.match.ComplexMatchResult; 37 import org.graalvm.compiler.core.match.MatchRule; 38 import org.graalvm.compiler.graph.Node; 39 import org.graalvm.compiler.lir.LIRFrameState; 40 import org.graalvm.compiler.lir.Variable; 41 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp; 42 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; 43 import org.graalvm.compiler.nodes.ConstantNode; 44 import org.graalvm.compiler.nodes.DeoptimizingNode; 45 import org.graalvm.compiler.nodes.NodeView; 46 import org.graalvm.compiler.nodes.ValueNode; 47 import org.graalvm.compiler.nodes.calc.AddNode; 48 import org.graalvm.compiler.nodes.calc.AndNode; 49 import org.graalvm.compiler.nodes.calc.BinaryNode; 50 import org.graalvm.compiler.nodes.calc.LeftShiftNode; 51 import org.graalvm.compiler.nodes.calc.NotNode; 52 import org.graalvm.compiler.nodes.calc.OrNode; 53 import org.graalvm.compiler.nodes.calc.RightShiftNode; 54 import org.graalvm.compiler.nodes.calc.SubNode; 55 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode; 56 import org.graalvm.compiler.nodes.calc.XorNode; 57 import org.graalvm.compiler.nodes.memory.Access; 58 59 import jdk.vm.ci.aarch64.AArch64Kind; 60 61 public class AArch64NodeMatchRules extends NodeMatchRules { 62 private static final EconomicMap<Class<? extends Node>, AArch64ArithmeticOp> nodeOpMap; 63 64 private static final EconomicMap<Class<? extends BinaryNode>, AArch64MacroAssembler.ShiftType> shiftTypeMap; 159 if (a.getStackKind().isNumericInteger() && b.getStackKind().isNumericInteger()) { 160 return builder -> getArithmeticLIRGenerator().emitMNeg(operand(a), operand(b)); 161 } 162 return null; 163 } 164 165 @MatchRule("(Add=binary (Mul a b) c)") 166 @MatchRule("(Sub=binary c (Mul a b))") 167 public ComplexMatchResult multiplyAddSub(BinaryNode binary, ValueNode a, ValueNode b, ValueNode c) { 168 JavaKind kindA = a.getStackKind(); 169 JavaKind kindB = b.getStackKind(); 170 JavaKind kindC = c.getStackKind(); 171 if (!kindA.isNumericInteger() || !kindB.isNumericInteger() || !kindC.isNumericInteger()) { 172 return null; 173 } 174 175 if (binary instanceof AddNode) { 176 return builder -> getArithmeticLIRGenerator().emitMAdd(operand(a), operand(b), operand(c)); 177 } 178 return builder -> getArithmeticLIRGenerator().emitMSub(operand(a), operand(b), operand(c)); 179 } 180 181 @Override 182 public AArch64LIRGenerator getLIRGeneratorTool() { 183 return (AArch64LIRGenerator) gen; 184 } 185 186 protected AArch64ArithmeticLIRGenerator getArithmeticLIRGenerator() { 187 return (AArch64ArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic(); 188 } 189 } | 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 26 package org.graalvm.compiler.core.aarch64; 27 28 import jdk.vm.ci.meta.AllocatableValue; 29 import jdk.vm.ci.meta.JavaKind; 30 import jdk.vm.ci.meta.Value; 31 import jdk.internal.vm.compiler.collections.EconomicMap; 32 import jdk.internal.vm.compiler.collections.Equivalence; 33 import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler; 34 import org.graalvm.compiler.core.common.LIRKind; 35 import org.graalvm.compiler.core.gen.NodeMatchRules; 36 import org.graalvm.compiler.core.match.ComplexMatchResult; 37 import org.graalvm.compiler.core.match.MatchRule; 38 import org.graalvm.compiler.graph.Node; 39 import org.graalvm.compiler.lir.LIRFrameState; 40 import org.graalvm.compiler.lir.LabelRef; 41 import org.graalvm.compiler.lir.Variable; 42 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp; 43 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow; 44 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; 45 import org.graalvm.compiler.nodes.ConstantNode; 46 import org.graalvm.compiler.nodes.DeoptimizingNode; 47 import org.graalvm.compiler.nodes.IfNode; 48 import org.graalvm.compiler.nodes.NodeView; 49 import org.graalvm.compiler.nodes.ValueNode; 50 import org.graalvm.compiler.nodes.calc.AddNode; 51 import org.graalvm.compiler.nodes.calc.AndNode; 52 import org.graalvm.compiler.nodes.calc.BinaryNode; 53 import org.graalvm.compiler.nodes.calc.LeftShiftNode; 54 import org.graalvm.compiler.nodes.calc.NotNode; 55 import org.graalvm.compiler.nodes.calc.OrNode; 56 import org.graalvm.compiler.nodes.calc.RightShiftNode; 57 import org.graalvm.compiler.nodes.calc.SubNode; 58 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode; 59 import org.graalvm.compiler.nodes.calc.XorNode; 60 import org.graalvm.compiler.nodes.memory.Access; 61 62 import jdk.vm.ci.aarch64.AArch64Kind; 63 64 public class AArch64NodeMatchRules extends NodeMatchRules { 65 private static final EconomicMap<Class<? extends Node>, AArch64ArithmeticOp> nodeOpMap; 66 67 private static final EconomicMap<Class<? extends BinaryNode>, AArch64MacroAssembler.ShiftType> shiftTypeMap; 162 if (a.getStackKind().isNumericInteger() && b.getStackKind().isNumericInteger()) { 163 return builder -> getArithmeticLIRGenerator().emitMNeg(operand(a), operand(b)); 164 } 165 return null; 166 } 167 168 @MatchRule("(Add=binary (Mul a b) c)") 169 @MatchRule("(Sub=binary c (Mul a b))") 170 public ComplexMatchResult multiplyAddSub(BinaryNode binary, ValueNode a, ValueNode b, ValueNode c) { 171 JavaKind kindA = a.getStackKind(); 172 JavaKind kindB = b.getStackKind(); 173 JavaKind kindC = c.getStackKind(); 174 if (!kindA.isNumericInteger() || !kindB.isNumericInteger() || !kindC.isNumericInteger()) { 175 return null; 176 } 177 178 if (binary instanceof AddNode) { 179 return builder -> getArithmeticLIRGenerator().emitMAdd(operand(a), operand(b), operand(c)); 180 } 181 return builder -> getArithmeticLIRGenerator().emitMSub(operand(a), operand(b), operand(c)); 182 } 183 184 /** 185 * ((x & (1 << n)) == 0) -> tbz/tbnz n label. 186 */ 187 @MatchRule("(If (IntegerTest value Constant=a))") 188 public ComplexMatchResult testBitAndBranch(IfNode root, ValueNode value, ConstantNode a) { 189 if (value.getStackKind().isNumericInteger()) { 190 long constant = a.asJavaConstant().asLong(); 191 if (Long.bitCount(constant) == 1) { 192 int bitToTest = Long.numberOfTrailingZeros(constant); 193 return builder -> { 194 LabelRef trueDestination = getLIRBlock(root.trueSuccessor()); 195 LabelRef falseDestination = getLIRBlock(root.falseSuccessor()); 196 AllocatableValue src = moveSp(gen.asAllocatable(operand(value))); 197 double trueDestinationProbability = root.getTrueSuccessorProbability(); 198 gen.append(new AArch64ControlFlow.BitTestAndBranchOp(trueDestination, falseDestination, src, trueDestinationProbability, bitToTest)); 199 return null; 200 }; 201 } 202 } 203 return null; 204 } 205 206 @Override 207 public AArch64LIRGenerator getLIRGeneratorTool() { 208 return (AArch64LIRGenerator) gen; 209 } 210 211 protected AArch64ArithmeticLIRGenerator getArithmeticLIRGenerator() { 212 return (AArch64ArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic(); 213 } 214 } |