< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java

Print this page
rev 52889 : 8214023: Update Graal

@@ -22,11 +22,13 @@
  */
 
 
 package org.graalvm.compiler.core.aarch64;
 
+import static jdk.vm.ci.aarch64.AArch64.sp;
 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
+import static org.graalvm.compiler.lir.LIRValueUtil.isIntConstant;
 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
 
 import java.util.function.Function;
 
 import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;

@@ -49,10 +51,11 @@
 import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
 import org.graalvm.compiler.lir.aarch64.AArch64Compare;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.BranchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondMoveOp;
+import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondSetOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64LIRFlagsVersioned;
 import org.graalvm.compiler.lir.aarch64.AArch64Move;
 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;

@@ -98,10 +101,22 @@
         // optimistic here and fix up mistakes later.
         return true;
     }
 
     /**
+     * If val denotes the stackpointer, move it to another location. This is necessary since most
+     * ops cannot handle the stackpointer as input or output.
+     */
+    public AllocatableValue moveSp(AllocatableValue val) {
+        if (val instanceof RegisterValue && ((RegisterValue) val).getRegister().equals(sp)) {
+            assert val.getPlatformKind() == AArch64Kind.QWORD : "Stackpointer must be long";
+            return emitMove(val);
+        }
+        return val;
+    }
+
+    /**
      * AArch64 cannot use anything smaller than a word in any instruction other than load and store.
      */
     @Override
     public <K extends ValueKind<K>> K toRegisterKind(K kind) {
         switch ((AArch64Kind) kind.getPlatformKind()) {

@@ -226,11 +241,18 @@
         boolean mirrored = emitCompare(cmpKind, left, right, cond, unorderedIsTrue);
         Condition finalCondition = mirrored ? cond.mirror() : cond;
         boolean finalUnorderedIsTrue = mirrored ? !unorderedIsTrue : unorderedIsTrue;
         ConditionFlag cmpCondition = toConditionFlag(((AArch64Kind) cmpKind).isInteger(), finalCondition, finalUnorderedIsTrue);
         Variable result = newVariable(trueValue.getValueKind());
+
+        if (isIntConstant(trueValue, 1) && isIntConstant(falseValue, 0)) {
+            append(new CondSetOp(result, cmpCondition));
+        } else if (isIntConstant(trueValue, 0) && isIntConstant(falseValue, 1)) {
+            append(new CondSetOp(result, cmpCondition.negate()));
+        } else {
         append(new CondMoveOp(result, cmpCondition, loadReg(trueValue), loadReg(falseValue)));
+        }
         return result;
     }
 
     @Override
     public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,

@@ -422,11 +444,18 @@
     public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
         assert ((AArch64Kind) left.getPlatformKind()).isInteger() && ((AArch64Kind) right.getPlatformKind()).isInteger();
         assert ((AArch64Kind) trueValue.getPlatformKind()).isInteger() && ((AArch64Kind) falseValue.getPlatformKind()).isInteger();
         ((AArch64ArithmeticLIRGenerator) getArithmetic()).emitBinary(left.getValueKind(), AArch64ArithmeticOp.ANDS, true, left, right);
         Variable result = newVariable(trueValue.getValueKind());
+
+        if (isIntConstant(trueValue, 1) && isIntConstant(falseValue, 0)) {
+            append(new CondSetOp(result, ConditionFlag.EQ));
+        } else if (isIntConstant(trueValue, 0) && isIntConstant(falseValue, 1)) {
+            append(new CondSetOp(result, ConditionFlag.NE));
+        } else {
         append(new CondMoveOp(result, ConditionFlag.EQ, load(trueValue), load(falseValue)));
+        }
         return result;
     }
 
     @Override
     public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
< prev index next >