Bug fix for rsubs being improperly generated.

This will miss some opportunities to generate rsubs, and has been marked
by a TODO note where code needs to be added.

Cherry-picked frmo dalvik-dev.

Change-Id: Iac272f16b78ab6d985b5aabef6bd360d36a5c7ce
diff --git a/dx/src/com/android/dx/rop/code/Insn.java b/dx/src/com/android/dx/rop/code/Insn.java
index dad2852..7b79422 100644
--- a/dx/src/com/android/dx/rop/code/Insn.java
+++ b/dx/src/com/android/dx/rop/code/Insn.java
@@ -237,14 +237,14 @@
 
     /**
      * Returns an instance that is just like this one, except that, if
-     * possible, the insn is converted into a version in which the last
-     * source (if it is a constant) is represented directly rather than
-     * as a register reference. {@code this} is returned in cases where
-     * the translation is not possible.
+     * possible, the insn is converted into a version in which a source
+     * (if it is a constant) is represented directly rather than as a
+     * register reference. {@code this} is returned in cases where the
+     * translation is not possible.
      *
      * @return {@code non-null;} an appropriately-constructed instance
      */
-    public Insn withLastSourceLiteral() {
+    public Insn withSourceLiteral() {
         return this;
     }
 
diff --git a/dx/src/com/android/dx/rop/code/PlainInsn.java b/dx/src/com/android/dx/rop/code/PlainInsn.java
index 3fd2ba5..027249f 100644
--- a/dx/src/com/android/dx/rop/code/PlainInsn.java
+++ b/dx/src/com/android/dx/rop/code/PlainInsn.java
@@ -21,6 +21,7 @@
 import com.android.dx.rop.type.TypeList;
 import com.android.dx.rop.type.TypeBearer;
 import com.android.dx.rop.cst.Constant;
+import com.android.dx.rop.cst.CstInteger;
 
 /**
  * Plain instruction, which has no embedded data and which cannot possibly
@@ -95,7 +96,7 @@
 
     /** {@inheritDoc} */
     @Override
-    public Insn withLastSourceLiteral() {
+    public Insn withSourceLiteral() {
         RegisterSpecList sources = getSources();
         int szSources = sources.size();
 
@@ -105,6 +106,7 @@
 
         TypeBearer lastType = sources.get(szSources - 1).getTypeBearer();
 
+        // TODO: Check for reverse subtraction, where first source is constant
         if (!lastType.isConstant()) {
             return this;
         }
@@ -115,8 +117,13 @@
 
         Rop newRop;
         try {
-            newRop = Rops.ropFor(getOpcode().getOpcode(),
-                    getResult(), newSources, (Constant)lastType);
+            // Check for constant subtraction and flip them to be addition
+            int opcode = getOpcode().getOpcode();
+            if (opcode == RegOps.SUB && cst instanceof CstInteger) {
+                opcode = RegOps.ADD;
+                cst = CstInteger.make(-((CstInteger)cst).getValue());
+            }
+            newRop = Rops.ropFor(opcode, getResult(), newSources, cst);
         } catch (IllegalArgumentException ex) {
             // There's no rop for this case
             return this;
diff --git a/dx/src/com/android/dx/ssa/NormalSsaInsn.java b/dx/src/com/android/dx/ssa/NormalSsaInsn.java
index 93d3647..cfef400 100644
--- a/dx/src/com/android/dx/ssa/NormalSsaInsn.java
+++ b/dx/src/com/android/dx/ssa/NormalSsaInsn.java
@@ -105,6 +105,7 @@
      *
      * @return {@code null-ok;} sources list
      */
+    @Override
     public RegisterSpecList getSources() {
         return insn.getSources();
     }
@@ -135,6 +136,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public RegisterSpec getLocalAssignment() {
         RegisterSpec assignment;
 
@@ -158,15 +160,15 @@
     }
 
     /**
-     * Upgrades this insn to a version that represents the constant last
-     * source literally. If the upgrade is not possible, this does nothing.
+     * Upgrades this insn to a version that represents the constant source
+     * literally. If the upgrade is not possible, this does nothing.
      *
-     * @see Insn#withLastSourceLiteral
+     * @see Insn#withSourceLiteral
      */
     public void upgradeToLiteral() {
         RegisterSpecList oldSources = insn.getSources();
 
-        insn = insn.withLastSourceLiteral();
+        insn = insn.withSourceLiteral();
         getBlock().getParent().onSourcesChanged(this, oldSources);
     }