blob: fc884612a0d88cdbf7c0d6c69f0a23874490681f [file] [log] [blame]
// Copyright (c) 2017, 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 static com.android.tools.r8.dex.Constants.U4BIT_MAX;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.IndexedDexItem;
import com.android.tools.r8.graph.ObjectToOffsetMapping;
import com.android.tools.r8.naming.ClassNameMapper;
import java.nio.ShortBuffer;
/** Format45cc for instructions of size 4, with 5 registers and 2 constant pool index. */
public abstract class Format45cc extends Base4Format {
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 DexMethod BBBB;
public DexProto HHHH;
Format45cc(int high, BytecodeStream stream, DexMethod[] methodMap, DexProto[] protoMap) {
super(stream);
G = (byte) (high & 0xf);
A = (byte) ((high >> 4) & 0xf);
BBBB = methodMap[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);
HHHH = protoMap[read16BitValue(stream)];
}
// A | G | op | [meth]@BBBB | F | E | D | C | [proto]@HHHH
protected Format45cc(int A, DexMethod BBBB, DexProto HHHH, int C, int D, int E, int F, int G) {
assert 0 <= A && A <= U4BIT_MAX;
assert 0 <= C && C <= U4BIT_MAX;
assert 0 <= D && D <= U4BIT_MAX;
assert 0 <= E && E <= U4BIT_MAX;
assert 0 <= F && F <= U4BIT_MAX;
assert 0 <= G && G <= U4BIT_MAX;
this.A = (byte) A;
this.BBBB = BBBB;
this.HHHH = HHHH;
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 ((HHHH.hashCode() << 28)
| (BBBB.hashCode() << 24)
| (A << 20)
| (C << 16)
| (D << 12)
| (E << 8)
| (F << 4)
| G)
^ getClass().hashCode();
}
@Override
public final boolean equals(Object other) {
if (other == null || (this.getClass() != other.getClass())) {
return false;
}
Format45cc o = (Format45cc) other;
return o.A == A
&& o.C == C
&& o.D == D
&& o.E == E
&& o.F == F
&& o.G == G
&& o.BBBB.equals(BBBB)
&& o.HHHH.equals(HHHH);
}
@Override
public void collectIndexedItems(IndexedItemCollection indexedItems,
DexMethod method, int instructionOffset) {
BBBB.collectIndexedItems(indexedItems, method, instructionOffset);
HHHH.collectIndexedItems(indexedItems, method, instructionOffset);
}
@Override
public void write(ShortBuffer dest, ObjectToOffsetMapping mapping) {
writeFirst(A, G, dest);
write16BitReference(BBBB, dest, mapping);
write16BitValue(combineBytes(makeByte(F, E), makeByte(D, C)), dest);
write16BitReference(HHHH, dest, mapping);
}
@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());
builder.append(", ");
builder.append(HHHH.toSmaliString());
return formatSmaliString(builder.toString());
}
@Override
public String toString(ClassNameMapper naming) {
StringBuilder builder = new StringBuilder();
appendRegisterArguments(builder, " ");
builder.append(" ");
builder.append(itemToString(BBBB, naming));
builder.append(", ");
builder.append(itemToString(HHHH, naming));
return formatString(builder.toString());
}
private String itemToString(IndexedDexItem indexedDexItem, ClassNameMapper naming) {
String str;
if (naming == null) {
str = indexedDexItem.toSmaliString();
} else {
str = naming.originalNameOf(indexedDexItem);
}
return str;
}
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 DexMethod getMethod() {
return BBBB;
}
@Override
public DexProto getProto() {
return HHHH;
}
}