70 import org.graalvm.compiler.lir.amd64.AMD64Binary;
71 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
72 import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp;
73 import org.graalvm.compiler.lir.amd64.AMD64Call;
74 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow;
75 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
76 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp;
77 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
78 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
79 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
80 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
81 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
82 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
83 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
84 import org.graalvm.compiler.lir.amd64.AMD64LFenceOp;
85 import org.graalvm.compiler.lir.amd64.AMD64Move;
86 import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
87 import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp;
88 import org.graalvm.compiler.lir.amd64.AMD64Move.StackLeaOp;
89 import org.graalvm.compiler.lir.amd64.AMD64PauseOp;
90 import org.graalvm.compiler.lir.amd64.AMD64StringIndexOfOp;
91 import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp;
92 import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp;
93 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
94 import org.graalvm.compiler.lir.gen.LIRGenerator;
95 import org.graalvm.compiler.phases.util.Providers;
96
97 import jdk.vm.ci.amd64.AMD64;
98 import jdk.vm.ci.amd64.AMD64Kind;
99 import jdk.vm.ci.code.CallingConvention;
100 import jdk.vm.ci.code.Register;
101 import jdk.vm.ci.code.RegisterValue;
102 import jdk.vm.ci.code.StackSlot;
103 import jdk.vm.ci.meta.AllocatableValue;
104 import jdk.vm.ci.meta.JavaConstant;
105 import jdk.vm.ci.meta.JavaKind;
106 import jdk.vm.ci.meta.PlatformKind;
107 import jdk.vm.ci.meta.VMConstant;
108 import jdk.vm.ci.meta.Value;
109 import jdk.vm.ci.meta.ValueKind;
110
245 } else {
246 Variable result = newVariable(kind);
247 emitMove(result, aRes);
248 return result;
249 }
250 }
251 }
252
253 @Override
254 public Variable emitLogicCompareAndSwap(LIRKind accessKind, Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
255 return (Variable) emitCompareAndSwap(true, accessKind, address, expectedValue, newValue, trueValue, falseValue);
256 }
257
258 @Override
259 public Value emitValueCompareAndSwap(LIRKind accessKind, Value address, Value expectedValue, Value newValue) {
260 return emitCompareAndSwap(false, accessKind, address, expectedValue, newValue, null, null);
261 }
262
263 public void emitCompareAndSwapBranch(ValueKind<?> kind, AMD64AddressValue address, Value expectedValue, Value newValue, Condition condition, LabelRef trueLabel, LabelRef falseLabel,
264 double trueLabelProbability) {
265 assert kind.equals(expectedValue.getValueKind());
266 assert kind.equals(newValue.getValueKind());
267 assert condition == Condition.EQ || condition == Condition.NE;
268 AMD64Kind memKind = (AMD64Kind) kind.getPlatformKind();
269 RegisterValue raxValue = AMD64.rax.asValue(kind);
270 emitMove(raxValue, expectedValue);
271 append(new CompareAndSwapOp(memKind, raxValue, address, raxValue, asAllocatable(newValue)));
272 append(new BranchOp(condition, trueLabel, falseLabel, trueLabelProbability));
273 }
274
275 @Override
276 public Value emitAtomicReadAndAdd(Value address, ValueKind<?> kind, Value delta) {
277 Variable result = newVariable(kind);
278 AMD64AddressValue addressValue = asAddressValue(address);
279 append(new AMD64Move.AtomicReadAndAddOp((AMD64Kind) kind.getPlatformKind(), result, addressValue, asAllocatable(delta)));
280 return result;
281 }
282
283 @Override
284 public Value emitAtomicReadAndWrite(Value address, ValueKind<?> kind, Value newValue) {
285 Variable result = newVariable(kind);
286 AMD64AddressValue addressValue = asAddressValue(address);
525 Variable result = newVariable(LIRKind.combine(input));
526 append(new AMD64ByteSwapOp(result, input));
527 return result;
528 }
529
530 @Override
531 public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
532 LIRKind resultKind = LIRKind.value(AMD64Kind.DWORD);
533 RegisterValue raxRes = AMD64.rax.asValue(resultKind);
534 RegisterValue cnt1 = AMD64.rcx.asValue(length1.getValueKind());
535 RegisterValue cnt2 = AMD64.rdx.asValue(length2.getValueKind());
536 emitMove(cnt1, length1);
537 emitMove(cnt2, length2);
538 append(new AMD64ArrayCompareToOp(this, kind1, kind2, raxRes, array1, array2, cnt1, cnt2));
539 Variable result = newVariable(resultKind);
540 emitMove(result, raxRes);
541 return result;
542 }
543
544 @Override
545 public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
546 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
547 append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
548 return result;
549 }
550
551 /**
552 * Return a conservative estimate of the page size for use by the String.indexOf intrinsic.
553 */
554 protected int getVMPageSize() {
555 return 4096;
556 }
557
558 @Override
559 public Variable emitStringIndexOf(Value source, Value sourceCount, Value target, Value targetCount, int constantTargetCount) {
560 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
561 RegisterValue cnt1 = AMD64.rdx.asValue(sourceCount.getValueKind());
562 emitMove(cnt1, sourceCount);
563 RegisterValue cnt2 = AMD64.rax.asValue(targetCount.getValueKind());
564 emitMove(cnt2, targetCount);
565 append(new AMD64StringIndexOfOp(this, result, source, target, cnt1, cnt2, AMD64.rcx.asValue(), AMD64.xmm0.asValue(), constantTargetCount, getVMPageSize()));
566 return result;
567 }
568
569 @Override
570 public Variable emitArrayIndexOf(JavaKind kind, Value arrayPointer, Value arrayLength, Value charValue) {
571 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
572 append(new AMD64ArrayIndexOfOp(kind, getVMPageSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), asAllocatable(charValue)));
573 return result;
574 }
575
576 @Override
577 public void emitReturn(JavaKind kind, Value input) {
578 AllocatableValue operand = Value.ILLEGAL;
579 if (input != null) {
580 operand = resultOperandFor(kind, input.getValueKind());
581 emitMove(operand, input);
582 }
583 append(new ReturnOp(operand));
584 }
585
586 protected StrategySwitchOp createStrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Variable key, AllocatableValue temp) {
587 return new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, temp);
588 }
589
590 @Override
591 public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
592 // a temp is needed for loading object constants
593 boolean needsTemp = !LIRKind.isValue(key);
597 @Override
598 protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
599 append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(LIRKind.value(target().arch.getWordKind())), newVariable(key.getValueKind())));
600 }
601
602 @Override
603 public void emitPause() {
604 append(new AMD64PauseOp());
605 }
606
607 @Override
608 public SaveRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) {
609 return new AMD64ZapRegistersOp(zappedRegisters, zapValues);
610 }
611
612 @Override
613 public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) {
614 return new AMD64ZapStackOp(zappedStack, zapValues);
615 }
616
617 public void emitLFence() {
618 append(new AMD64LFenceOp());
619 }
620 }
|
70 import org.graalvm.compiler.lir.amd64.AMD64Binary;
71 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
72 import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp;
73 import org.graalvm.compiler.lir.amd64.AMD64Call;
74 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow;
75 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
76 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp;
77 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
78 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
79 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
80 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
81 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
82 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
83 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
84 import org.graalvm.compiler.lir.amd64.AMD64LFenceOp;
85 import org.graalvm.compiler.lir.amd64.AMD64Move;
86 import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
87 import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp;
88 import org.graalvm.compiler.lir.amd64.AMD64Move.StackLeaOp;
89 import org.graalvm.compiler.lir.amd64.AMD64PauseOp;
90 import org.graalvm.compiler.lir.amd64.AMD64StringLatin1InflateOp;
91 import org.graalvm.compiler.lir.amd64.AMD64StringUTF16CompressOp;
92 import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp;
93 import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp;
94 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
95 import org.graalvm.compiler.lir.gen.LIRGenerator;
96 import org.graalvm.compiler.phases.util.Providers;
97
98 import jdk.vm.ci.amd64.AMD64;
99 import jdk.vm.ci.amd64.AMD64Kind;
100 import jdk.vm.ci.code.CallingConvention;
101 import jdk.vm.ci.code.Register;
102 import jdk.vm.ci.code.RegisterValue;
103 import jdk.vm.ci.code.StackSlot;
104 import jdk.vm.ci.meta.AllocatableValue;
105 import jdk.vm.ci.meta.JavaConstant;
106 import jdk.vm.ci.meta.JavaKind;
107 import jdk.vm.ci.meta.PlatformKind;
108 import jdk.vm.ci.meta.VMConstant;
109 import jdk.vm.ci.meta.Value;
110 import jdk.vm.ci.meta.ValueKind;
111
246 } else {
247 Variable result = newVariable(kind);
248 emitMove(result, aRes);
249 return result;
250 }
251 }
252 }
253
254 @Override
255 public Variable emitLogicCompareAndSwap(LIRKind accessKind, Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
256 return (Variable) emitCompareAndSwap(true, accessKind, address, expectedValue, newValue, trueValue, falseValue);
257 }
258
259 @Override
260 public Value emitValueCompareAndSwap(LIRKind accessKind, Value address, Value expectedValue, Value newValue) {
261 return emitCompareAndSwap(false, accessKind, address, expectedValue, newValue, null, null);
262 }
263
264 public void emitCompareAndSwapBranch(ValueKind<?> kind, AMD64AddressValue address, Value expectedValue, Value newValue, Condition condition, LabelRef trueLabel, LabelRef falseLabel,
265 double trueLabelProbability) {
266 assert kind.getPlatformKind().getSizeInBytes() <= expectedValue.getValueKind().getPlatformKind().getSizeInBytes();
267 assert kind.getPlatformKind().getSizeInBytes() <= newValue.getValueKind().getPlatformKind().getSizeInBytes();
268 assert condition == Condition.EQ || condition == Condition.NE;
269 AMD64Kind memKind = (AMD64Kind) kind.getPlatformKind();
270 RegisterValue raxValue = AMD64.rax.asValue(kind);
271 emitMove(raxValue, expectedValue);
272 append(new CompareAndSwapOp(memKind, raxValue, address, raxValue, asAllocatable(newValue)));
273 append(new BranchOp(condition, trueLabel, falseLabel, trueLabelProbability));
274 }
275
276 @Override
277 public Value emitAtomicReadAndAdd(Value address, ValueKind<?> kind, Value delta) {
278 Variable result = newVariable(kind);
279 AMD64AddressValue addressValue = asAddressValue(address);
280 append(new AMD64Move.AtomicReadAndAddOp((AMD64Kind) kind.getPlatformKind(), result, addressValue, asAllocatable(delta)));
281 return result;
282 }
283
284 @Override
285 public Value emitAtomicReadAndWrite(Value address, ValueKind<?> kind, Value newValue) {
286 Variable result = newVariable(kind);
287 AMD64AddressValue addressValue = asAddressValue(address);
526 Variable result = newVariable(LIRKind.combine(input));
527 append(new AMD64ByteSwapOp(result, input));
528 return result;
529 }
530
531 @Override
532 public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
533 LIRKind resultKind = LIRKind.value(AMD64Kind.DWORD);
534 RegisterValue raxRes = AMD64.rax.asValue(resultKind);
535 RegisterValue cnt1 = AMD64.rcx.asValue(length1.getValueKind());
536 RegisterValue cnt2 = AMD64.rdx.asValue(length2.getValueKind());
537 emitMove(cnt1, length1);
538 emitMove(cnt2, length2);
539 append(new AMD64ArrayCompareToOp(this, kind1, kind2, raxRes, array1, array2, cnt1, cnt2));
540 Variable result = newVariable(resultKind);
541 emitMove(result, raxRes);
542 return result;
543 }
544
545 @Override
546 public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
547 Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
548 append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), constantLength, directPointers, getMaxVectorSize()));
549 return result;
550 }
551
552 /**
553 * Return a conservative estimate of the page size for use by the String.indexOf intrinsic.
554 */
555 protected int getVMPageSize() {
556 return 4096;
557 }
558
559 /**
560 * Return the maximum size of vector registers used in SSE/AVX instructions.
561 */
562 protected int getMaxVectorSize() {
563 // default for "unlimited"
564 return -1;
565 }
566
567 @Override
568 public Variable emitArrayIndexOf(JavaKind kind, boolean findTwoConsecutive, Value arrayPointer, Value arrayLength, Value... searchValues) {
569 Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD));
570 Value[] allocatableSearchValues = new Value[searchValues.length];
571 for (int i = 0; i < searchValues.length; i++) {
572 allocatableSearchValues[i] = asAllocatable(searchValues[i]);
573 }
574 append(new AMD64ArrayIndexOfOp(kind, findTwoConsecutive, getVMPageSize(), getMaxVectorSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), allocatableSearchValues));
575 return result;
576 }
577
578 @Override
579 public void emitStringLatin1Inflate(Value src, Value dst, Value len) {
580 RegisterValue rsrc = AMD64.rsi.asValue(src.getValueKind());
581 RegisterValue rdst = AMD64.rdi.asValue(dst.getValueKind());
582 RegisterValue rlen = AMD64.rdx.asValue(len.getValueKind());
583
584 emitMove(rsrc, src);
585 emitMove(rdst, dst);
586 emitMove(rlen, len);
587
588 append(new AMD64StringLatin1InflateOp(this, rsrc, rdst, rlen));
589 }
590
591 @Override
592 public Variable emitStringUTF16Compress(Value src, Value dst, Value len) {
593 RegisterValue rsrc = AMD64.rsi.asValue(src.getValueKind());
594 RegisterValue rdst = AMD64.rdi.asValue(dst.getValueKind());
595 RegisterValue rlen = AMD64.rdx.asValue(len.getValueKind());
596
597 emitMove(rsrc, src);
598 emitMove(rdst, dst);
599 emitMove(rlen, len);
600
601 LIRKind reskind = LIRKind.value(AMD64Kind.DWORD);
602 RegisterValue rres = AMD64.rax.asValue(reskind);
603
604 append(new AMD64StringUTF16CompressOp(this, rres, rsrc, rdst, rlen));
605
606 Variable res = newVariable(reskind);
607 emitMove(res, rres);
608 return res;
609 }
610
611 @Override
612 public void emitReturn(JavaKind kind, Value input) {
613 AllocatableValue operand = Value.ILLEGAL;
614 if (input != null) {
615 operand = resultOperandFor(kind, input.getValueKind());
616 emitMove(operand, input);
617 }
618 append(new ReturnOp(operand));
619 }
620
621 protected StrategySwitchOp createStrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Variable key, AllocatableValue temp) {
622 return new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, temp);
623 }
624
625 @Override
626 public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
627 // a temp is needed for loading object constants
628 boolean needsTemp = !LIRKind.isValue(key);
632 @Override
633 protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
634 append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(LIRKind.value(target().arch.getWordKind())), newVariable(key.getValueKind())));
635 }
636
637 @Override
638 public void emitPause() {
639 append(new AMD64PauseOp());
640 }
641
642 @Override
643 public SaveRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) {
644 return new AMD64ZapRegistersOp(zappedRegisters, zapValues);
645 }
646
647 @Override
648 public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) {
649 return new AMD64ZapStackOp(zappedStack, zapValues);
650 }
651
652 @Override
653 public void emitSpeculationFence() {
654 append(new AMD64LFenceOp());
655 }
656 }
|