src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java
changeset 52910 583fd71c47d6
parent 52578 7dd81e82d083
child 54084 84f10bbf993f
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java	Sat Dec 08 05:04:19 2018 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java	Sat Dec 08 00:56:10 2018 -0800
@@ -24,7 +24,9 @@
 
 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;
@@ -51,6 +53,7 @@
 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;
@@ -100,6 +103,18 @@
     }
 
     /**
+     * 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
@@ -228,7 +243,14 @@
         boolean finalUnorderedIsTrue = mirrored ? !unorderedIsTrue : unorderedIsTrue;
         ConditionFlag cmpCondition = toConditionFlag(((AArch64Kind) cmpKind).isInteger(), finalCondition, finalUnorderedIsTrue);
         Variable result = newVariable(trueValue.getValueKind());
-        append(new CondMoveOp(result, cmpCondition, loadReg(trueValue), loadReg(falseValue)));
+
+        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;
     }
 
@@ -424,7 +446,14 @@
         assert ((AArch64Kind) trueValue.getPlatformKind()).isInteger() && ((AArch64Kind) falseValue.getPlatformKind()).isInteger();
         ((AArch64ArithmeticLIRGenerator) getArithmetic()).emitBinary(left.getValueKind(), AArch64ArithmeticOp.ANDS, true, left, right);
         Variable result = newVariable(trueValue.getValueKind());
-        append(new CondMoveOp(result, ConditionFlag.EQ, load(trueValue), load(falseValue)));
+
+        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;
     }