31 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB; |
31 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB; |
32 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR; |
32 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR; |
33 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX; |
33 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX; |
34 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB; |
34 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB; |
35 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD; |
35 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD; |
|
36 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VADDSD; |
|
37 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VADDSS; |
|
38 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMULSD; |
|
39 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMULSS; |
|
40 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSD; |
|
41 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSS; |
36 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; |
42 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; |
37 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; |
43 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; |
38 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD; |
44 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD; |
39 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS; |
45 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS; |
40 |
46 |
|
47 import org.graalvm.compiler.asm.amd64.AMD64Assembler; |
41 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; |
48 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; |
42 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; |
49 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; |
43 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; |
50 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; |
44 import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; |
51 import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; |
45 import org.graalvm.compiler.core.common.LIRKind; |
52 import org.graalvm.compiler.core.common.LIRKind; |
378 @MatchRule("(If (PointerEquals=compare value ValueCompareAndSwap=cas))") |
385 @MatchRule("(If (PointerEquals=compare value ValueCompareAndSwap=cas))") |
379 @MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))") |
386 @MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))") |
380 @MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))") |
387 @MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))") |
381 public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) { |
388 public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) { |
382 assert compare.condition() == CanonicalCondition.EQ; |
389 assert compare.condition() == CanonicalCondition.EQ; |
383 if (value == cas.getExpectedValue() && cas.usages().count() == 1) { |
390 if (value == cas.getExpectedValue() && cas.hasExactlyOneUsage()) { |
384 return builder -> { |
391 return builder -> { |
385 LIRKind kind = getLirKind(cas); |
392 LIRKind kind = getLirKind(cas); |
386 LabelRef trueLabel = getLIRBlock(root.trueSuccessor()); |
393 LabelRef trueLabel = getLIRBlock(root.trueSuccessor()); |
387 LabelRef falseLabel = getLIRBlock(root.falseSuccessor()); |
394 LabelRef falseLabel = getLIRBlock(root.falseSuccessor()); |
388 double trueLabelProbability = root.probability(root.trueSuccessor()); |
395 double trueLabelProbability = root.probability(root.trueSuccessor()); |
401 @MatchRule("(If (FloatEquals=compare value LogicCompareAndSwap=cas))") |
408 @MatchRule("(If (FloatEquals=compare value LogicCompareAndSwap=cas))") |
402 @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))") |
409 @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))") |
403 public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) { |
410 public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) { |
404 JavaConstant constant = value.asJavaConstant(); |
411 JavaConstant constant = value.asJavaConstant(); |
405 assert compare.condition() == CanonicalCondition.EQ; |
412 assert compare.condition() == CanonicalCondition.EQ; |
406 if (constant != null && cas.usages().count() == 1) { |
413 if (constant != null && cas.hasExactlyOneUsage()) { |
407 long constantValue = constant.asLong(); |
414 long constantValue = constant.asLong(); |
408 boolean successIsTrue; |
415 boolean successIsTrue; |
409 if (constantValue == 0) { |
416 if (constantValue == 0) { |
410 successIsTrue = false; |
417 successIsTrue = false; |
411 } else if (constantValue == 1) { |
418 } else if (constantValue == 1) { |
461 private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode value, LIRLowerableAccess access) { |
468 private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode value, LIRLowerableAccess access) { |
462 return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), |
469 return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), |
463 getState(access)); |
470 getState(access)); |
464 } |
471 } |
465 |
472 |
|
473 private ComplexMatchResult binaryRead(AMD64Assembler.VexRVMOp op, OperandSize size, ValueNode value, LIRLowerableAccess access) { |
|
474 assert size == SS || size == SD; |
|
475 return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), |
|
476 getState(access)); |
|
477 } |
|
478 |
466 @MatchRule("(Add value Read=access)") |
479 @MatchRule("(Add value Read=access)") |
467 @MatchRule("(Add value FloatingRead=access)") |
480 @MatchRule("(Add value FloatingRead=access)") |
468 public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) { |
481 public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) { |
469 OperandSize size = getMemorySize(access); |
482 OperandSize size = getMemorySize(access); |
470 if (size.isXmmType()) { |
483 if (size.isXmmType()) { |
471 return binaryRead(SSEOp.ADD, size, value, access); |
484 if (getArithmeticLIRGenerator().supportAVX()) { |
|
485 return binaryRead(size == SS ? VADDSS : VADDSD, size, value, access); |
|
486 } else { |
|
487 return binaryRead(SSEOp.ADD, size, value, access); |
|
488 } |
472 } else { |
489 } else { |
473 return binaryRead(ADD.getRMOpcode(size), size, value, access); |
490 return binaryRead(ADD.getRMOpcode(size), size, value, access); |
474 } |
491 } |
475 } |
492 } |
476 |
493 |
477 @MatchRule("(Sub value Read=access)") |
494 @MatchRule("(Sub value Read=access)") |
478 @MatchRule("(Sub value FloatingRead=access)") |
495 @MatchRule("(Sub value FloatingRead=access)") |
479 public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) { |
496 public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) { |
480 OperandSize size = getMemorySize(access); |
497 OperandSize size = getMemorySize(access); |
481 if (size.isXmmType()) { |
498 if (size.isXmmType()) { |
482 return binaryRead(SSEOp.SUB, size, value, access); |
499 if (getArithmeticLIRGenerator().supportAVX()) { |
|
500 return binaryRead(size == SS ? VSUBSS : VSUBSD, size, value, access); |
|
501 } else { |
|
502 return binaryRead(SSEOp.SUB, size, value, access); |
|
503 } |
483 } else { |
504 } else { |
484 return binaryRead(SUB.getRMOpcode(size), size, value, access); |
505 return binaryRead(SUB.getRMOpcode(size), size, value, access); |
485 } |
506 } |
486 } |
507 } |
487 |
508 |
488 @MatchRule("(Mul value Read=access)") |
509 @MatchRule("(Mul value Read=access)") |
489 @MatchRule("(Mul value FloatingRead=access)") |
510 @MatchRule("(Mul value FloatingRead=access)") |
490 public ComplexMatchResult mulMemory(ValueNode value, LIRLowerableAccess access) { |
511 public ComplexMatchResult mulMemory(ValueNode value, LIRLowerableAccess access) { |
491 OperandSize size = getMemorySize(access); |
512 OperandSize size = getMemorySize(access); |
492 if (size.isXmmType()) { |
513 if (size.isXmmType()) { |
493 return binaryRead(SSEOp.MUL, size, value, access); |
514 if (getArithmeticLIRGenerator().supportAVX()) { |
|
515 return binaryRead(size == SS ? VMULSS : VMULSD, size, value, access); |
|
516 } else { |
|
517 return binaryRead(SSEOp.MUL, size, value, access); |
|
518 } |
494 } else { |
519 } else { |
495 return binaryRead(AMD64RMOp.IMUL, size, value, access); |
520 return binaryRead(AMD64RMOp.IMUL, size, value, access); |
496 } |
521 } |
497 } |
522 } |
498 |
523 |