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 package org.graalvm.compiler.core.amd64;
25
26 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
27 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
28 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR;
29 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB;
30 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
31 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
32 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
33 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
34 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD;
35 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
36 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD;
37 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS;
38
39 import org.graalvm.compiler.core.common.NumUtil;
40 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
41 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
42 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp;
43 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp;
44 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
45 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
46 import org.graalvm.compiler.core.common.LIRKind;
47 import org.graalvm.compiler.core.common.calc.Condition;
48 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
49 import org.graalvm.compiler.core.gen.NodeMatchRules;
50 import org.graalvm.compiler.core.match.ComplexMatchResult;
51 import org.graalvm.compiler.core.match.MatchRule;
52 import org.graalvm.compiler.debug.Debug;
53 import org.graalvm.compiler.debug.GraalError;
54 import org.graalvm.compiler.lir.LIRFrameState;
55 import org.graalvm.compiler.lir.LIRValueUtil;
56 import org.graalvm.compiler.lir.LabelRef;
57 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
58 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
59 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
60 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
61 import org.graalvm.compiler.nodes.ConstantNode;
62 import org.graalvm.compiler.nodes.DeoptimizingNode;
63 import org.graalvm.compiler.nodes.IfNode;
64 import org.graalvm.compiler.nodes.ValueNode;
65 import org.graalvm.compiler.nodes.calc.CompareNode;
66 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
67 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
68 import org.graalvm.compiler.nodes.calc.NarrowNode;
69 import org.graalvm.compiler.nodes.calc.ReinterpretNode;
70 import org.graalvm.compiler.nodes.calc.SignExtendNode;
71 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
72 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
130 protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
131 Condition cond = compare.condition();
132 AMD64Kind kind = getMemoryKind(access);
133 boolean matchedAsConstant = false; // For assertion checking
134
135 if (value.isConstant()) {
136 JavaConstant constant = value.asJavaConstant();
137 if (constant != null) {
138 if (kind == AMD64Kind.QWORD && !constant.getJavaKind().isObject() && !NumUtil.isInt(constant.asLong())) {
139 // Only imm32 as long
140 return null;
141 }
142 // A QWORD that can be encoded as int can be embedded as a constant
143 matchedAsConstant = kind == AMD64Kind.QWORD && !constant.getJavaKind().isObject() && NumUtil.isInt(constant.asLong());
144 }
145 if (kind == AMD64Kind.DWORD) {
146 // Any DWORD value should be embeddable as a constant
147 matchedAsConstant = true;
148 }
149 if (kind.isXMM()) {
150 Debug.log("Skipping constant compares for float kinds");
151 return null;
152 }
153 }
154 boolean matchedAsConstantFinal = matchedAsConstant;
155
156 /*
157 * emitCompareBranchMemory expects the memory on the right, so mirror the condition if
158 * that's not true. It might be mirrored again the actual compare is emitted but that's ok.
159 */
160 Condition finalCondition = GraphUtil.unproxify(compare.getX()) == access ? cond.mirror() : cond;
161 return new ComplexMatchResult() {
162 @Override
163 public Value evaluate(NodeLIRBuilder builder) {
164 LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
165 LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
166 boolean unorderedIsTrue = compare.unorderedIsTrue();
167 double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
168 Value other = operand(value);
169 /*
170 * Check that patterns which were matched as a constant actually end up seeing a
|
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 package org.graalvm.compiler.core.amd64;
25
26 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
27 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
28 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR;
29 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB;
30 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
31 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
32 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
33 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
34 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD;
35 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
36 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD;
37 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS;
38
39 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
40 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
41 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp;
42 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp;
43 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
44 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
45 import org.graalvm.compiler.core.common.LIRKind;
46 import org.graalvm.compiler.core.common.NumUtil;
47 import org.graalvm.compiler.core.common.calc.Condition;
48 import org.graalvm.compiler.core.gen.NodeLIRBuilder;
49 import org.graalvm.compiler.core.gen.NodeMatchRules;
50 import org.graalvm.compiler.core.match.ComplexMatchResult;
51 import org.graalvm.compiler.core.match.MatchRule;
52 import org.graalvm.compiler.debug.GraalError;
53 import org.graalvm.compiler.lir.LIRFrameState;
54 import org.graalvm.compiler.lir.LIRValueUtil;
55 import org.graalvm.compiler.lir.LabelRef;
56 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
57 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
58 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
59 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
60 import org.graalvm.compiler.nodes.ConstantNode;
61 import org.graalvm.compiler.nodes.DeoptimizingNode;
62 import org.graalvm.compiler.nodes.IfNode;
63 import org.graalvm.compiler.nodes.ValueNode;
64 import org.graalvm.compiler.nodes.calc.CompareNode;
65 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
66 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
67 import org.graalvm.compiler.nodes.calc.NarrowNode;
68 import org.graalvm.compiler.nodes.calc.ReinterpretNode;
69 import org.graalvm.compiler.nodes.calc.SignExtendNode;
70 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
71 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
129 protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
130 Condition cond = compare.condition();
131 AMD64Kind kind = getMemoryKind(access);
132 boolean matchedAsConstant = false; // For assertion checking
133
134 if (value.isConstant()) {
135 JavaConstant constant = value.asJavaConstant();
136 if (constant != null) {
137 if (kind == AMD64Kind.QWORD && !constant.getJavaKind().isObject() && !NumUtil.isInt(constant.asLong())) {
138 // Only imm32 as long
139 return null;
140 }
141 // A QWORD that can be encoded as int can be embedded as a constant
142 matchedAsConstant = kind == AMD64Kind.QWORD && !constant.getJavaKind().isObject() && NumUtil.isInt(constant.asLong());
143 }
144 if (kind == AMD64Kind.DWORD) {
145 // Any DWORD value should be embeddable as a constant
146 matchedAsConstant = true;
147 }
148 if (kind.isXMM()) {
149 ifNode.getDebug().log("Skipping constant compares for float kinds");
150 return null;
151 }
152 }
153 boolean matchedAsConstantFinal = matchedAsConstant;
154
155 /*
156 * emitCompareBranchMemory expects the memory on the right, so mirror the condition if
157 * that's not true. It might be mirrored again the actual compare is emitted but that's ok.
158 */
159 Condition finalCondition = GraphUtil.unproxify(compare.getX()) == access ? cond.mirror() : cond;
160 return new ComplexMatchResult() {
161 @Override
162 public Value evaluate(NodeLIRBuilder builder) {
163 LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
164 LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
165 boolean unorderedIsTrue = compare.unorderedIsTrue();
166 double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
167 Value other = operand(value);
168 /*
169 * Check that patterns which were matched as a constant actually end up seeing a
|