< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java

Print this page
rev 52509 : [mq]: graal


  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 }
< prev index next >