1 /* 2 * Copyright (c) 2009, 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 24 25 26 package org.graalvm.compiler.core.sparc; 27 28 import static jdk.vm.ci.sparc.SPARCKind.BYTE; 29 import static jdk.vm.ci.sparc.SPARCKind.HWORD; 30 import static jdk.vm.ci.sparc.SPARCKind.WORD; 31 import static jdk.vm.ci.sparc.SPARCKind.XWORD; 32 33 import org.graalvm.compiler.core.common.LIRKind; 34 import org.graalvm.compiler.core.common.calc.CanonicalCondition; 35 import org.graalvm.compiler.core.common.calc.Condition; 36 import org.graalvm.compiler.core.gen.NodeMatchRules; 37 import org.graalvm.compiler.core.match.ComplexMatchResult; 38 import org.graalvm.compiler.core.match.MatchRule; 39 import org.graalvm.compiler.debug.GraalError; 40 import org.graalvm.compiler.lir.LIRFrameState; 41 import org.graalvm.compiler.lir.LabelRef; 42 import org.graalvm.compiler.lir.gen.LIRGeneratorTool; 43 import org.graalvm.compiler.lir.sparc.SPARCAddressValue; 44 import org.graalvm.compiler.nodes.DeoptimizingNode; 45 import org.graalvm.compiler.nodes.IfNode; 46 import org.graalvm.compiler.nodes.ValueNode; 47 import org.graalvm.compiler.nodes.calc.CompareNode; 48 import org.graalvm.compiler.nodes.calc.SignExtendNode; 49 import org.graalvm.compiler.nodes.calc.ZeroExtendNode; 50 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode; 51 import org.graalvm.compiler.nodes.memory.Access; 52 import org.graalvm.compiler.nodes.memory.LIRLowerableAccess; 53 54 import jdk.vm.ci.meta.JavaConstant; 55 import jdk.vm.ci.meta.Value; 56 import jdk.vm.ci.sparc.SPARCKind; 57 58 /** 59 * This class implements the SPARC specific portion of the LIR generator. 60 */ 61 public class SPARCNodeMatchRules extends NodeMatchRules { 62 63 public SPARCNodeMatchRules(LIRGeneratorTool gen) { 64 super(gen); 65 } 66 67 protected LIRFrameState getState(Access access) { 68 if (access instanceof DeoptimizingNode) { 69 return state((DeoptimizingNode) access); 70 } 71 return null; 72 } 73 74 protected LIRKind getLirKind(LIRLowerableAccess access) { 75 return gen.getLIRKind(access.getAccessStamp()); 76 } 77 78 private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) { 79 assert fromBits <= toBits && toBits <= 64; 80 SPARCKind toKind = null; 81 SPARCKind fromKind = null; 82 if (fromBits == toBits) { 83 return null; 84 } 85 toKind = toBits > 32 ? XWORD : WORD; 86 switch (fromBits) { 87 case 8: 88 fromKind = BYTE; 89 break; 90 case 16: 91 fromKind = HWORD; 92 break; 93 case 32: 94 fromKind = WORD; 95 break; 96 default: 97 throw GraalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); 98 } 99 SPARCKind localFromKind = fromKind; 100 SPARCKind localToKind = toKind; 101 return builder -> { 102 return getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), LIRKind.value(localToKind), operand(access.getAddress()), getState(access)); 103 }; 104 } 105 106 private ComplexMatchResult emitZeroExtendMemory(Access access, int fromBits, int toBits) { 107 assert fromBits <= toBits && toBits <= 64; 108 SPARCKind toKind = null; 109 SPARCKind fromKind = null; 110 if (fromBits == toBits) { 111 return null; 112 } 113 toKind = toBits > 32 ? XWORD : WORD; 114 switch (fromBits) { 115 case 8: 116 fromKind = BYTE; 117 break; 118 case 16: 119 fromKind = HWORD; 120 break; 121 case 32: 122 fromKind = WORD; 123 break; 124 default: 125 throw GraalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); 126 } 127 SPARCKind localFromKind = fromKind; 128 SPARCKind localToKind = toKind; 129 return builder -> { 130 // Loads are always zero extending load 131 return getLIRGeneratorTool().emitZeroExtendLoad(LIRKind.value(localFromKind), LIRKind.value(localToKind), operand(access.getAddress()), getState(access)); 132 }; 133 } 134 135 @MatchRule("(SignExtend Read=access)") 136 @MatchRule("(SignExtend FloatingRead=access)") 137 public ComplexMatchResult signExtend(SignExtendNode root, Access access) { 138 return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits()); 139 } 140 141 @MatchRule("(ZeroExtend Read=access)") 142 @MatchRule("(ZeroExtend FloatingRead=access)") 143 public ComplexMatchResult zeroExtend(ZeroExtendNode root, Access access) { 144 return emitZeroExtendMemory(access, root.getInputBits(), root.getResultBits()); 145 } 146 147 @MatchRule("(If (ObjectEquals=compare value LogicCompareAndSwap=cas))") 148 @MatchRule("(If (PointerEquals=compare value LogicCompareAndSwap=cas))") 149 @MatchRule("(If (FloatEquals=compare value LogicCompareAndSwap=cas))") 150 @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))") 151 public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) { 152 JavaConstant constant = value.asJavaConstant(); 153 assert compare.condition() == CanonicalCondition.EQ; 154 if (constant != null && cas.usages().count() == 1) { 155 long constantValue = constant.asLong(); 156 boolean successIsTrue; 157 if (constantValue == 0) { 158 successIsTrue = false; 159 } else if (constantValue == 1) { 160 successIsTrue = true; 161 } else { 162 return null; 163 } 164 return builder -> { 165 LIRKind kind = getLirKind(cas); 166 LabelRef trueLabel = getLIRBlock(root.trueSuccessor()); 167 LabelRef falseLabel = getLIRBlock(root.falseSuccessor()); 168 double trueLabelProbability = root.probability(root.trueSuccessor()); 169 Value expectedValue = operand(cas.getExpectedValue()); 170 Value newValue = operand(cas.getNewValue()); 171 SPARCAddressValue address = (SPARCAddressValue) operand(cas.getAddress()); 172 Condition condition = successIsTrue ? Condition.EQ : Condition.NE; 173 174 Value result = getLIRGeneratorTool().emitValueCompareAndSwap(kind, address, expectedValue, newValue); 175 getLIRGeneratorTool().emitCompareBranch(kind.getPlatformKind(), result, expectedValue, condition, false, trueLabel, falseLabel, trueLabelProbability); 176 return null; 177 }; 178 } 179 return null; 180 } 181 182 @Override 183 public SPARCLIRGenerator getLIRGeneratorTool() { 184 return (SPARCLIRGenerator) super.getLIRGeneratorTool(); 185 } 186 187 protected SPARCArithmeticLIRGenerator getArithmeticLIRGenerator() { 188 return (SPARCArithmeticLIRGenerator) getLIRGeneratorTool().getArithmetic(); 189 } 190 }