summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikaelpeltier <mikaelpeltier@google.com>2015-05-22 16:59:33 +0200
committerMikael Peltier <mikaelpeltier@google.com>2015-05-28 07:24:53 +0000
commit18d76d9a6dc022d7d89b3033e15c6945f877b688 (patch)
treea1e6d603d615111e3fc0982c11f84f27c9465b4b
parenta613d7171d5528580d604d31d19aa9caccfc7a53 (diff)
downloadtoolchain_jill-18d76d9a6dc022d7d89b3033e15c6945f877b688.zip
toolchain_jill-18d76d9a6dc022d7d89b3033e15c6945f877b688.tar.gz
toolchain_jill-18d76d9a6dc022d7d89b3033e15c6945f877b688.tar.bz2
Fix bug when generating floating comparisons
- some combinaison of opcodes could not be rewrite into Jack IR without adding a not operator on the condition to take into account the specific NaN values. Bug: 21384161 Change-Id: I1319e8f926a2b8eff875a5d8dddd31f335aa7fbe (cherry picked from commit 0c5d494a389849f3745dcb9df6d23a2f1d841079)
-rw-r--r--jill/src/com/android/jill/frontend/java/MethodBodyWriter.java57
1 files changed, 51 insertions, 6 deletions
diff --git a/jill/src/com/android/jill/frontend/java/MethodBodyWriter.java b/jill/src/com/android/jill/frontend/java/MethodBodyWriter.java
index 686037f..f68c9e7 100644
--- a/jill/src/com/android/jill/frontend/java/MethodBodyWriter.java
+++ b/jill/src/com/android/jill/frontend/java/MethodBodyWriter.java
@@ -132,12 +132,15 @@ public class MethodBodyWriter extends JillWriter implements Opcodes {
}
private static class CmpOperands{
+ @Nonnegative
+ int opcode;
@Nonnull
Variable lhs;
@Nonnull
Variable rhs;
- public CmpOperands(@Nonnull Variable lhs, @Nonnull Variable rhs) {
+ public CmpOperands(@Nonnegative int opcode, @Nonnull Variable lhs, @Nonnull Variable rhs) {
+ this.opcode = opcode;
this.lhs = lhs;
this.rhs = rhs;
}
@@ -1379,7 +1382,7 @@ public class MethodBodyWriter extends JillWriter implements Opcodes {
Variable lhs = getStackVariable(frame, TOP_OF_STACK - 1);
Variable rhs = getStackVariable(frame, TOP_OF_STACK);
Variable result = getStackVariable(nextFrame, TOP_OF_STACK);
- cmpOperands.put(result, new CmpOperands(lhs, rhs));
+ cmpOperands.put(result, new CmpOperands(insn.getOpcode(), lhs, rhs));
break;
}
case DSUB:
@@ -1732,15 +1735,27 @@ public class MethodBodyWriter extends JillWriter implements Opcodes {
Variable topOfStackVariable = getStackVariable(frame, TOP_OF_STACK);
CmpOperands cmpOps = cmpOperands.get(topOfStackVariable);
if (cmpOps != null) {
+ // CmpOperands concerns double, float and long types
assert jumpInsn.getOpcode() != IFNONNULL && jumpInsn.getOpcode() != IFNULL;
+ // Not operator can be generate only for double and long types to manage comparisons with
+ // Nan.
+ Token comparisonToken = getConditionToken(jumpInsn.getOpcode());
+ boolean needNotoperator = needNotOperator(comparisonToken, cmpOps);
sourceInfoWriter.writeDebugBegin(currentClass, currentLine);
writer.writeCatchBlockIds(currentCatchList);
writer.writeKeyword(Token.IF_STATEMENT);
writer.writeOpen();
- // Condition is inverted to be compliant with language level semantics
- // This has been done for comparison to NaN, which forces the branching order.
- Token comparisonToken = invertComparisonToken(getConditionToken(jumpInsn.getOpcode()));
+ if (needNotoperator) {
+ sourceInfoWriter.writeDebugBegin(currentClass, currentLine);
+ writer.writeKeyword(Token.PREFIX_NOT_OPERATION);
+ writer.writeOpen();
+ } else {
+ // Condition is inverted to be compliant with language level semantics
+ // This has been done for comparison to NaN, which forces the branching order.
+ comparisonToken = invertComparisonToken(comparisonToken);
+ }
+
sourceInfoWriter.writeDebugBegin(currentClass, currentLine);
writer.writeKeyword(comparisonToken);
writer.writeOpen();
@@ -1748,6 +1763,12 @@ public class MethodBodyWriter extends JillWriter implements Opcodes {
writeLocalRef(cmpOps.rhs);
sourceInfoWriter.writeDebugEnd(currentClass, currentLine + 1);
writer.writeClose();
+
+ if (needNotoperator) {
+ sourceInfoWriter.writeDebugEnd(currentClass, currentLine + 1);
+ writer.writeClose();
+ }
+
int labeledStatmentIndex = insIndex + 1;
writeGoto(labeledStatmentIndex);
writeGoto(jumpInsn.label);
@@ -1757,7 +1778,6 @@ public class MethodBodyWriter extends JillWriter implements Opcodes {
insertLabeledStatementIfNecessary(labeledStatmentIndex);
cmpOperands.remove(topOfStackVariable);
-
} else {
sourceInfoWriter.writeDebugBegin(currentClass, currentLine);
writer.writeCatchBlockIds(currentCatchList);
@@ -1891,6 +1911,31 @@ public class MethodBodyWriter extends JillWriter implements Opcodes {
}
}
+ @Nonnull
+ private boolean needNotOperator(@Nonnull Token cmpToken, @Nonnull CmpOperands cmpOps) {
+ switch (cmpToken) {
+ case GTE_OPERATION:
+ case GT_OPERATION: {
+ return !isCmpg(cmpOps);
+ }
+ case LTE_OPERATION:
+ case LT_OPERATION: {
+ return !isCmpl(cmpOps);
+ }
+ default: {
+ return false;
+ }
+ }
+ }
+
+ private boolean isCmpl(@Nonnull CmpOperands cmpOps) {
+ return cmpOps.opcode == DCMPL || cmpOps.opcode == FCMPL;
+ }
+
+ private boolean isCmpg(@Nonnull CmpOperands cmpOps) {
+ return cmpOps.opcode == DCMPG || cmpOps.opcode == FCMPG;
+ }
+
private void writeGoto(LabelNode labelNode) throws IOException {
int insIndex = currentMethod.instructions.indexOf(labelNode);
writeGoto(insIndex);