blob: 8e446db4211a24d445626b1d5d680f57f6876d01 [file] [log] [blame]
// Copyright (c) 2016, 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.code;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.IndexedDexItem;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.utils.ComparatorUtils;
import java.util.function.BiPredicate;
public abstract class Format35c<T extends IndexedDexItem> extends Base3Format {
public final byte A;
public final byte C;
public final byte D;
public final byte E;
public final byte F;
public final byte G;
public T BBBB;
// A | G | op | BBBB | F | E | D | C
Format35c(int high, BytecodeStream stream, T[] map) {
super(stream);
G = (byte) (high & 0xf);
A = (byte) ((high >> 4) & 0xf);
BBBB = map[read16BitValue(stream)];
int next = read8BitValue(stream);
E = (byte) (next & 0xf);
F = (byte) ((next >> 4) & 0xf);
next = read8BitValue(stream);
C = (byte) (next & 0xf);
D = (byte) ((next >> 4) & 0xf);
}
Format35c(int A, T BBBB, int C, int D, int E, int F, int G) {
assert 0 <= A && A <= Constants.U4BIT_MAX;
assert 0 <= C && C <= Constants.U4BIT_MAX;
assert 0 <= D && D <= Constants.U4BIT_MAX;
assert 0 <= E && E <= Constants.U4BIT_MAX;
assert 0 <= F && F <= Constants.U4BIT_MAX;
assert 0 <= G && G <= Constants.U4BIT_MAX;
this.A = (byte) A;
this.BBBB = BBBB;
this.C = (byte) C;
this.D = (byte) D;
this.E = (byte) E;
this.F = (byte) F;
this.G = (byte) G;
}
@Override
public final int hashCode() {
return ((BBBB.hashCode() << 24) | (A << 20) | (C << 16) | (D << 12) | (E << 8) | (F << 4)
| G) ^ getClass().hashCode();
}
@Override
final int internalCompareTo(Instruction other) {
Format35c<?> o = (Format35c<?>) other;
int diff =
ComparatorUtils.compareInts(
A, o.A,
C, o.C,
D, o.D,
E, o.E,
F, o.F,
G, o.G);
return diff != 0 ? diff : internalCompareBBBB(o);
}
abstract int internalCompareBBBB(Format35c<?> other);
private void appendRegisterArguments(StringBuilder builder, String separator) {
builder.append("{ ");
int[] values = new int[]{C, D, E, F, G};
for (int i = 0; i < A; i++) {
if (i != 0) {
builder.append(separator);
}
builder.append("v").append(values[i]);
}
builder.append(" }");
}
@Override
public String toString(ClassNameMapper naming) {
StringBuilder builder = new StringBuilder();
appendRegisterArguments(builder, " ");
builder.append(" ");
if (naming == null) {
builder.append(BBBB.toSmaliString());
} else {
builder.append(naming.originalNameOf(BBBB));
}
return formatString(builder.toString());
}
@Override
public String toSmaliString(ClassNameMapper naming) {
StringBuilder builder = new StringBuilder();
appendRegisterArguments(builder, ", ");
builder.append(", ");
// TODO(sgjesse): Add support for smali name mapping.
builder.append(BBBB.toSmaliString());
return formatSmaliString(builder.toString());
}
@Override
public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
if (other == null || (this.getClass() != other.getClass())) {
return false;
}
Format35c o = (Format35c) other;
return o.A == A && o.C == C && o.D == D && o.E == E && o.F == F && o.G == G
&& equality.test(BBBB, o.BBBB);
}
}