changeset 21600:5d6c9d2cd5f7

AMD64: emit INC and DEC for add or sub with 1 or -1.
author Josef Eisl <josef.eisl@jku.at>
date Thu, 28 May 2015 20:02:54 +0200
parents b8416bf57508
children aeb8489242b6
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java
diffstat 1 files changed, 44 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu May 28 19:49:05 2015 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu May 28 20:02:54 2015 +0200
@@ -718,11 +718,11 @@
         return result;
     }
 
-    private Variable emitBinary(AMD64BinaryArithmetic op, OperandSize size, boolean commutative, Value a, Value b) {
+    private Variable emitBinary(AMD64BinaryArithmetic op, OperandSize size, boolean commutative, Value a, Value b, boolean setFlags) {
         if (isConstant(b)) {
-            return emitBinaryConst(op, size, commutative, asAllocatable(a), asConstant(b));
+            return emitBinaryConst(op, size, commutative, asAllocatable(a), asConstant(b), setFlags);
         } else if (commutative && isConstant(a)) {
-            return emitBinaryConst(op, size, commutative, asAllocatable(b), asConstant(a));
+            return emitBinaryConst(op, size, commutative, asAllocatable(b), asConstant(a), setFlags);
         } else {
             return emitBinaryVar(op.getRMOpcode(size), size, commutative, asAllocatable(a), asAllocatable(b));
         }
@@ -738,16 +738,45 @@
         }
     }
 
-    private Variable emitBinaryConst(AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, JavaConstant b) {
+    private Variable emitBinaryConst(AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, JavaConstant b, boolean setFlags) {
         if (NumUtil.isInt(b.asLong())) {
             Variable result = newVariable(LIRKind.derive(a, b));
-            append(new AMD64Binary.ConstOp(op, size, result, a, (int) b.asLong()));
+            int constant = (int) b.asLong();
+
+            if (!setFlags) {
+                AMD64MOp mop = getMOp(op, constant);
+                if (mop != null) {
+                    append(new AMD64Unary.MOp(mop, size, result, a));
+                    return result;
+                }
+            }
+
+            append(new AMD64Binary.ConstOp(op, size, result, a, constant));
             return result;
         } else {
             return emitBinaryVar(op.getRMOpcode(size), size, commutative, a, asAllocatable(b));
         }
     }
 
+    private static AMD64MOp getMOp(AMD64BinaryArithmetic op, int constant) {
+        if (constant == 1) {
+            if (op.equals(AMD64BinaryArithmetic.ADD)) {
+                return AMD64MOp.INC;
+            }
+            if (op.equals(AMD64BinaryArithmetic.SUB)) {
+                return AMD64MOp.DEC;
+            }
+        } else if (constant == -1) {
+            if (op.equals(AMD64BinaryArithmetic.ADD)) {
+                return AMD64MOp.DEC;
+            }
+            if (op.equals(AMD64BinaryArithmetic.SUB)) {
+                return AMD64MOp.INC;
+            }
+        }
+        return null;
+    }
+
     private Variable emitBinaryConst(AMD64RMOp op, OperandSize size, AllocatableValue a, JavaConstant b) {
         Variable result = newVariable(LIRKind.derive(a, b));
         append(new AMD64Binary.DataOp(op, size, result, a, b));
@@ -768,9 +797,9 @@
     public Variable emitAdd(Value a, Value b, boolean setFlags) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                return emitBinary(ADD, DWORD, true, a, b);
+                return emitBinary(ADD, DWORD, true, a, b, setFlags);
             case Long:
-                return emitBinary(ADD, QWORD, true, a, b);
+                return emitBinary(ADD, QWORD, true, a, b, setFlags);
             case Float:
                 return emitBinary(SSEOp.ADD, SS, true, a, b);
             case Double:
@@ -784,9 +813,9 @@
     public Variable emitSub(Value a, Value b, boolean setFlags) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                return emitBinary(SUB, DWORD, false, a, b);
+                return emitBinary(SUB, DWORD, false, a, b, setFlags);
             case Long:
-                return emitBinary(SUB, QWORD, false, a, b);
+                return emitBinary(SUB, QWORD, false, a, b, setFlags);
             case Float:
                 return emitBinary(SSEOp.SUB, SS, false, a, b);
             case Double:
@@ -1021,9 +1050,9 @@
     public Variable emitAnd(Value a, Value b) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                return emitBinary(AND, DWORD, true, a, b);
+                return emitBinary(AND, DWORD, true, a, b, false);
             case Long:
-                return emitBinary(AND, QWORD, true, a, b);
+                return emitBinary(AND, QWORD, true, a, b, false);
             case Float:
                 return emitBinary(SSEOp.AND, PS, true, a, b);
             case Double:
@@ -1037,9 +1066,9 @@
     public Variable emitOr(Value a, Value b) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                return emitBinary(OR, DWORD, true, a, b);
+                return emitBinary(OR, DWORD, true, a, b, false);
             case Long:
-                return emitBinary(OR, QWORD, true, a, b);
+                return emitBinary(OR, QWORD, true, a, b, false);
             case Float:
                 return emitBinary(SSEOp.OR, PS, true, a, b);
             case Double:
@@ -1053,9 +1082,9 @@
     public Variable emitXor(Value a, Value b) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                return emitBinary(XOR, DWORD, true, a, b);
+                return emitBinary(XOR, DWORD, true, a, b, false);
             case Long:
-                return emitBinary(XOR, QWORD, true, a, b);
+                return emitBinary(XOR, QWORD, true, a, b, false);
             case Float:
                 return emitBinary(SSEOp.XOR, PS, true, a, b);
             case Double: