Desugar Long.compareUnsigned and Integer.remainder/divide/compareUnsigned
Test: Java8MethodsTest
Change-Id: Iaf476a6761d8d73119faff3a7779f978cb7d0c22
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
index 1ba0620..69d0b48 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
@@ -214,6 +214,18 @@
return new IntegerMethods(options, method, "sumImpl");
}
+ public static IntegerMethods divideUnsignedCode(InternalOptions options, DexMethod method) {
+ return new IntegerMethods(options, method, "divideUnsignedImpl");
+ }
+
+ public static IntegerMethods remainderUnsignedCode(InternalOptions options, DexMethod method) {
+ return new IntegerMethods(options, method, "remainderUnsignedImpl");
+ }
+
+ public static IntegerMethods compareUnsignedCode(InternalOptions options, DexMethod method) {
+ return new IntegerMethods(options, method, "compareUnsignedImpl");
+ }
+
public static int hashCodeImpl(int i) {
return Integer.valueOf(i).hashCode();
}
@@ -229,6 +241,24 @@
public static int sumImpl(int a, int b) {
return a + b;
}
+
+ public static int divideUnsignedImpl(int dividend, int divisor) {
+ long dividendLong = dividend & 0xffffffffL;
+ long divisorLong = divisor & 0xffffffffL;
+ return (int) (dividendLong / divisorLong);
+ }
+
+ public static int remainderUnsignedImpl(int dividend, int divisor) {
+ long dividendLong = dividend & 0xffffffffL;
+ long divisorLong = divisor & 0xffffffffL;
+ return (int) (dividendLong % divisorLong);
+ }
+
+ public static int compareUnsignedImpl(int a, int b) {
+ int aFlipped = a ^ Integer.MIN_VALUE;
+ int bFlipped = b ^ Integer.MIN_VALUE;
+ return (aFlipped < bFlipped) ? -1 : ((aFlipped > bFlipped) ? 1 : 0);
+ }
}
private static final class DoubleMethods extends TemplateMethodCode {
@@ -392,6 +422,10 @@
return new LongMethods(options, method, "remainderUnsignedImpl");
}
+ public static LongMethods compareUnsignedCode(InternalOptions options, DexMethod method) {
+ return new LongMethods(options, method, "compareUnsignedImpl");
+ }
+
public static int hashCodeImpl(long i) {
return Long.valueOf(i).hashCode();
}
@@ -479,6 +513,12 @@
long divisorFlipped = divisor ^ Long.MIN_VALUE;
return rem - (remFlipped >= divisorFlipped ? divisor : 0);
}
+
+ public static int compareUnsignedImpl(long a, long b) {
+ long aFlipped = a ^ Long.MIN_VALUE;
+ long bFlipped = b ^ Long.MIN_VALUE;
+ return (aFlipped < bFlipped) ? -1 : ((aFlipped > bFlipped) ? 1 : 0);
+ }
}
private static final class CharacterMethods extends TemplateMethodCode {
@@ -688,11 +728,31 @@
}
private void initializeJava8UnsignedOperations(DexItemFactory factory) {
- DexString clazz = factory.boxedLongDescriptor;
+ DexString clazz = factory.boxedIntDescriptor;
+
+ // int Integer.divideUnsigned(int a, int b)
+ DexString method = factory.createString("divideUnsigned");
+ DexProto proto = factory.createProto(factory.intType, factory.intType, factory.intType);
+ addOrGetMethod(clazz, method).put(proto,
+ new MethodGenerator(IntegerMethods::divideUnsignedCode, clazz, method, proto));
+
+ // int Integer.remainderUnsigned(int a, int b)
+ method = factory.createString("remainderUnsigned");
+ proto = factory.createProto(factory.intType, factory.intType, factory.intType);
+ addOrGetMethod(clazz, method).put(proto,
+ new MethodGenerator(IntegerMethods::remainderUnsignedCode, clazz, method, proto));
+
+ // int Integer.compareUnsigned(int a, int b)
+ method = factory.createString("compareUnsigned");
+ proto = factory.createProto(factory.intType, factory.intType, factory.intType);
+ addOrGetMethod(clazz, method).put(proto,
+ new MethodGenerator(IntegerMethods::compareUnsignedCode, clazz, method, proto));
+
+ clazz = factory.boxedLongDescriptor;
// long Long.divideUnsigned(long a, long b)
- DexString method = factory.createString("divideUnsigned");
- DexProto proto = factory.createProto(factory.longType, factory.longType, factory.longType);
+ method = factory.createString("divideUnsigned");
+ proto = factory.createProto(factory.longType, factory.longType, factory.longType);
addOrGetMethod(clazz, method).put(proto,
new MethodGenerator(LongMethods::divideUnsignedCode, clazz, method, proto));
@@ -701,6 +761,12 @@
proto = factory.createProto(factory.longType, factory.longType, factory.longType);
addOrGetMethod(clazz, method).put(proto,
new MethodGenerator(LongMethods::remainderUnsignedCode, clazz, method, proto));
+
+ // int Long.compareUnsigned(long a, long b)
+ method = factory.createString("compareUnsigned");
+ proto = factory.createProto(factory.intType, factory.longType, factory.longType);
+ addOrGetMethod(clazz, method).put(proto,
+ new MethodGenerator(LongMethods::compareUnsignedCode, clazz, method, proto));
}
private Map<DexString, Map<DexProto, MethodGenerator>> addOrGetClass(DexString clazz) {
diff --git a/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java b/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
index ebc9b29..cb4c9b7 100644
--- a/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
@@ -36,7 +36,7 @@
.run(Java8Methods.class)
.assertSuccessWithOutput(expectedOutput);
- assertDesugaring(AndroidApiLevel.O, 27);
+ assertDesugaring(AndroidApiLevel.O, 31);
assertDesugaring(AndroidApiLevel.N, 25);
assertDesugaring(AndroidApiLevel.M, 0);
}
@@ -142,6 +142,9 @@
System.out.println(Integer.max(aInt, bInt));
System.out.println(Integer.min(aInt, bInt));
System.out.println(Integer.sum(aInt, bInt));
+ System.out.println(Integer.divideUnsigned(aInt, bInt));
+ System.out.println(Integer.remainderUnsigned(aInt, bInt));
+ System.out.println(Integer.compareUnsigned(aInt, bInt));
}
}
@@ -198,6 +201,7 @@
System.out.println(Long.sum(aLong, bLong));
System.out.println(Long.divideUnsigned(aLong, bLong));
System.out.println(Long.remainderUnsigned(aLong, bLong));
+ System.out.println(Long.compareUnsigned(aLong, bLong));
}
}