13c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein/*
23c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Copyright (C) 2011 The Android Open Source Project
33c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein *
43c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Licensed under the Apache License, Version 2.0 (the "License");
53c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * you may not use this file except in compliance with the License.
63c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * You may obtain a copy of the License at
73c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein *
83c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein *      http://www.apache.org/licenses/LICENSE-2.0
93c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein *
103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Unless required by applicable law or agreed to in writing, software
113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * distributed under the License is distributed on an "AS IS" BASIS,
123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * See the License for the specific language governing permissions and
143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * limitations under the License.
153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */
163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
17537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinpackage com.android.dx.io.instructions;
183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.DexException;
20537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.IndexType;
21537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.OpcodeInfo;
22537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.Opcodes;
2386f38347e3aa34c146ccba141bb091b340b7791aDan Bornsteinimport com.android.dx.util.Hex;
24a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornsteinimport java.io.EOFException;
25a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein
263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein/**
273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * A decoded Dalvik instruction. This consists of a format codec, a
283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * numeric opcode, an optional index type, and any additional
293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * arguments of the instruction. The additional arguments (if any) are
303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * represented as uninterpreted data.
313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein *
323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * <p><b>Note:</b> The names of the arguments are <i>not</i> meant to
333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * match the names given in the Dalvik instruction format
343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * specification, specification which just names fields (somewhat)
353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * arbitrarily alphabetically from A. In this class, non-register
363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * fields are given descriptive names and register fields are
373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * consistently named alphabetically.</p>
383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */
39740fce415cf1a982e9b035604f432eed378fbd05Dan Bornsteinpublic abstract class DecodedInstruction {
403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /** non-null; instruction format / codec */
413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private final InstructionCodec format;
423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /** opcode number */
443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private final int opcode;
453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /** constant index argument */
473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private final int index;
483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /** null-ok; index type */
503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private final IndexType indexType;
513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    /**
53d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * target address argument. This is an absolute address, not just
54d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * a signed offset. <b>Note:</b> The address is unsigned, even
55d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * though it is stored in an {@code int}.
5632dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein     */
573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private final int target;
583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * literal value argument; also used for special verification error
61ab35b50311951feea3782151dd5422ee944685c2Elliott Hughes     * constants (format 20bc) as well as should-be-zero values
623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * (formats 10x, 20t, 30t, and 32x)
633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private final long literal;
653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
67a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein     * Decodes an instruction from the given input source.
68a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein     */
69a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein    public static DecodedInstruction decode(CodeInput in) throws EOFException {
70a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein        int opcodeUnit = in.read();
71a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein        int opcode = Opcodes.extractOpcodeFromUnit(opcodeUnit);
72a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein        InstructionCodec format = OpcodeInfo.getFormat(opcode);
73a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein
74a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein        return format.decode(opcodeUnit, in);
75a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein    }
76a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein
77a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein    /**
7838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     * Decodes an array of instructions. The result has non-null
7938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     * elements at each offset that represents the start of an
8038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     * instruction.
8138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     */
8238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public static DecodedInstruction[] decodeAll(short[] encodedInstructions) {
8338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        int size = encodedInstructions.length;
8438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        DecodedInstruction[] decoded = new DecodedInstruction[size];
8538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions);
8638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
8738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        try {
8838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            while (in.hasMore()) {
8938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein                decoded[in.cursor()] = DecodedInstruction.decode(in);
9038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            }
9138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        } catch (EOFException ex) {
922cdb0f99380a09f494977d1799e21e2a79d40a65Jesse Wilson            throw new DexException(ex);
9338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        }
9438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
9538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        return decoded;
9638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
9738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
9838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /**
99740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein     * Constructs an instance.
1003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
1013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    public DecodedInstruction(InstructionCodec format, int opcode,
102d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int index, IndexType indexType, int target, long literal) {
1033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if (format == null) {
1043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new NullPointerException("format == null");
1053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1077ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein        if (!Opcodes.isValidShape(opcode)) {
1083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("invalid opcode");
1093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        this.format = format;
1123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        this.opcode = opcode;
1133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        this.index = index;
1143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        this.indexType = indexType;
1153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        this.target = target;
1163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        this.literal = literal;
1173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
119740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final InstructionCodec getFormat() {
1203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return format;
1213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
123740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final int getOpcode() {
1243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return opcode;
1253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
1283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Gets the opcode, as a code unit.
1293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
130740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getOpcodeUnit() {
1313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) opcode;
1323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
134740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final int getIndex() {
1353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return index;
1363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
1393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Gets the index, as a code unit.
1403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
141740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getIndexUnit() {
1423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) index;
1433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
145740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final IndexType getIndexType() {
1463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return indexType;
1473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
149d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /**
150d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * Gets the raw target.
151d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     */
152740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final int getTarget() {
1533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return target;
1543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
157d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * Gets the target as a relative offset from the given address.
1583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
159d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public final int getTarget(int baseAddress) {
160d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        return target - baseAddress;
161d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
162d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
163d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /**
164d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * Gets the target as a relative offset from the given base
165d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * address, as a code unit. This will throw if the value is out of
166d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * the range of a signed code unit.
167d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     */
168d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public final short getTargetUnit(int baseAddress) {
169d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        int relativeTarget = getTarget(baseAddress);
170d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
171d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        if (relativeTarget != (short) relativeTarget) {
172d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            throw new DexException("Target out of range: "
173d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    + Hex.s4(relativeTarget));
17486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
17586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
176d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        return (short) relativeTarget;
1773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
180d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * Gets the target as a relative offset from the given base
181d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * address, masked to be a byte in size. This will throw if the
182d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * value is out of the range of a signed byte.
1833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
184d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public final int getTargetByte(int baseAddress) {
185d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        int relativeTarget = getTarget(baseAddress);
186d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
187d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        if (relativeTarget != (byte) relativeTarget) {
188d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            throw new DexException("Target out of range: "
189d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    + Hex.s4(relativeTarget));
19086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
19186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
192d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        return relativeTarget & 0xff;
1933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
195740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final long getLiteral() {
1963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return literal;
1973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
1983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
20086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the literal value, masked to be an int in size. This will
20186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * throw if the value is out of the range of a signed int.
2023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
203740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final int getLiteralInt() {
2041bbb3378b108329c7ab75713fe9507b7ffc7f885Jesse Wilson        if (literal != (int) literal) {
20586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Literal out of range: " + Hex.u8(literal));
20686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
20786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
2083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (int) literal;
2093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
2103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
21286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the literal value, as a code unit. This will throw if the
21386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of a signed code unit.
2143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
215740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getLiteralUnit() {
2161bbb3378b108329c7ab75713fe9507b7ffc7f885Jesse Wilson        if (literal != (short) literal) {
21786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Literal out of range: " + Hex.u8(literal));
21886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
21986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
2203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) literal;
2213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
2223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
22486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the literal value, masked to be a byte in size. This will
22586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * throw if the value is out of the range of a signed byte.
2263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
227740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final int getLiteralByte() {
2281bbb3378b108329c7ab75713fe9507b7ffc7f885Jesse Wilson        if (literal != (byte) literal) {
22986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Literal out of range: " + Hex.u8(literal));
23086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
23186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
2323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (int) literal & 0xff;
2333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
2343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
23686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the literal value, masked to be a nibble in size. This
23786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * will throw if the value is out of the range of a signed nibble.
2383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
239740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final int getLiteralNibble() {
24086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((literal < -8) || (literal > 7)) {
24186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Literal out of range: " + Hex.u8(literal));
24286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
24386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
2443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (int) literal & 0xf;
2453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
2463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
247740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public abstract int getRegisterCount();
248740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
249740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public int getA() {
250740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        return 0;
251740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    }
252740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
253740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public int getB() {
254740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        return 0;
255740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    }
256740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
257740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public int getC() {
258740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        return 0;
259740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    }
260740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
261740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public int getD() {
262740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        return 0;
263740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    }
264740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
265740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public int getE() {
266740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        return 0;
2673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
2683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
27086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the register count, as a code unit. This will throw if the
27186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned code unit.
2723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
273740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getRegisterCountUnit() {
274740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int registerCount = getRegisterCount();
275740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
27686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((registerCount & ~0xffff) != 0) {
27786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register count out of range: "
27886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein                    + Hex.u8(registerCount));
27986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
28086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
2813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) registerCount;
2823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
2833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
28486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
28586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the A register number, as a code unit. This will throw if the
28686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned code unit.
28786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
288740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getAUnit() {
289740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int a = getA();
290740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
29186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((a & ~0xffff) != 0) {
29286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register A out of range: " + Hex.u8(a));
29386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
29486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
29586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) a;
29686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
29786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
29886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
29986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the A register number, as a byte. This will throw if the
30086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned byte.
30186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
302740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getAByte() {
303740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int a = getA();
304740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
30586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((a & ~0xff) != 0) {
30686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register A out of range: " + Hex.u8(a));
30786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
30886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
30986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) a;
31086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
31186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
31286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
31386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the A register number, as a nibble. This will throw if the
31486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned nibble.
31586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
316740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getANibble() {
317740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int a = getA();
318740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
31986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((a & ~0xf) != 0) {
32086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register A out of range: " + Hex.u8(a));
32186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
32286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
3233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) a;
3243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
3253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
32686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
32786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the B register number, as a code unit. This will throw if the
32886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned code unit.
32986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
330740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getBUnit() {
331740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int b = getB();
332740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
33386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((b & ~0xffff) != 0) {
33486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register B out of range: " + Hex.u8(b));
33586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
33686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
33786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) b;
33886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
33986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
34086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
34186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the B register number, as a byte. This will throw if the
34286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned byte.
34386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
344740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getBByte() {
345740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int b = getB();
346740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
34786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((b & ~0xff) != 0) {
34886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register B out of range: " + Hex.u8(b));
34986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
35086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
35186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) b;
35286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
35386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
35486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
35586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the B register number, as a nibble. This will throw if the
35686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned nibble.
35786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
358740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getBNibble() {
359740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int b = getB();
360740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
36186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((b & ~0xf) != 0) {
36286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register B out of range: " + Hex.u8(b));
36386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
36486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
3653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) b;
3663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
3673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
36886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
36986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the C register number, as a code unit. This will throw if the
37086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned code unit.
37186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
372740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getCUnit() {
373740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int c = getC();
374740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
37586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((c & ~0xffff) != 0) {
37686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register C out of range: " + Hex.u8(c));
37786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
37886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
37986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) c;
38086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
38186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
38286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
38386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the C register number, as a byte. This will throw if the
38486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned byte.
38586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
386740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getCByte() {
387740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int c = getC();
388740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
38986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((c & ~0xff) != 0) {
39086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register C out of range: " + Hex.u8(c));
39186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
39286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
39386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) c;
39486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
39586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
39686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
39786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the C register number, as a nibble. This will throw if the
39886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned nibble.
39986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
400740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getCNibble() {
401740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int c = getC();
402740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
40386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((c & ~0xf) != 0) {
40486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register C out of range: " + Hex.u8(c));
40586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
40686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
40786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) c;
4083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
4093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
41086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
41186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the D register number, as a code unit. This will throw if the
41286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned code unit.
41386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
414740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getDUnit() {
415740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int d = getD();
416740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
41786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((d & ~0xffff) != 0) {
41886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register D out of range: " + Hex.u8(d));
41986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
42086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
42186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) d;
42286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
42386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
42486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
42586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the D register number, as a byte. This will throw if the
42686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned byte.
42786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
428740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getDByte() {
429740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int d = getD();
430740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
43186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((d & ~0xff) != 0) {
43286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register D out of range: " + Hex.u8(d));
43386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
43486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
43586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) d;
43686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
43786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
43886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
43986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the D register number, as a nibble. This will throw if the
44086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned nibble.
44186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
442740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getDNibble() {
443740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int d = getD();
444740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
44586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((d & ~0xf) != 0) {
44686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register D out of range: " + Hex.u8(d));
44786f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
44886f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
44986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) d;
45086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
45186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
4523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
45386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * Gets the E register number, as a nibble. This will throw if the
45486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     * value is out of the range of an unsigned nibble.
45586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein     */
456740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final short getENibble() {
457740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        int e = getE();
458740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
45986f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        if ((e & ~0xf) != 0) {
46086f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein            throw new DexException("Register E out of range: " + Hex.u8(e));
46186f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        }
46286f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
46386f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein        return (short) e;
46486f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    }
46586f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein
46686f38347e3aa34c146ccba141bb091b340b7791aDan Bornstein    /**
467a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein     * Encodes this instance to the given output.
468a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein     */
469740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public final void encode(CodeOutput out) {
470a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein        format.encode(this, out);
471a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein    }
472a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein
473a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein    /**
474a2c9b2631e0e0034fdd6518e45a20d27914c731fDan Bornstein     * Returns an instance just like this one, except with the index replaced
4753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * with the given one.
4763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
477740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein    public abstract DecodedInstruction withIndex(int newIndex);
4783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein}
479