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);
}