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.NodeView;
65 import org.graalvm.compiler.nodes.ValueNode;
66 import org.graalvm.compiler.nodes.calc.CompareNode;
67 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
68 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
69 import org.graalvm.compiler.nodes.calc.NarrowNode;
70 import org.graalvm.compiler.nodes.calc.ReinterpretNode;
71 import org.graalvm.compiler.nodes.calc.SignExtendNode;
72 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
73 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
74 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
75 import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
76 import org.graalvm.compiler.nodes.memory.Access;
77 import org.graalvm.compiler.nodes.memory.LIRLowerableAccess;
78 import org.graalvm.compiler.nodes.memory.WriteNode;
79 import org.graalvm.compiler.nodes.util.GraphUtil;
80
81 import jdk.vm.ci.amd64.AMD64Kind;
82 import jdk.vm.ci.meta.AllocatableValue;
83 import jdk.vm.ci.meta.JavaConstant;
84 import jdk.vm.ci.meta.PlatformKind;
85 import jdk.vm.ci.meta.Value;
86 import jdk.vm.ci.meta.ValueKind;
87
88 public class AMD64NodeMatchRules extends NodeMatchRules {
89
90 public AMD64NodeMatchRules(LIRGeneratorTool gen) {
91 super(gen);
92 }
93
94 protected LIRFrameState getState(Access access) {
95 if (access instanceof DeoptimizingNode) {
96 return state((DeoptimizingNode) access);
97 }
98 return null;
99 }
100
101 protected AMD64Kind getMemoryKind(LIRLowerableAccess access) {
102 return (AMD64Kind) getLirKind(access).getPlatformKind();
103 }
253 break;
254 case 16:
255 op = MOVSX;
256 break;
257 case 32:
258 return null;
259 default:
260 throw GraalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
261 }
262 }
263 if (kind != null && op != null) {
264 return emitConvertMemoryOp(kind, op, size, access, addressKind);
265 }
266 return null;
267 }
268
269 private Value emitReinterpretMemory(LIRKind to, Access access) {
270 AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
271 LIRFrameState state = getState(access);
272 return getArithmeticLIRGenerator().emitLoad(to, address, state);
273 }
274
275 @MatchRule("(If (IntegerTest Read=access value))")
276 @MatchRule("(If (IntegerTest FloatingRead=access value))")
277 public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
278 return emitIntegerTestBranchMemory(root, value, access);
279 }
280
281 @MatchRule("(If (IntegerEquals=compare value Read=access))")
282 @MatchRule("(If (IntegerLessThan=compare value Read=access))")
283 @MatchRule("(If (IntegerBelow=compare value Read=access))")
284 @MatchRule("(If (IntegerEquals=compare value FloatingRead=access))")
285 @MatchRule("(If (IntegerLessThan=compare value FloatingRead=access))")
286 @MatchRule("(If (IntegerBelow=compare value FloatingRead=access))")
287 @MatchRule("(If (FloatEquals=compare value Read=access))")
288 @MatchRule("(If (FloatEquals=compare value FloatingRead=access))")
289 @MatchRule("(If (FloatLessThan=compare value Read=access))")
290 @MatchRule("(If (FloatLessThan=compare value FloatingRead=access))")
291 @MatchRule("(If (PointerEquals=compare value Read=access))")
292 @MatchRule("(If (PointerEquals=compare value FloatingRead=access))")
|
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.NodeView;
65 import org.graalvm.compiler.nodes.ValueNode;
66 import org.graalvm.compiler.nodes.calc.CompareNode;
67 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
68 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
69 import org.graalvm.compiler.nodes.calc.NarrowNode;
70 import org.graalvm.compiler.nodes.calc.ReinterpretNode;
71 import org.graalvm.compiler.nodes.calc.SignExtendNode;
72 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
73 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
74 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
75 import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
76 import org.graalvm.compiler.nodes.memory.Access;
77 import org.graalvm.compiler.nodes.memory.LIRLowerableAccess;
78 import org.graalvm.compiler.nodes.memory.WriteNode;
79 import org.graalvm.compiler.nodes.util.GraphUtil;
80
81 import jdk.vm.ci.amd64.AMD64;
82 import jdk.vm.ci.amd64.AMD64.CPUFeature;
83 import jdk.vm.ci.amd64.AMD64Kind;
84 import jdk.vm.ci.meta.AllocatableValue;
85 import jdk.vm.ci.meta.JavaConstant;
86 import jdk.vm.ci.meta.JavaKind;
87 import jdk.vm.ci.meta.PlatformKind;
88 import jdk.vm.ci.meta.Value;
89 import jdk.vm.ci.meta.ValueKind;
90
91 public class AMD64NodeMatchRules extends NodeMatchRules {
92
93 public AMD64NodeMatchRules(LIRGeneratorTool gen) {
94 super(gen);
95 }
96
97 protected LIRFrameState getState(Access access) {
98 if (access instanceof DeoptimizingNode) {
99 return state((DeoptimizingNode) access);
100 }
101 return null;
102 }
103
104 protected AMD64Kind getMemoryKind(LIRLowerableAccess access) {
105 return (AMD64Kind) getLirKind(access).getPlatformKind();
106 }
256 break;
257 case 16:
258 op = MOVSX;
259 break;
260 case 32:
261 return null;
262 default:
263 throw GraalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
264 }
265 }
266 if (kind != null && op != null) {
267 return emitConvertMemoryOp(kind, op, size, access, addressKind);
268 }
269 return null;
270 }
271
272 private Value emitReinterpretMemory(LIRKind to, Access access) {
273 AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
274 LIRFrameState state = getState(access);
275 return getArithmeticLIRGenerator().emitLoad(to, address, state);
276 }
277
278 private boolean supports(CPUFeature feature) {
279 return ((AMD64) getLIRGeneratorTool().target().arch).getFeatures().contains(feature);
280 }
281
282 @MatchRule("(And (Not a) b)")
283 public ComplexMatchResult logicalAndNot(ValueNode a, ValueNode b) {
284 if (!supports(CPUFeature.BMI1)) {
285 return null;
286 }
287 return builder -> getArithmeticLIRGenerator().emitLogicalAndNot(operand(a), operand(b));
288 }
289
290 @MatchRule("(And a (Negate a))")
291 public ComplexMatchResult lowestSetIsolatedBit(ValueNode a) {
292 if (!supports(CPUFeature.BMI1)) {
293 return null;
294 }
295 return builder -> getArithmeticLIRGenerator().emitLowestSetIsolatedBit(operand(a));
296 }
297
298 @MatchRule("(Xor a (Add a b))")
299 public ComplexMatchResult getMaskUpToLowestSetBit(ValueNode a, ValueNode b) {
300 if (!supports(CPUFeature.BMI1)) {
301 return null;
302 }
303
304 // Make sure that the pattern matches a subtraction by one.
305 if (!b.isJavaConstant()) {
306 return null;
307 }
308
309 JavaConstant bCst = b.asJavaConstant();
310 long bValue;
311 if (bCst.getJavaKind() == JavaKind.Int) {
312 bValue = bCst.asInt();
313 } else if (bCst.getJavaKind() == JavaKind.Long) {
314 bValue = bCst.asLong();
315 } else {
316 return null;
317 }
318
319 if (bValue == -1) {
320 return builder -> getArithmeticLIRGenerator().emitGetMaskUpToLowestSetBit(operand(a));
321 } else {
322 return null;
323 }
324 }
325
326 @MatchRule("(And a (Add a b))")
327 public ComplexMatchResult resetLowestSetBit(ValueNode a, ValueNode b) {
328 if (!supports(CPUFeature.BMI1)) {
329 return null;
330 }
331 // Make sure that the pattern matches a subtraction by one.
332 if (!b.isJavaConstant()) {
333 return null;
334 }
335
336 JavaConstant bCst = b.asJavaConstant();
337 long bValue;
338 if (bCst.getJavaKind() == JavaKind.Int) {
339 bValue = bCst.asInt();
340 } else if (bCst.getJavaKind() == JavaKind.Long) {
341 bValue = bCst.asLong();
342 } else {
343 return null;
344 }
345
346 if (bValue == -1) {
347 return builder -> getArithmeticLIRGenerator().emitResetLowestSetBit(operand(a));
348 } else {
349 return null;
350 }
351 }
352
353 @MatchRule("(If (IntegerTest Read=access value))")
354 @MatchRule("(If (IntegerTest FloatingRead=access value))")
355 public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
356 return emitIntegerTestBranchMemory(root, value, access);
357 }
358
359 @MatchRule("(If (IntegerEquals=compare value Read=access))")
360 @MatchRule("(If (IntegerLessThan=compare value Read=access))")
361 @MatchRule("(If (IntegerBelow=compare value Read=access))")
362 @MatchRule("(If (IntegerEquals=compare value FloatingRead=access))")
363 @MatchRule("(If (IntegerLessThan=compare value FloatingRead=access))")
364 @MatchRule("(If (IntegerBelow=compare value FloatingRead=access))")
365 @MatchRule("(If (FloatEquals=compare value Read=access))")
366 @MatchRule("(If (FloatEquals=compare value FloatingRead=access))")
367 @MatchRule("(If (FloatLessThan=compare value Read=access))")
368 @MatchRule("(If (FloatLessThan=compare value FloatingRead=access))")
369 @MatchRule("(If (PointerEquals=compare value Read=access))")
370 @MatchRule("(If (PointerEquals=compare value FloatingRead=access))")
|