Revert "Math.StrictMath#unsignedMultiply II, LI, LL"
This reverts commit 87d54680fc129118d1d7e4ccbff08d9923e651fb.
Revert "Math.StrictMath#unsignedPow II LI"
This reverts commit 7cea7573f46dfa545cce602087fef1a5b9f70e23.
Revert "Math.StrictMath#pow II LI"
This reverts commit 07db94d20fd1b4c1f4e087be8f6dd0db9001ef7d.
Revert "Fix powExact backport error"
This reverts commit f638ecbe87b326b94667507fd2900bbef4dcb672.
Revert "Add a few more Math tests"
This reverts commit 55c45ad3de32c049fe3bb2fb41b76962c1d5fdb7.
Revert "Refactor Backported methods"
This reverts commit 0ff3b82e05ea293393b7c79b6d5a86fb41c2db31.
Change-Id: I27d7cdac71cade537410320d39df514092ce300d
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 0250ce0..9d9c33f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -371,7 +371,6 @@
if (options.getMinApiLevel().isLessThan(AndroidApiLevel.BAKLAVA_1)) {
initializeAndroidBaklava1MethodProviders(factory);
}
- initializeJava25MethodProviders(factory);
}
private Map<DexType, AndroidApiLevel> initializeTypeMinApi(DexItemFactory factory) {
@@ -470,61 +469,6 @@
rewritableFields.keySet().forEach(consumer);
}
- private void initializeJava25MethodProviders(DexItemFactory factory) {
- // Math
- for (DexType mathType : new DexType[] {factory.mathType, factory.strictMathType}) {
- // int Math.unsignedMultiplyExact(int, int)
- DexString name = factory.createString("unsignedMultiplyExact");
- DexProto proto = factory.createProto(factory.intType, factory.intType, factory.intType);
- DexMethod method = factory.createMethod(mathType, proto, name);
- addProvider(
- new MethodGenerator(
- method, BackportedMethods::MathMethods_unsignedMultiplyExactIntInt));
-
- // long Math.unsignedMultiplyExact(long, int)
- name = factory.createString("unsignedMultiplyExact");
- proto = factory.createProto(factory.longType, factory.longType, factory.intType);
- method = factory.createMethod(mathType, proto, name);
- addProvider(
- new MethodGenerator(
- method, BackportedMethods::MathMethods_unsignedMultiplyExactLongInt));
-
- // long Math.unsignedMultiplyExact(long, long)
- name = factory.createString("unsignedMultiplyExact");
- proto = factory.createProto(factory.longType, factory.longType, factory.longType);
- method = factory.createMethod(mathType, proto, name);
- addProvider(
- new MethodGenerator(
- method, BackportedMethods::MathMethods_unsignedMultiplyExactLongLong));
-
- // int Math.unsignedPowExact(int, int)
- name = factory.createString("unsignedPowExact");
- proto = factory.createProto(factory.intType, factory.intType, factory.intType);
- method = factory.createMethod(mathType, proto, name);
- addProvider(
- new MethodGenerator(method, BackportedMethods::MathMethods_unsignedPowExactInt));
-
- // long Math.unsignedPowExact(long, int)
- name = factory.createString("unsignedPowExact");
- proto = factory.createProto(factory.longType, factory.longType, factory.intType);
- method = factory.createMethod(mathType, proto, name);
- addProvider(
- new MethodGenerator(method, BackportedMethods::MathMethods_unsignedPowExactLong));
-
- // Math.powExact(int, int)
- name = factory.createString("powExact");
- proto = factory.createProto(factory.intType, factory.intType, factory.intType);
- method = factory.createMethod(mathType, proto, name);
- addProvider(new MethodGenerator(method, BackportedMethods::MathMethods_powExactInt));
-
- // Math.powExact(long, int)
- name = factory.createString("powExact");
- proto = factory.createProto(factory.longType, factory.longType, factory.intType);
- method = factory.createMethod(mathType, proto, name);
- addProvider(new MethodGenerator(method, BackportedMethods::MathMethods_powExactLong));
- }
- }
-
private void initializeAndroidKObjectsMethodProviders(DexItemFactory factory) {
DexType type;
DexString name;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
index 32b1fb5..a2e1891 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
@@ -8913,10 +8913,17 @@
CfLabel label1 = new CfLabel();
CfLabel label2 = new CfLabel();
CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ CfLabel label5 = new CfLabel();
+ CfLabel label6 = new CfLabel();
+ CfLabel label7 = new CfLabel();
+ CfLabel label8 = new CfLabel();
+ CfLabel label9 = new CfLabel();
+ CfLabel label10 = new CfLabel();
return new CfCode(
method.holder,
3,
- 2,
+ 5,
ImmutableList.of(
label0,
new CfLoad(ValueType.INT, 0),
@@ -8943,15 +8950,67 @@
new int[] {0, 1}, new FrameType[] {FrameType.intType(), FrameType.intType()})),
new CfLoad(ValueType.INT, 0),
new CfLoad(ValueType.INT, 1),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.intType, factory.intType, factory.intType),
- factory.createString("ceilDiv")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Div, NumericType.INT),
+ new CfStore(ValueType.INT, 2),
+ label3,
+ new CfLoad(ValueType.INT, 0),
+ new CfLoad(ValueType.INT, 1),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Rem, NumericType.INT),
+ new CfStore(ValueType.INT, 3),
+ label4,
+ new CfLoad(ValueType.INT, 0),
+ new CfLoad(ValueType.INT, 1),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Xor, NumericType.INT),
+ new CfIf(IfType.LT, ValueType.INT, label5),
+ new CfConstNumber(1, ValueType.INT),
+ new CfGoto(label6),
+ label5,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3},
+ new FrameType[] {
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType()
+ })),
+ new CfConstNumber(0, ValueType.INT),
+ label6,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3},
+ new FrameType[] {
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.intType()))),
+ new CfStore(ValueType.INT, 4),
+ label7,
+ new CfLoad(ValueType.INT, 4),
+ new CfIf(IfType.EQ, ValueType.INT, label9),
+ new CfLoad(ValueType.INT, 3),
+ new CfIf(IfType.EQ, ValueType.INT, label9),
+ label8,
+ new CfLoad(ValueType.INT, 2),
+ new CfConstNumber(1, ValueType.INT),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.INT),
new CfReturn(ValueType.INT),
- label3),
+ label9,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4},
+ new FrameType[] {
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType()
+ })),
+ new CfLoad(ValueType.INT, 2),
+ new CfReturn(ValueType.INT),
+ label10),
ImmutableList.of(),
ImmutableList.of());
}
@@ -8961,10 +9020,17 @@
CfLabel label1 = new CfLabel();
CfLabel label2 = new CfLabel();
CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ CfLabel label5 = new CfLabel();
+ CfLabel label6 = new CfLabel();
+ CfLabel label7 = new CfLabel();
+ CfLabel label8 = new CfLabel();
+ CfLabel label9 = new CfLabel();
+ CfLabel label10 = new CfLabel();
return new CfCode(
method.holder,
4,
- 4,
+ 9,
ImmutableList.of(
label0,
new CfLoad(ValueType.LONG, 0),
@@ -8999,15 +9065,83 @@
})),
new CfLoad(ValueType.LONG, 0),
new CfLoad(ValueType.LONG, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("ceilDiv")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Div, NumericType.LONG),
+ new CfStore(ValueType.LONG, 4),
+ label3,
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.LONG, 2),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Rem, NumericType.LONG),
+ new CfStore(ValueType.LONG, 6),
+ label4,
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.LONG, 2),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Xor, NumericType.LONG),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.LT, ValueType.INT, label5),
+ new CfConstNumber(1, ValueType.INT),
+ new CfGoto(label6),
+ label5,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfConstNumber(0, ValueType.INT),
+ label6,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.intType()))),
+ new CfStore(ValueType.INT, 8),
+ label7,
+ new CfLoad(ValueType.INT, 8),
+ new CfIf(IfType.EQ, ValueType.INT, label9),
+ new CfLoad(ValueType.LONG, 6),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.EQ, ValueType.INT, label9),
+ label8,
+ new CfLoad(ValueType.LONG, 4),
+ new CfConstNumber(1, ValueType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
new CfReturn(ValueType.LONG),
- label3),
+ label9,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType()
+ })),
+ new CfLoad(ValueType.LONG, 4),
+ new CfReturn(ValueType.LONG),
+ label10),
ImmutableList.of(),
ImmutableList.of());
}
@@ -9098,24 +9232,98 @@
public static CfCode MathMethods_ceilDivLongInt(DexItemFactory factory, DexMethod method) {
CfLabel label0 = new CfLabel();
CfLabel label1 = new CfLabel();
+ CfLabel label2 = new CfLabel();
+ CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ CfLabel label5 = new CfLabel();
+ CfLabel label6 = new CfLabel();
+ CfLabel label7 = new CfLabel();
+ CfLabel label8 = new CfLabel();
return new CfCode(
method.holder,
4,
- 3,
+ 8,
ImmutableList.of(
label0,
new CfLoad(ValueType.LONG, 0),
new CfLoad(ValueType.INT, 2),
new CfNumberConversion(NumberConversionType.INT_TO_LONG),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("ceilDiv")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Div, NumericType.LONG),
+ new CfStore(ValueType.LONG, 3),
+ label1,
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.INT, 2),
+ new CfNumberConversion(NumberConversionType.INT_TO_LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Rem, NumericType.LONG),
+ new CfStore(ValueType.LONG, 5),
+ label2,
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.INT, 2),
+ new CfNumberConversion(NumberConversionType.INT_TO_LONG),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Xor, NumericType.LONG),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.LT, ValueType.INT, label3),
+ new CfConstNumber(1, ValueType.INT),
+ new CfGoto(label4),
+ label3,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfConstNumber(0, ValueType.INT),
+ label4,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.intType()))),
+ new CfStore(ValueType.INT, 7),
+ label5,
+ new CfLoad(ValueType.INT, 7),
+ new CfIf(IfType.EQ, ValueType.INT, label7),
+ new CfLoad(ValueType.LONG, 5),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.EQ, ValueType.INT, label7),
+ label6,
+ new CfLoad(ValueType.LONG, 3),
+ new CfConstNumber(1, ValueType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
new CfReturn(ValueType.LONG),
- label1),
+ label7,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType()
+ })),
+ new CfLoad(ValueType.LONG, 3),
+ new CfReturn(ValueType.LONG),
+ label8),
ImmutableList.of(),
ImmutableList.of());
}
@@ -9292,25 +9500,99 @@
public static CfCode MathMethods_ceilModLongInt(DexItemFactory factory, DexMethod method) {
CfLabel label0 = new CfLabel();
CfLabel label1 = new CfLabel();
+ CfLabel label2 = new CfLabel();
+ CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ CfLabel label5 = new CfLabel();
+ CfLabel label6 = new CfLabel();
+ CfLabel label7 = new CfLabel();
return new CfCode(
method.holder,
4,
- 3,
+ 6,
ImmutableList.of(
label0,
new CfLoad(ValueType.LONG, 0),
new CfLoad(ValueType.INT, 2),
new CfNumberConversion(NumberConversionType.INT_TO_LONG),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("ceilMod")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Rem, NumericType.LONG),
+ new CfStore(ValueType.LONG, 3),
+ label1,
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.INT, 2),
+ new CfNumberConversion(NumberConversionType.INT_TO_LONG),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Xor, NumericType.LONG),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.LT, ValueType.INT, label2),
+ new CfConstNumber(1, ValueType.INT),
+ new CfGoto(label3),
+ label2,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfConstNumber(0, ValueType.INT),
+ label3,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.intType()))),
+ new CfStore(ValueType.INT, 5),
+ label4,
+ new CfLoad(ValueType.INT, 5),
+ new CfIf(IfType.EQ, ValueType.INT, label5),
+ new CfLoad(ValueType.LONG, 3),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.EQ, ValueType.INT, label5),
+ new CfLoad(ValueType.LONG, 3),
+ new CfLoad(ValueType.INT, 2),
+ new CfNumberConversion(NumberConversionType.INT_TO_LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Sub, NumericType.LONG),
+ new CfGoto(label6),
+ label5,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType()
+ })),
+ new CfLoad(ValueType.LONG, 3),
+ label6,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.intType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.longType()))),
new CfNumberConversion(NumberConversionType.LONG_TO_INT),
new CfReturn(ValueType.INT),
- label1),
+ label7),
ImmutableList.of(),
ImmutableList.of());
}
@@ -10117,10 +10399,17 @@
CfLabel label1 = new CfLabel();
CfLabel label2 = new CfLabel();
CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ CfLabel label5 = new CfLabel();
+ CfLabel label6 = new CfLabel();
+ CfLabel label7 = new CfLabel();
+ CfLabel label8 = new CfLabel();
+ CfLabel label9 = new CfLabel();
+ CfLabel label10 = new CfLabel();
return new CfCode(
method.holder,
3,
- 2,
+ 5,
ImmutableList.of(
label0,
new CfLoad(ValueType.INT, 0),
@@ -10147,15 +10436,72 @@
new int[] {0, 1}, new FrameType[] {FrameType.intType(), FrameType.intType()})),
new CfLoad(ValueType.INT, 0),
new CfLoad(ValueType.INT, 1),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.intType, factory.intType, factory.intType),
- factory.createString("floorDiv")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Div, NumericType.INT),
+ new CfStore(ValueType.INT, 2),
+ label3,
+ new CfLoad(ValueType.INT, 0),
+ new CfLoad(ValueType.INT, 1),
+ new CfLoad(ValueType.INT, 2),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.INT),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Sub, NumericType.INT),
+ new CfStore(ValueType.INT, 3),
+ label4,
+ new CfLoad(ValueType.INT, 3),
+ new CfIf(IfType.NE, ValueType.INT, label6),
+ label5,
+ new CfLoad(ValueType.INT, 2),
new CfReturn(ValueType.INT),
- label3),
+ label6,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3},
+ new FrameType[] {
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType()
+ })),
+ new CfConstNumber(1, ValueType.INT),
+ new CfLoad(ValueType.INT, 0),
+ new CfLoad(ValueType.INT, 1),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Xor, NumericType.INT),
+ new CfConstNumber(31, ValueType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Shr, NumericType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Or, NumericType.INT),
+ new CfStore(ValueType.INT, 4),
+ label7,
+ new CfLoad(ValueType.INT, 4),
+ new CfIf(IfType.GE, ValueType.INT, label8),
+ new CfLoad(ValueType.INT, 2),
+ new CfConstNumber(1, ValueType.INT),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Sub, NumericType.INT),
+ new CfGoto(label9),
+ label8,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4},
+ new FrameType[] {
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType()
+ })),
+ new CfLoad(ValueType.INT, 2),
+ label9,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4},
+ new FrameType[] {
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType(),
+ FrameType.intType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.intType()))),
+ new CfReturn(ValueType.INT),
+ label10),
ImmutableList.of(),
ImmutableList.of());
}
@@ -10165,10 +10511,17 @@
CfLabel label1 = new CfLabel();
CfLabel label2 = new CfLabel();
CfLabel label3 = new CfLabel();
+ CfLabel label4 = new CfLabel();
+ CfLabel label5 = new CfLabel();
+ CfLabel label6 = new CfLabel();
+ CfLabel label7 = new CfLabel();
+ CfLabel label8 = new CfLabel();
+ CfLabel label9 = new CfLabel();
+ CfLabel label10 = new CfLabel();
return new CfCode(
method.holder,
- 4,
- 4,
+ 6,
+ 10,
ImmutableList.of(
label0,
new CfLoad(ValueType.LONG, 0),
@@ -10203,15 +10556,90 @@
})),
new CfLoad(ValueType.LONG, 0),
new CfLoad(ValueType.LONG, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("floorDiv")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Div, NumericType.LONG),
+ new CfStore(ValueType.LONG, 4),
+ label3,
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.LONG, 2),
+ new CfLoad(ValueType.LONG, 4),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Sub, NumericType.LONG),
+ new CfStore(ValueType.LONG, 6),
+ label4,
+ new CfLoad(ValueType.LONG, 6),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.NE, ValueType.INT, label6),
+ label5,
+ new CfLoad(ValueType.LONG, 4),
new CfReturn(ValueType.LONG),
- label3),
+ label6,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfConstNumber(1, ValueType.LONG),
+ new CfLoad(ValueType.LONG, 0),
+ new CfLoad(ValueType.LONG, 2),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Xor, NumericType.LONG),
+ new CfConstNumber(63, ValueType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Shr, NumericType.LONG),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Or, NumericType.LONG),
+ new CfStore(ValueType.LONG, 8),
+ label7,
+ new CfLoad(ValueType.LONG, 8),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.GE, ValueType.INT, label8),
+ new CfLoad(ValueType.LONG, 4),
+ new CfConstNumber(1, ValueType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Sub, NumericType.LONG),
+ new CfGoto(label9),
+ label8,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfLoad(ValueType.LONG, 4),
+ label9,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ }),
+ new ArrayDeque<>(Arrays.asList(FrameType.longType()))),
+ new CfReturn(ValueType.LONG),
+ label10),
ImmutableList.of(),
ImmutableList.of());
}
@@ -11248,309 +11676,6 @@
ImmutableList.of());
}
- public static CfCode MathMethods_powExactInt(DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- CfLabel label2 = new CfLabel();
- CfLabel label3 = new CfLabel();
- CfLabel label4 = new CfLabel();
- CfLabel label5 = new CfLabel();
- CfLabel label6 = new CfLabel();
- CfLabel label7 = new CfLabel();
- CfLabel label8 = new CfLabel();
- CfLabel label9 = new CfLabel();
- CfLabel label10 = new CfLabel();
- CfLabel label11 = new CfLabel();
- CfLabel label12 = new CfLabel();
- CfLabel label13 = new CfLabel();
- return new CfCode(
- method.holder,
- 3,
- 5,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.INT, 0),
- new CfStore(ValueType.INT, 2),
- label1,
- new CfLoad(ValueType.INT, 1),
- new CfStore(ValueType.INT, 3),
- label2,
- new CfLoad(ValueType.INT, 3),
- new CfIf(IfType.GE, ValueType.INT, label4),
- label3,
- new CfNew(factory.createType("Ljava/lang/ArithmeticException;")),
- new CfStackInstruction(CfStackInstruction.Opcode.Dup),
- new CfConstString(factory.createString("negative exponent")),
- new CfInvoke(
- 183,
- factory.createMethod(
- factory.createType("Ljava/lang/ArithmeticException;"),
- factory.createProto(factory.voidType, factory.stringType),
- factory.createString("<init>")),
- false),
- new CfThrow(),
- label4,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 3),
- new CfIf(IfType.NE, ValueType.INT, label6),
- label5,
- new CfConstNumber(1, ValueType.INT),
- new CfReturn(ValueType.INT),
- label6,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType()
- })),
- new CfConstNumber(1, ValueType.INT),
- new CfStore(ValueType.INT, 4),
- label7,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 3),
- new CfConstNumber(1, ValueType.INT),
- new CfIfCmp(IfType.LE, ValueType.INT, label12),
- label8,
- new CfLoad(ValueType.INT, 3),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.INT),
- new CfIf(IfType.EQ, ValueType.INT, label10),
- label9,
- new CfLoad(ValueType.INT, 4),
- new CfLoad(ValueType.INT, 2),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.INT),
- new CfStore(ValueType.INT, 4),
- label10,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 2),
- new CfLoad(ValueType.INT, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.intType, factory.intType, factory.intType),
- factory.createString("multiplyExact")),
- false),
- new CfStore(ValueType.INT, 2),
- label11,
- new CfLoad(ValueType.INT, 3),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.Ushr, NumericType.INT),
- new CfStore(ValueType.INT, 3),
- new CfGoto(label7),
- label12,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 4),
- new CfLoad(ValueType.INT, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.intType, factory.intType, factory.intType),
- factory.createString("multiplyExact")),
- false),
- new CfReturn(ValueType.INT),
- label13),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
- public static CfCode MathMethods_powExactLong(DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- CfLabel label2 = new CfLabel();
- CfLabel label3 = new CfLabel();
- CfLabel label4 = new CfLabel();
- CfLabel label5 = new CfLabel();
- CfLabel label6 = new CfLabel();
- CfLabel label7 = new CfLabel();
- CfLabel label8 = new CfLabel();
- CfLabel label9 = new CfLabel();
- CfLabel label10 = new CfLabel();
- CfLabel label11 = new CfLabel();
- CfLabel label12 = new CfLabel();
- CfLabel label13 = new CfLabel();
- return new CfCode(
- method.holder,
- 4,
- 8,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.LONG, 0),
- new CfStore(ValueType.LONG, 3),
- label1,
- new CfLoad(ValueType.INT, 2),
- new CfStore(ValueType.INT, 5),
- label2,
- new CfLoad(ValueType.INT, 5),
- new CfIf(IfType.GE, ValueType.INT, label4),
- label3,
- new CfNew(factory.createType("Ljava/lang/ArithmeticException;")),
- new CfStackInstruction(CfStackInstruction.Opcode.Dup),
- new CfConstString(factory.createString("negative exponent")),
- new CfInvoke(
- 183,
- factory.createMethod(
- factory.createType("Ljava/lang/ArithmeticException;"),
- factory.createProto(factory.voidType, factory.stringType),
- factory.createString("<init>")),
- false),
- new CfThrow(),
- label4,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 5),
- new CfIf(IfType.NE, ValueType.INT, label6),
- label5,
- new CfConstNumber(1, ValueType.LONG),
- new CfReturn(ValueType.LONG),
- label6,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType()
- })),
- new CfConstNumber(1, ValueType.LONG),
- new CfStore(ValueType.LONG, 6),
- label7,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.INT, 5),
- new CfConstNumber(1, ValueType.INT),
- new CfIfCmp(IfType.LE, ValueType.INT, label12),
- label8,
- new CfLoad(ValueType.INT, 5),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.INT),
- new CfIf(IfType.EQ, ValueType.INT, label10),
- label9,
- new CfLoad(ValueType.LONG, 6),
- new CfLoad(ValueType.LONG, 3),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
- new CfStore(ValueType.LONG, 6),
- label10,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.LONG, 3),
- new CfLoad(ValueType.LONG, 3),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("multiplyExact")),
- false),
- new CfStore(ValueType.LONG, 3),
- label11,
- new CfLoad(ValueType.INT, 5),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.Ushr, NumericType.INT),
- new CfStore(ValueType.INT, 5),
- new CfGoto(label7),
- label12,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.LONG, 6),
- new CfLoad(ValueType.LONG, 3),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("multiplyExact")),
- false),
- new CfReturn(ValueType.LONG),
- label13),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
public static CfCode MathMethods_subtractExactInt(DexItemFactory factory, DexMethod method) {
CfLabel label0 = new CfLabel();
CfLabel label1 = new CfLabel();
@@ -11777,161 +11902,6 @@
ImmutableList.of());
}
- public static CfCode MathMethods_unsignedMultiplyExactIntInt(
- DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- CfLabel label2 = new CfLabel();
- CfLabel label3 = new CfLabel();
- CfLabel label4 = new CfLabel();
- return new CfCode(
- method.holder,
- 6,
- 4,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.INT, 0),
- new CfNumberConversion(NumberConversionType.INT_TO_LONG),
- new CfConstNumber(4294967295L, ValueType.LONG),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.LONG),
- new CfLoad(ValueType.INT, 1),
- new CfNumberConversion(NumberConversionType.INT_TO_LONG),
- new CfConstNumber(4294967295L, ValueType.LONG),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.LONG),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
- new CfStore(ValueType.LONG, 2),
- label1,
- new CfLoad(ValueType.LONG, 2),
- new CfConstNumber(32, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.Ushr, NumericType.LONG),
- new CfConstNumber(0, ValueType.LONG),
- new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
- new CfIf(IfType.EQ, ValueType.INT, label3),
- label2,
- new CfNew(factory.createType("Ljava/lang/ArithmeticException;")),
- new CfStackInstruction(CfStackInstruction.Opcode.Dup),
- new CfConstString(factory.createString("unsigned integer overflow")),
- new CfInvoke(
- 183,
- factory.createMethod(
- factory.createType("Ljava/lang/ArithmeticException;"),
- factory.createProto(factory.voidType, factory.stringType),
- factory.createString("<init>")),
- false),
- new CfThrow(),
- label3,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.LONG, 2),
- new CfNumberConversion(NumberConversionType.LONG_TO_INT),
- new CfReturn(ValueType.INT),
- label4),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
- public static CfCode MathMethods_unsignedMultiplyExactLongInt(
- DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- return new CfCode(
- method.holder,
- 6,
- 3,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.LONG, 0),
- new CfLoad(ValueType.INT, 2),
- new CfNumberConversion(NumberConversionType.INT_TO_LONG),
- new CfConstNumber(4294967295L, ValueType.LONG),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.LONG),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("unsignedMultiplyExact")),
- false),
- new CfReturn(ValueType.LONG),
- label1),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
- public static CfCode MathMethods_unsignedMultiplyExactLongLong(
- DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- CfLabel label2 = new CfLabel();
- CfLabel label3 = new CfLabel();
- CfLabel label4 = new CfLabel();
- CfLabel label5 = new CfLabel();
- return new CfCode(
- method.holder,
- 4,
- 8,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.LONG, 0),
- new CfLoad(ValueType.LONG, 2),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
- new CfStore(ValueType.LONG, 4),
- label1,
- new CfLoad(ValueType.LONG, 0),
- new CfLoad(ValueType.LONG, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("unsignedMultiplyHigh")),
- false),
- new CfStore(ValueType.LONG, 6),
- label2,
- new CfLoad(ValueType.LONG, 6),
- new CfConstNumber(0, ValueType.LONG),
- new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
- new CfIf(IfType.NE, ValueType.INT, label4),
- label3,
- new CfLoad(ValueType.LONG, 4),
- new CfReturn(ValueType.LONG),
- label4,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfNew(factory.createType("Ljava/lang/ArithmeticException;")),
- new CfStackInstruction(CfStackInstruction.Opcode.Dup),
- new CfConstString(factory.createString("unsigned long overflow")),
- new CfInvoke(
- 183,
- factory.createMethod(
- factory.createType("Ljava/lang/ArithmeticException;"),
- factory.createProto(factory.voidType, factory.stringType),
- factory.createString("<init>")),
- false),
- new CfThrow(),
- label5),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
public static CfCode MathMethods_unsignedMultiplyHigh(DexItemFactory factory, DexMethod method) {
CfLabel label0 = new CfLabel();
CfLabel label1 = new CfLabel();
@@ -11940,222 +11910,6 @@
CfLabel label4 = new CfLabel();
CfLabel label5 = new CfLabel();
CfLabel label6 = new CfLabel();
- return new CfCode(
- method.holder,
- 4,
- 6,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.LONG, 0),
- new CfLoad(ValueType.LONG, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("multiplyHigh")),
- false),
- new CfStore(ValueType.LONG, 4),
- label1,
- new CfLoad(ValueType.LONG, 0),
- new CfConstNumber(0, ValueType.LONG),
- new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
- new CfIf(IfType.GE, ValueType.INT, label3),
- label2,
- new CfLoad(ValueType.LONG, 4),
- new CfLoad(ValueType.LONG, 2),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
- new CfStore(ValueType.LONG, 4),
- label3,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.LONG, 2),
- new CfConstNumber(0, ValueType.LONG),
- new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
- new CfIf(IfType.GE, ValueType.INT, label5),
- label4,
- new CfLoad(ValueType.LONG, 4),
- new CfLoad(ValueType.LONG, 0),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
- new CfStore(ValueType.LONG, 4),
- label5,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.LONG, 4),
- new CfReturn(ValueType.LONG),
- label6),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
- public static CfCode MathMethods_unsignedPowExactInt(DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- CfLabel label2 = new CfLabel();
- CfLabel label3 = new CfLabel();
- CfLabel label4 = new CfLabel();
- CfLabel label5 = new CfLabel();
- CfLabel label6 = new CfLabel();
- CfLabel label7 = new CfLabel();
- CfLabel label8 = new CfLabel();
- CfLabel label9 = new CfLabel();
- CfLabel label10 = new CfLabel();
- CfLabel label11 = new CfLabel();
- CfLabel label12 = new CfLabel();
- CfLabel label13 = new CfLabel();
- return new CfCode(
- method.holder,
- 3,
- 6,
- ImmutableList.of(
- label0,
- new CfLoad(ValueType.INT, 0),
- new CfStore(ValueType.INT, 2),
- label1,
- new CfLoad(ValueType.INT, 1),
- new CfIf(IfType.GE, ValueType.INT, label3),
- label2,
- new CfNew(factory.createType("Ljava/lang/ArithmeticException;")),
- new CfStackInstruction(CfStackInstruction.Opcode.Dup),
- new CfConstString(factory.createString("negative exponent")),
- new CfInvoke(
- 183,
- factory.createMethod(
- factory.createType("Ljava/lang/ArithmeticException;"),
- factory.createProto(factory.voidType, factory.stringType),
- factory.createString("<init>")),
- false),
- new CfThrow(),
- label3,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2},
- new FrameType[] {
- FrameType.intType(), FrameType.intType(), FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 1),
- new CfIf(IfType.NE, ValueType.INT, label5),
- label4,
- new CfConstNumber(1, ValueType.INT),
- new CfReturn(ValueType.INT),
- label5,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2},
- new FrameType[] {
- FrameType.intType(), FrameType.intType(), FrameType.intType()
- })),
- new CfConstNumber(4294967295L, ValueType.LONG),
- new CfStore(ValueType.LONG, 3),
- label6,
- new CfConstNumber(1, ValueType.INT),
- new CfStore(ValueType.INT, 5),
- label7,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 1),
- new CfConstNumber(1, ValueType.INT),
- new CfIfCmp(IfType.LE, ValueType.INT, label12),
- label8,
- new CfLoad(ValueType.INT, 1),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.INT),
- new CfIf(IfType.EQ, ValueType.INT, label10),
- label9,
- new CfLoad(ValueType.INT, 5),
- new CfLoad(ValueType.INT, 2),
- new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.INT),
- new CfStore(ValueType.INT, 5),
- label10,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 2),
- new CfLoad(ValueType.INT, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.intType, factory.intType, factory.intType),
- factory.createString("unsignedMultiplyExact")),
- false),
- new CfStore(ValueType.INT, 2),
- label11,
- new CfLoad(ValueType.INT, 1),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.Ushr, NumericType.INT),
- new CfStore(ValueType.INT, 1),
- new CfGoto(label7),
- label12,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5},
- new FrameType[] {
- FrameType.intType(),
- FrameType.intType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType()
- })),
- new CfLoad(ValueType.INT, 5),
- new CfLoad(ValueType.INT, 2),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.intType, factory.intType, factory.intType),
- factory.createString("unsignedMultiplyExact")),
- false),
- new CfReturn(ValueType.INT),
- label13),
- ImmutableList.of(),
- ImmutableList.of());
- }
-
- public static CfCode MathMethods_unsignedPowExactLong(DexItemFactory factory, DexMethod method) {
- CfLabel label0 = new CfLabel();
- CfLabel label1 = new CfLabel();
- CfLabel label2 = new CfLabel();
- CfLabel label3 = new CfLabel();
- CfLabel label4 = new CfLabel();
- CfLabel label5 = new CfLabel();
- CfLabel label6 = new CfLabel();
CfLabel label7 = new CfLabel();
CfLabel label8 = new CfLabel();
CfLabel label9 = new CfLabel();
@@ -12164,152 +11918,156 @@
CfLabel label12 = new CfLabel();
CfLabel label13 = new CfLabel();
CfLabel label14 = new CfLabel();
+ CfLabel label15 = new CfLabel();
return new CfCode(
method.holder,
- 4,
- 10,
+ 6,
+ 22,
ImmutableList.of(
label0,
new CfLoad(ValueType.LONG, 0),
- new CfStore(ValueType.LONG, 3),
- label1,
- new CfLoad(ValueType.INT, 2),
- new CfIf(IfType.GE, ValueType.INT, label3),
- label2,
- new CfNew(factory.createType("Ljava/lang/ArithmeticException;")),
- new CfStackInstruction(CfStackInstruction.Opcode.Dup),
- new CfConstString(factory.createString("negative exponent")),
- new CfInvoke(
- 183,
- factory.createMethod(
- factory.createType("Ljava/lang/ArithmeticException;"),
- factory.createProto(factory.voidType, factory.stringType),
- factory.createString("<init>")),
- false),
- new CfThrow(),
- label3,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.INT, 2),
- new CfIf(IfType.NE, ValueType.INT, label5),
- label4,
- new CfConstNumber(1, ValueType.LONG),
- new CfReturn(ValueType.LONG),
- label5,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
new CfConstNumber(32, ValueType.INT),
- new CfStore(ValueType.INT, 5),
- label6,
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Shr, NumericType.LONG),
+ new CfStore(ValueType.LONG, 4),
+ label1,
+ new CfLoad(ValueType.LONG, 0),
new CfConstNumber(4294967295L, ValueType.LONG),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.LONG),
new CfStore(ValueType.LONG, 6),
- label7,
- new CfConstNumber(1, ValueType.LONG),
+ label2,
+ new CfLoad(ValueType.LONG, 2),
+ new CfConstNumber(32, ValueType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Shr, NumericType.LONG),
new CfStore(ValueType.LONG, 8),
- label8,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.INT, 2),
- new CfConstNumber(1, ValueType.INT),
- new CfIfCmp(IfType.LE, ValueType.INT, label13),
- label9,
- new CfLoad(ValueType.INT, 2),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.INT),
- new CfIf(IfType.EQ, ValueType.INT, label11),
- label10,
- new CfLoad(ValueType.LONG, 8),
- new CfLoad(ValueType.LONG, 3),
+ label3,
+ new CfLoad(ValueType.LONG, 2),
+ new CfConstNumber(4294967295L, ValueType.LONG),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.LONG),
+ new CfStore(ValueType.LONG, 10),
+ label4,
+ new CfLoad(ValueType.LONG, 6),
+ new CfLoad(ValueType.LONG, 10),
new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
- new CfStore(ValueType.LONG, 8),
- label11,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
- new CfLoad(ValueType.LONG, 3),
- new CfLoad(ValueType.LONG, 3),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("unsignedMultiplyExact")),
- false),
- new CfStore(ValueType.LONG, 3),
- label12,
- new CfLoad(ValueType.INT, 2),
- new CfConstNumber(1, ValueType.INT),
- new CfLogicalBinop(CfLogicalBinop.Opcode.Ushr, NumericType.INT),
- new CfStore(ValueType.INT, 2),
- new CfGoto(label8),
- label13,
- new CfFrame(
- new Int2ObjectAVLTreeMap<>(
- new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
- new FrameType[] {
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.intType(),
- FrameType.longType(),
- FrameType.longHighType(),
- FrameType.longType(),
- FrameType.longHighType()
- })),
+ new CfStore(ValueType.LONG, 12),
+ label5,
+ new CfLoad(ValueType.LONG, 4),
+ new CfLoad(ValueType.LONG, 10),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+ new CfLoad(ValueType.LONG, 12),
+ new CfConstNumber(32, ValueType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Ushr, NumericType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+ new CfStore(ValueType.LONG, 14),
+ label6,
+ new CfLoad(ValueType.LONG, 14),
+ new CfConstNumber(4294967295L, ValueType.LONG),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.And, NumericType.LONG),
+ new CfStore(ValueType.LONG, 16),
+ label7,
+ new CfLoad(ValueType.LONG, 14),
+ new CfConstNumber(32, ValueType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Shr, NumericType.LONG),
+ new CfStore(ValueType.LONG, 18),
+ label8,
+ new CfLoad(ValueType.LONG, 16),
+ new CfLoad(ValueType.LONG, 6),
new CfLoad(ValueType.LONG, 8),
- new CfLoad(ValueType.LONG, 3),
- new CfInvoke(
- 184,
- factory.createMethod(
- factory.createType("Ljava/lang/Math;"),
- factory.createProto(factory.longType, factory.longType, factory.longType),
- factory.createString("unsignedMultiplyExact")),
- false),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+ new CfStore(ValueType.LONG, 16),
+ label9,
+ new CfLoad(ValueType.LONG, 4),
+ new CfLoad(ValueType.LONG, 8),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Mul, NumericType.LONG),
+ new CfLoad(ValueType.LONG, 18),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+ new CfLoad(ValueType.LONG, 16),
+ new CfConstNumber(32, ValueType.INT),
+ new CfLogicalBinop(CfLogicalBinop.Opcode.Shr, NumericType.LONG),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+ new CfStore(ValueType.LONG, 20),
+ label10,
+ new CfLoad(ValueType.LONG, 0),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.GE, ValueType.INT, label12),
+ label11,
+ new CfLoad(ValueType.LONG, 20),
+ new CfLoad(ValueType.LONG, 2),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+ new CfStore(ValueType.LONG, 20),
+ label12,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
+ },
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfLoad(ValueType.LONG, 2),
+ new CfConstNumber(0, ValueType.LONG),
+ new CfCmp(Cmp.Bias.NONE, NumericType.LONG),
+ new CfIf(IfType.GE, ValueType.INT, label14),
+ label13,
+ new CfLoad(ValueType.LONG, 20),
+ new CfLoad(ValueType.LONG, 0),
+ new CfArithmeticBinop(CfArithmeticBinop.Opcode.Add, NumericType.LONG),
+ new CfStore(ValueType.LONG, 20),
+ label14,
+ new CfFrame(
+ new Int2ObjectAVLTreeMap<>(
+ new int[] {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
+ },
+ new FrameType[] {
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType(),
+ FrameType.longType(),
+ FrameType.longHighType()
+ })),
+ new CfLoad(ValueType.LONG, 20),
new CfReturn(ValueType.LONG),
- label14),
+ label15),
ImmutableList.of(),
ImmutableList.of());
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/BackportMethodsStub.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/BackportMethodsStub.java
index 2545d6a..7f2f17e 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/BackportMethodsStub.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/BackportMethodsStub.java
@@ -40,47 +40,4 @@
return 0L;
}
}
-
- static class MathStub {
-
- public static long ceilMod(long x, int y) {
- return 0L;
- }
-
- public static long ceilMod(long x, long y) {
- return 0L;
- }
-
- public static int ceilDiv(int x, int y) {
- return 0;
- }
-
- public static long ceilDiv(long x, int y) {
- return 0L;
- }
-
- public static long ceilDiv(long x, long y) {
- return 0L;
- }
-
- public static int unsignedMultiplyExact(int x, int y) {
- return 0;
- }
-
- public static long unsignedMultiplyExact(long x, int y) {
- return 0L;
- }
-
- public static long unsignedMultiplyExact(long x, long y) {
- return 0L;
- }
-
- public static long unsignedMultiplyHigh(long x, long y) {
- return 0L;
- }
-
- public static long multiplyHigh(long x, long y) {
- return 0L;
- }
- }
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
index d7a1770..e2a7e4e 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
@@ -18,7 +18,6 @@
import com.android.tools.r8.ir.desugar.backports.BackportMethodsStub.AndroidOsBuildStub;
import com.android.tools.r8.ir.desugar.backports.BackportMethodsStub.AndroidOsBuildVersionStub;
import com.android.tools.r8.ir.desugar.backports.BackportMethodsStub.LongStub;
-import com.android.tools.r8.ir.desugar.backports.BackportMethodsStub.MathStub;
import com.android.tools.r8.ir.desugar.backports.BackportMethodsStub.UnsafeStub;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
@@ -109,8 +108,6 @@
ImmutableMap.of(
classToType(LongStub.class),
factory.boxedLongType,
- classToType(MathStub.class),
- factory.mathType,
classToType(UnsafeStub.class),
factory.unsafeType,
classToType(AndroidOsBuildStub.class),
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/MathMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/MathMethods.java
index 38f2fb5..86995f4 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/MathMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/MathMethods.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.ir.desugar.backports;
-import com.android.tools.r8.ir.desugar.backports.BackportMethodsStub.MathStub;
-
public final class MathMethods {
public static int addExactInt(int x, int y) {
@@ -288,14 +286,28 @@
if (x == Integer.MIN_VALUE && y == -1) {
throw new ArithmeticException("integer overflow");
}
- return MathStub.ceilDiv(x, y);
+ // Inlined: return Math.ceilDiv(x, y);
+ int div = x / y;
+ int rem = x % y;
+ boolean sameSign = (x ^ y) >= 0;
+ if (sameSign && (rem != 0)) {
+ return div + 1;
+ }
+ return div;
}
public static long ceilDivExactLongLong(long x, long y) {
if (x == Long.MIN_VALUE && y == -1) {
throw new ArithmeticException("long overflow");
}
- return MathStub.ceilDiv(x, y);
+ // Inlined: return Math.ceilDiv(x, y);
+ long div = x / y;
+ long rem = x % y;
+ boolean sameSign = (x ^ y) >= 0;
+ if (sameSign && (rem != 0)) {
+ return div + 1;
+ }
+ return div;
}
public static int ceilDivIntInt(int x, int y) {
@@ -309,7 +321,14 @@
}
public static long ceilDivLongInt(long x, int y) {
- return MathStub.ceilDiv(x, (long) y);
+ // Inlined: return Math.ceilDiv(x, (long) y);
+ long div = x / (long) y;
+ long rem = x % (long) y;
+ boolean sameSign = (x ^ (long) y) >= 0;
+ if (sameSign && (rem != 0)) {
+ return div + 1;
+ }
+ return div;
}
public static long ceilDivLongLong(long x, long y) {
@@ -332,7 +351,10 @@
}
public static int ceilModLongInt(long x, int y) {
- return (int) MathStub.ceilMod(x, (long) y);
+ // Inlined: return (int) Math.ceilMod(x, (long) y);
+ long rem = x % y;
+ boolean sameSign = (x ^ y) >= 0;
+ return (int) ((sameSign && rem != 0) ? rem - y : rem);
}
public static long ceilModLongLong(long x, long y) {
@@ -362,18 +384,43 @@
if (x == Integer.MIN_VALUE && y == -1) {
throw new ArithmeticException("integer overflow");
}
- return Math.floorDiv(x, y);
+ // Inlined: return Math.floorDiv(x,y);
+ int div = x / y;
+ int rem = x - y * div;
+ if (rem == 0) {
+ return div;
+ }
+ int signum = 1 | ((x ^ y) >> (Integer.SIZE - 1));
+ return signum < 0 ? div - 1 : div;
}
public static long floorDivExactLong(long x, long y) {
if (x == Long.MIN_VALUE && y == -1) {
throw new ArithmeticException("long overflow");
}
- return Math.floorDiv(x, y);
+ // Inlined: return Math.floorDiv(x,y);
+ long div = x / y;
+ long rem = x - y * div;
+ if (rem == 0L) {
+ return div;
+ }
+ long signum = 1L | ((x ^ y) >> (Long.SIZE - 1));
+ return signum < 0L ? div - 1L : div;
}
public static long unsignedMultiplyHigh(long x, long y) {
- long result = MathStub.multiplyHigh(x, y);
+ long x1 = x >> 32;
+ long x2 = x & 0xFFFFFFFFL;
+ long y1 = y >> 32;
+ long y2 = y & 0xFFFFFFFFL;
+
+ long z2 = x2 * y2;
+ long t = x1 * y2 + (z2 >>> 32);
+ long z1 = t & 0xFFFFFFFFL;
+ long z0 = t >> 32;
+ z1 += x2 * y1;
+
+ long result = x1 * y1 + z0 + (z1 >> 32);
if (x < 0) {
result += y;
}
@@ -382,114 +429,4 @@
}
return result;
}
-
- public static int unsignedMultiplyExactIntInt(int x, int y) {
- long r = (x & 0xFFFF_FFFFL) * (y & 0xFFFF_FFFFL);
- if (r >>> 32 != 0) {
- throw new ArithmeticException("unsigned integer overflow");
- }
- return (int) r;
- }
-
- public static long unsignedMultiplyExactLongInt(long x, int y) {
- return MathStub.unsignedMultiplyExact(x, y & 0xFFFF_FFFFL);
- }
-
- public static long unsignedMultiplyExactLongLong(long x, long y) {
- long l = x * y;
- long h = MathStub.unsignedMultiplyHigh(x, y);
- if (h == 0) {
- return l;
- }
- throw new ArithmeticException("unsigned long overflow");
- }
-
- public static int unsignedPowExactInt(int x, int y) {
- int result = x;
- if (y < 0) {
- throw new ArithmeticException("negative exponent");
- }
- if (y == 0) {
- return 1;
- }
-
- long mask = 0xFFFF_FFFFL;
-
- int p = 1;
- while (y > 1) {
- if ((y & 1) != 0) {
- p *= result;
- }
- result = MathStub.unsignedMultiplyExact(result, result);
- y >>>= 1;
- }
-
- return MathStub.unsignedMultiplyExact(p, result);
- }
-
- public static long unsignedPowExactLong(long x, int n) {
- long result = x;
- if (n < 0) {
- throw new ArithmeticException("negative exponent");
- }
- if (n == 0) {
- return 1;
- }
-
- int intShift = 32;
- long mask32 = 0xFFFFFFFFL;
-
- long p = 1;
- while (n > 1) {
- if ((n & 1) != 0) {
- p *= result;
- }
- result = MathStub.unsignedMultiplyExact(result, result);
- n >>>= 1;
- }
-
- return MathStub.unsignedMultiplyExact(p, result);
- }
-
- public static int powExactInt(int x, int y) {
- int result = x;
- int operand = y;
- if (operand < 0) {
- throw new ArithmeticException("negative exponent");
- }
- if (operand == 0) {
- return 1;
- }
-
- int p = 1;
- while (operand > 1) {
- if ((operand & 1) != 0) {
- p *= result;
- }
- result = Math.multiplyExact(result, result);
- operand >>>= 1;
- }
- return Math.multiplyExact(p, result);
- }
-
- public static long powExactLong(long x, int y) {
- long result = x;
- int operand = y;
- if (operand < 0) {
- throw new ArithmeticException("negative exponent");
- }
- if (operand == 0) {
- return 1;
- }
-
- long p = 1;
- while (operand > 1) {
- if ((operand & 0b1) != 0) {
- p *= result;
- }
- result = Math.multiplyExact(result, result);
- operand >>>= 1;
- }
- return Math.multiplyExact(p, result);
- }
}
diff --git a/src/test/java25/com/android/tools/r8/jdk25/backport/MathBackportJava25Test.java b/src/test/java25/com/android/tools/r8/jdk25/backport/MathBackportJava25Test.java
deleted file mode 100644
index 22dbb69..0000000
--- a/src/test/java25/com/android/tools/r8/jdk25/backport/MathBackportJava25Test.java
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.jdk25.backport;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.desugar.backports.AbstractBackportTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public final class MathBackportJava25Test extends AbstractBackportTest {
- @Parameters(name = "{0}")
- public static Iterable<?> data() {
- return TestBase.getTestParameters()
- .withCfRuntimesStartingFromIncluding(CfVm.JDK25)
- .withDexRuntimes()
- .withAllApiLevelsAlsoForCf()
- .build();
- }
-
- public MathBackportJava25Test(TestParameters parameters) {
- super(parameters, Math.class, MathBackportJava25Main.class);
- }
-
- public static class MathBackportJava25Main {
- public static void main(String[] args) {
- testUnsignedMultiplyExactLongLong();
- testUnsignedMultiplyExactLongInt();
- testUnsignedMultiplyExactIntInt();
- testUnsignedPowExactLong();
- testUnsignedPowExactInt();
- testPowExactLong();
- testPowExactInt();
- }
-
- static void testPowExactLong() {
- try {
- Math.powExact(42L, -1);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.powExact(0L, 0));
- assertEquals(0, Math.powExact(0L, 1));
- assertEquals(0, Math.powExact(0L, 2));
-
- assertEquals(1, Math.powExact(-1L, 0));
- assertEquals(-1, Math.powExact(-1L, 1));
- assertEquals(1, Math.powExact(-1L, 2));
-
- assertEquals(1, Math.powExact(1L, 0));
- assertEquals(1, Math.powExact(1L, 1));
- assertEquals(1, Math.powExact(1L, 2));
-
- assertEquals(1, Math.powExact(2L, 0));
- assertEquals(2, Math.powExact(2L, 1));
- assertEquals(4, Math.powExact(2L, 2));
-
- assertEquals(1, Math.powExact(Long.MIN_VALUE, 0));
- assertEquals(Long.MIN_VALUE, Math.powExact(Long.MIN_VALUE, 1));
- try {
- Math.powExact(Long.MIN_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.powExact(Long.MAX_VALUE, 0));
- assertEquals(Long.MAX_VALUE, Math.powExact(Long.MAX_VALUE, 1));
- try {
- Math.powExact(Long.MAX_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(4096, Math.powExact((long) (256 / 16), 3));
- assertEquals(512, Math.powExact((long) (256 / 32), 3));
-
- assertEquals(1L << 62, Math.powExact(2L, 62));
- assertEquals(Long.MIN_VALUE, Math.powExact(-2L, 63));
- try {
- Math.powExact(2L, 63);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void testPowExactInt() {
- try {
- Math.powExact(42, -1);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.powExact(0, 0));
- assertEquals(0, Math.powExact(0, 1));
- assertEquals(0, Math.powExact(0, 2));
-
- assertEquals(1, Math.powExact(-1, 0));
- assertEquals(-1, Math.powExact(-1, 1));
- assertEquals(1, Math.powExact(-1, 2));
-
- assertEquals(1, Math.powExact(1, 0));
- assertEquals(1, Math.powExact(1, 1));
- assertEquals(1, Math.powExact(1, 2));
-
- assertEquals(1, Math.powExact(2, 0));
- assertEquals(2, Math.powExact(2, 1));
- assertEquals(4, Math.powExact(2, 2));
-
- assertEquals(1, Math.powExact(Integer.MIN_VALUE, 0));
- assertEquals(Integer.MIN_VALUE, Math.powExact(Integer.MIN_VALUE, 1));
- try {
- Math.powExact(Integer.MIN_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.powExact(Integer.MAX_VALUE, 0));
- assertEquals(Integer.MAX_VALUE, Math.powExact(Integer.MAX_VALUE, 1));
- try {
- Math.powExact(Integer.MAX_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(4096, Math.powExact(256 / 16, 3));
- assertEquals(512, Math.powExact(256 / 32, 3));
-
- assertEquals(1 << -2, Math.powExact(2, Integer.SIZE - 2));
- assertEquals(-1 << -1, Math.powExact(-2, Integer.SIZE - 1));
-
- try {
- Math.powExact(2, 31);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void testUnsignedPowExactLong() {
- try {
- Math.unsignedPowExact(42L, -1);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.unsignedPowExact(0L, 0));
- assertEquals(0, Math.unsignedPowExact(0L, 1));
- assertEquals(0, Math.unsignedPowExact(0L, 2));
-
- assertEquals(1, Math.unsignedPowExact(-1L, 0));
- assertEquals(-1, Math.unsignedPowExact(-1L, 1));
- try {
- Math.unsignedPowExact(-1L, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.unsignedPowExact(1L, 0));
- assertEquals(1, Math.unsignedPowExact(1L, 1));
- assertEquals(1, Math.unsignedPowExact(1L, 2));
-
- assertEquals(1, Math.unsignedPowExact(2L, 0));
- assertEquals(2, Math.unsignedPowExact(2L, 1));
- assertEquals(4, Math.unsignedPowExact(2L, 2));
-
- assertEquals(1, Math.unsignedPowExact(Long.MIN_VALUE, 0));
- assertEquals(Long.MIN_VALUE, Math.unsignedPowExact(Long.MIN_VALUE, 1));
- try {
- Math.unsignedPowExact(Long.MIN_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.unsignedPowExact(Long.MAX_VALUE, 0));
- assertEquals(Long.MAX_VALUE, Math.unsignedPowExact(Long.MAX_VALUE, 1));
- try {
- Math.unsignedPowExact(Long.MAX_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(4096, Math.unsignedPowExact((long) (256 / 16), 3));
- assertEquals(512, Math.unsignedPowExact((long) (256 / 32), 3));
-
- assertEquals(Long.MIN_VALUE, Math.unsignedPowExact(2L, 63));
- try {
- Math.unsignedPowExact(2L, 64);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void testUnsignedPowExactInt() {
- try {
- Math.unsignedPowExact(42, -1);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.unsignedPowExact(0, 0));
- assertEquals(0, Math.unsignedPowExact(0, 1));
- assertEquals(0, Math.unsignedPowExact(0, 2));
-
- assertEquals(1, Math.unsignedPowExact(-1, 0));
- assertEquals(-1, Math.unsignedPowExact(-1, 1));
- try {
- Math.unsignedPowExact(-1, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.unsignedPowExact(1, 0));
- assertEquals(1, Math.unsignedPowExact(1, 1));
- assertEquals(1, Math.unsignedPowExact(1, 2));
-
- assertEquals(1, Math.unsignedPowExact(2, 0));
- assertEquals(2, Math.unsignedPowExact(2, 1));
- assertEquals(4, Math.unsignedPowExact(2, 2));
-
- assertEquals(1, Math.unsignedPowExact(Integer.MIN_VALUE, 0));
- assertEquals(Integer.MIN_VALUE, Math.unsignedPowExact(Integer.MIN_VALUE, 1));
- try {
- Math.unsignedPowExact(Integer.MIN_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1, Math.unsignedPowExact(Integer.MAX_VALUE, 0));
- assertEquals(Integer.MAX_VALUE, Math.unsignedPowExact(Integer.MAX_VALUE, 1));
- try {
- Math.unsignedPowExact(Integer.MAX_VALUE, 2);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(4096, Math.unsignedPowExact(256 / 16, 3));
- assertEquals(512, Math.unsignedPowExact(256 / 32, 3));
-
- assertEquals(Integer.MIN_VALUE, Math.unsignedPowExact(2, 31));
- try {
- Math.unsignedPowExact(2, 32);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void testUnsignedMultiplyExactLongLong() {
- assertEquals(0L, Math.unsignedMultiplyExact(0L, 0L));
- assertEquals(0L, Math.unsignedMultiplyExact(0L, 1L));
- assertEquals(1L, Math.unsignedMultiplyExact(1L, 1L));
-
- assertEquals(256L, Math.unsignedMultiplyExact(16L, 16L));
-
- assertEquals(-2L, Math.unsignedMultiplyExact(Long.MAX_VALUE, 2L));
- assertEquals(Long.MIN_VALUE, Math.unsignedMultiplyExact(Long.MIN_VALUE, 1L));
-
- try {
- Math.unsignedMultiplyExact(Long.MAX_VALUE, 16L);
- fail();
- } catch (ArithmeticException ae) {
- }
- try {
- Math.unsignedMultiplyExact(Long.MIN_VALUE, 16L);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1L << 63, Math.unsignedMultiplyExact(1L << 31, 1L << 32));
- assertEquals(1L << 63, Math.unsignedMultiplyExact(1L << 25, 1L << 38));
- assertEquals(-1L, Math.unsignedMultiplyExact((1L << 32) + 1, (1L << 32) - 1));
-
- try {
- Math.unsignedMultiplyExact(-1L, -1L);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void testUnsignedMultiplyExactLongInt() {
- assertEquals(0, Math.unsignedMultiplyExact(0L, 0));
- assertEquals(0, Math.unsignedMultiplyExact(0L, 1));
- assertEquals(1, Math.unsignedMultiplyExact(1L, 1));
-
- assertEquals(256, Math.unsignedMultiplyExact(16L, 16));
-
- assertEquals(-2, Math.unsignedMultiplyExact(Long.MAX_VALUE, 2));
- assertEquals(Long.MIN_VALUE, Math.unsignedMultiplyExact(Long.MIN_VALUE, 1));
-
- try {
- Math.unsignedMultiplyExact(Long.MAX_VALUE, 16);
- fail();
- } catch (ArithmeticException ae) {
- }
- try {
- Math.unsignedMultiplyExact(Long.MIN_VALUE, 16);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1L << 50, Math.unsignedMultiplyExact(1L << 25, 1 << 25));
- assertEquals(-1L, Math.unsignedMultiplyExact((1L << 32) + 1, -1));
-
- try {
- Math.unsignedMultiplyExact(-1L, -1);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void testUnsignedMultiplyExactIntInt() {
- assertEquals(0, Math.unsignedMultiplyExact(0, 0));
- assertEquals(0, Math.unsignedMultiplyExact(0, 1));
- assertEquals(1, Math.unsignedMultiplyExact(1, 1));
-
- assertEquals(256, Math.unsignedMultiplyExact(16, 16));
-
- assertEquals(-2, Math.unsignedMultiplyExact(Integer.MAX_VALUE, 2));
- assertEquals(Integer.MIN_VALUE, Math.unsignedMultiplyExact(Integer.MIN_VALUE, 1));
-
- try {
- Math.unsignedMultiplyExact(Integer.MAX_VALUE, 16);
- fail();
- } catch (ArithmeticException ae) {
- }
- try {
- Math.unsignedMultiplyExact(Integer.MIN_VALUE, 16);
- fail();
- } catch (ArithmeticException ae) {
- }
-
- assertEquals(1 << 31, Math.unsignedMultiplyExact(1 << 15, 1 << 16));
- assertEquals(1 << 31, Math.unsignedMultiplyExact(1 << 10, 1 << 21));
- assertEquals(-1, Math.unsignedMultiplyExact((1 << 16) + 1, (1 << 16) - 1));
-
- try {
- Math.unsignedMultiplyExact(-1, -1);
- fail();
- } catch (ArithmeticException ae) {
- }
- }
-
- static void assertEquals(int x, int y) {
- if (x != y) {
- throw new RuntimeException("Not equals " + x + " and " + y);
- }
- }
-
- static void assertEquals(long x, long y) {
- if (x != y) {
- throw new RuntimeException("Not equals " + x + " and " + y);
- }
- }
-
- static void fail() {
- throw new RuntimeException("Test fails.");
- }
- }
-}