46 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; |
46 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; |
47 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; |
47 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; |
48 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; |
48 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; |
49 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; |
49 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; |
50 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; |
50 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; |
|
51 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp; |
51 import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; |
52 import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; |
|
53 import org.graalvm.compiler.asm.amd64.AVXKind; |
|
54 import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; |
52 import org.graalvm.compiler.core.common.LIRKind; |
55 import org.graalvm.compiler.core.common.LIRKind; |
53 import org.graalvm.compiler.core.common.NumUtil; |
56 import org.graalvm.compiler.core.common.NumUtil; |
54 import org.graalvm.compiler.core.common.calc.Condition; |
57 import org.graalvm.compiler.core.common.calc.Condition; |
55 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; |
58 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; |
56 import org.graalvm.compiler.core.common.spi.LIRKindTool; |
59 import org.graalvm.compiler.core.common.spi.LIRKindTool; |
59 import org.graalvm.compiler.lir.LIRFrameState; |
62 import org.graalvm.compiler.lir.LIRFrameState; |
60 import org.graalvm.compiler.lir.LIRInstruction; |
63 import org.graalvm.compiler.lir.LIRInstruction; |
61 import org.graalvm.compiler.lir.LIRValueUtil; |
64 import org.graalvm.compiler.lir.LIRValueUtil; |
62 import org.graalvm.compiler.lir.LabelRef; |
65 import org.graalvm.compiler.lir.LabelRef; |
63 import org.graalvm.compiler.lir.StandardOp.JumpOp; |
66 import org.graalvm.compiler.lir.StandardOp.JumpOp; |
64 import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp; |
67 import org.graalvm.compiler.lir.StandardOp.ZapRegistersOp; |
65 import org.graalvm.compiler.lir.SwitchStrategy; |
68 import org.graalvm.compiler.lir.SwitchStrategy; |
66 import org.graalvm.compiler.lir.Variable; |
69 import org.graalvm.compiler.lir.Variable; |
67 import org.graalvm.compiler.lir.amd64.AMD64AddressValue; |
70 import org.graalvm.compiler.lir.amd64.AMD64AddressValue; |
68 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool; |
71 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool; |
69 import org.graalvm.compiler.lir.amd64.AMD64ArrayCompareToOp; |
72 import org.graalvm.compiler.lir.amd64.AMD64ArrayCompareToOp; |
92 import org.graalvm.compiler.lir.amd64.AMD64PauseOp; |
95 import org.graalvm.compiler.lir.amd64.AMD64PauseOp; |
93 import org.graalvm.compiler.lir.amd64.AMD64StringLatin1InflateOp; |
96 import org.graalvm.compiler.lir.amd64.AMD64StringLatin1InflateOp; |
94 import org.graalvm.compiler.lir.amd64.AMD64StringUTF16CompressOp; |
97 import org.graalvm.compiler.lir.amd64.AMD64StringUTF16CompressOp; |
95 import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp; |
98 import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp; |
96 import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp; |
99 import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp; |
|
100 import org.graalvm.compiler.lir.amd64.AMD64ZeroMemoryOp; |
|
101 import org.graalvm.compiler.lir.amd64.vector.AMD64VectorCompareOp; |
97 import org.graalvm.compiler.lir.gen.LIRGenerationResult; |
102 import org.graalvm.compiler.lir.gen.LIRGenerationResult; |
98 import org.graalvm.compiler.lir.gen.LIRGenerator; |
103 import org.graalvm.compiler.lir.gen.LIRGenerator; |
99 import org.graalvm.compiler.lir.hashing.Hasher; |
104 import org.graalvm.compiler.lir.hashing.Hasher; |
100 import org.graalvm.compiler.phases.util.Providers; |
105 import org.graalvm.compiler.phases.util.Providers; |
101 |
106 |
402 Variable result = newVariable(trueValue.getValueKind()); |
407 Variable result = newVariable(trueValue.getValueKind()); |
403 append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue))); |
408 append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue))); |
404 return result; |
409 return result; |
405 } |
410 } |
406 |
411 |
|
412 private static AVXSize getRegisterSize(Value a) { |
|
413 AMD64Kind kind = (AMD64Kind) a.getPlatformKind(); |
|
414 if (kind.isXMM()) { |
|
415 return AVXKind.getRegisterSize(kind); |
|
416 } else { |
|
417 return AVXSize.XMM; |
|
418 } |
|
419 } |
|
420 |
407 private void emitIntegerTest(Value a, Value b) { |
421 private void emitIntegerTest(Value a, Value b) { |
408 assert ((AMD64Kind) a.getPlatformKind()).isInteger(); |
422 if (a.getPlatformKind().getVectorLength() > 1) { |
409 OperandSize size = a.getPlatformKind() == AMD64Kind.QWORD ? QWORD : DWORD; |
423 append(new AMD64VectorCompareOp(VexRMOp.VPTEST, getRegisterSize(a), asAllocatable(a), asAllocatable(b))); |
410 if (isJavaConstant(b) && NumUtil.is32bit(asJavaConstant(b).asLong())) { |
424 } else { |
411 append(new AMD64BinaryConsumer.ConstOp(AMD64MIOp.TEST, size, asAllocatable(a), (int) asJavaConstant(b).asLong())); |
425 assert ((AMD64Kind) a.getPlatformKind()).isInteger(); |
412 } else if (isJavaConstant(a) && NumUtil.is32bit(asJavaConstant(a).asLong())) { |
426 OperandSize size = a.getPlatformKind() == AMD64Kind.QWORD ? QWORD : DWORD; |
413 append(new AMD64BinaryConsumer.ConstOp(AMD64MIOp.TEST, size, asAllocatable(b), (int) asJavaConstant(a).asLong())); |
427 if (isJavaConstant(b) && NumUtil.is32bit(asJavaConstant(b).asLong())) { |
414 } else if (isAllocatableValue(b)) { |
428 append(new AMD64BinaryConsumer.ConstOp(AMD64MIOp.TEST, size, asAllocatable(a), (int) asJavaConstant(b).asLong())); |
415 append(new AMD64BinaryConsumer.Op(AMD64RMOp.TEST, size, asAllocatable(b), asAllocatable(a))); |
429 } else if (isJavaConstant(a) && NumUtil.is32bit(asJavaConstant(a).asLong())) { |
416 } else { |
430 append(new AMD64BinaryConsumer.ConstOp(AMD64MIOp.TEST, size, asAllocatable(b), (int) asJavaConstant(a).asLong())); |
417 append(new AMD64BinaryConsumer.Op(AMD64RMOp.TEST, size, asAllocatable(a), asAllocatable(b))); |
431 } else if (isAllocatableValue(b)) { |
|
432 append(new AMD64BinaryConsumer.Op(AMD64RMOp.TEST, size, asAllocatable(b), asAllocatable(a))); |
|
433 } else { |
|
434 append(new AMD64BinaryConsumer.Op(AMD64RMOp.TEST, size, asAllocatable(a), asAllocatable(b))); |
|
435 } |
418 } |
436 } |
419 } |
437 } |
420 |
438 |
421 /** |
439 /** |
422 * This method emits the compare against memory instruction, and may reorder the operands. It |
440 * This method emits the compare against memory instruction, and may reorder the operands. It |
545 emitMove(result, raxRes); |
563 emitMove(result, raxRes); |
546 return result; |
564 return result; |
547 } |
565 } |
548 |
566 |
549 @Override |
567 @Override |
550 public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) { |
568 public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, boolean directPointers) { |
551 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); |
569 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); |
552 append(new AMD64ArrayEqualsOp(this, kind, kind, result, array1, array2, asAllocatable(length), constantLength, directPointers, getMaxVectorSize())); |
570 append(new AMD64ArrayEqualsOp(this, kind, kind, result, array1, array2, length, directPointers, getMaxVectorSize())); |
553 return result; |
571 return result; |
554 } |
572 } |
555 |
573 |
556 @Override |
574 @Override |
557 public Variable emitArrayEquals(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length, int constantLength, boolean directPointers) { |
575 public Variable emitArrayEquals(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length, boolean directPointers) { |
558 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); |
576 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); |
559 append(new AMD64ArrayEqualsOp(this, kind1, kind2, result, array1, array2, asAllocatable(length), constantLength, directPointers, getMaxVectorSize())); |
577 append(new AMD64ArrayEqualsOp(this, kind1, kind2, result, array1, array2, length, directPointers, getMaxVectorSize())); |
560 return result; |
578 return result; |
561 } |
|
562 |
|
563 /** |
|
564 * Return a conservative estimate of the page size for use by the String.indexOf intrinsic. |
|
565 */ |
|
566 protected int getVMPageSize() { |
|
567 return 4096; |
|
568 } |
579 } |
569 |
580 |
570 /** |
581 /** |
571 * Return the maximum size of vector registers used in SSE/AVX instructions. |
582 * Return the maximum size of vector registers used in SSE/AVX instructions. |
572 */ |
583 */ |
659 public void emitPause() { |
670 public void emitPause() { |
660 append(new AMD64PauseOp()); |
671 append(new AMD64PauseOp()); |
661 } |
672 } |
662 |
673 |
663 @Override |
674 @Override |
664 public SaveRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) { |
675 public ZapRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) { |
665 return new AMD64ZapRegistersOp(zappedRegisters, zapValues); |
676 return new AMD64ZapRegistersOp(zappedRegisters, zapValues); |
666 } |
677 } |
667 |
678 |
668 @Override |
679 @Override |
669 public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) { |
680 public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) { |