InstructionCodec.java revision 7baa3b69f87348aa2f4f16375a66be59965e8dd4
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
19537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.IndexType;
20537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.OpcodeInfo;
21537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.Opcodes;
227baa3b69f87348aa2f4f16375a66be59965e8dd4Dan Bornsteinimport com.android.dx.util.DexException;
23740fce415cf1a982e9b035604f432eed378fbd05Dan Bornsteinimport com.android.dx.util.Hex;
24740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
2519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornsteinimport java.io.EOFException;
2619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein
273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein/**
283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Representation of an instruction format, which knows how to decode into
293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * and encode from instances of {@link DecodedInstruction}.
303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */
313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornsteinpublic enum InstructionCodec {
323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_00X() {
333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
3419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
35740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
36740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, 0, null,
37d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L);
383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(insn.getOpcodeUnit());
423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_10X() {
463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
4719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = byte1(opcodeUnit); // should be zero
50740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
51740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
52d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal);
533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(insn.getOpcodeUnit());
573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_12X() {
613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
6219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = nibble2(opcodeUnit);
653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = nibble3(opcodeUnit);
66740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
67740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
68d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
69740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcodeUnit(),
753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             makeByte(insn.getA(), insn.getB())));
763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_11N() {
803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
8119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = nibble2(opcodeUnit);
843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = (nibble3(opcodeUnit) << 28) >> 28; // sign-extend
85740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
86740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
87d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
88740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcodeUnit(),
943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             makeByte(insn.getA(), insn.getLiteralNibble())));
953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_11X() {
993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
10019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
1013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
1023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
103740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
104740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
105d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
106740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
1073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
1103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(codeUnit(insn.getOpcode(), insn.getA()));
1113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
1133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_10T() {
1153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
11619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
117d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.cursor() - 1;
1183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
11932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            int target = (byte) byte1(opcodeUnit); // sign-extend
120740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
121740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
122d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    baseAddress + target, 0L);
1233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
126d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int relativeTarget = insn.getTargetByte(out.cursor());
127d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(codeUnit(insn.getOpcode(), relativeTarget));
1283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
1303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_20T() {
1323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
13319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
134d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.cursor() - 1;
1353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
1363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = byte1(opcodeUnit); // should be zero
1373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int target = (short) in.read(); // sign-extend
138740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
139740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
140d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    baseAddress + target, literal);
1413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
144d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            short relativeTarget = insn.getTargetUnit(out.cursor());
145d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(insn.getOpcodeUnit(), relativeTarget);
1463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
1483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_20BC() {
1503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
15119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
1523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            // Note: We use the literal field to hold the decoded AA value.
1533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
1543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = byte1(opcodeUnit);
1553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.read();
156740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
157740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, index, IndexType.VARIES,
158d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal);
1593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
1623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
1633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getLiteralByte()),
1643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getIndexUnit());
1653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
1673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_22X() {
1693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
17019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
1713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
1723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
1733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = in.read();
174740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
175740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
176d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
177740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
1783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
1813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
1823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
1833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getBUnit());
1843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
1863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_21T() {
1883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
18919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
190d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.cursor() - 1;
1913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
1923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
1933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int target = (short) in.read(); // sign-extend
194740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
195740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
196d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    baseAddress + target, 0L,
197740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
1983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
1993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
201d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            short relativeTarget = insn.getTargetUnit(out.cursor());
202d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(codeUnit(insn.getOpcode(), insn.getA()), relativeTarget);
2033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
2053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_21S() {
2073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
20819cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
2093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
2103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
2113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = (short) in.read(); // sign-extend
212740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
213740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
214d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
215740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
2163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
2193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
2203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
2213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getLiteralUnit());
2223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
2243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_21H() {
2263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
22719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
2283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
2293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
2303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = (short) in.read(); // sign-extend
2313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            /*
2333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein             * Format 21h decodes differently depending on the opcode,
2343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein             * because the "signed hat" might represent either a 32-
2353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein             * or 64- bit value.
2363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein             */
2377ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein            literal <<= (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;
2383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
239740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
240740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
241d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
242740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
2433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
2463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            // See above.
2473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = insn.getOpcode();
2487ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein            int shift = (opcode == Opcodes.CONST_HIGH16) ? 16 : 48;
2493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            short literal = (short) (insn.getLiteral() >> shift);
2503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(codeUnit(opcode, insn.getA()), literal);
2523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
2543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_21C() {
2563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
25719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
2583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
2593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
2603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.read();
2613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            IndexType indexType = OpcodeInfo.getIndexType(opcode);
262740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
263740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, index, indexType,
264d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
265740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
2663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
2693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
2703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
2713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getLiteralUnit());
2723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
2743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_23X() {
2763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
27719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
2783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
2793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
2803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int bc = in.read();
2813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = byte0(bc);
2823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int c = byte1(bc);
283740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ThreeRegisterDecodedInstruction(
284740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
285d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
286740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b, c);
2873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
2903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
2913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
2923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getB(), insn.getC()));
2933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
2943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
2953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
2963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_22B() {
2973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
29819cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
2993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
3003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
3013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int bc = in.read();
3023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = byte0(bc);
3033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = (byte) byte1(bc); // sign-extend
304740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
305740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
306d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
307740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
3083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
3113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
3123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
3133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getB(),
3143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             insn.getLiteralByte()));
3153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
3173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_22T() {
3193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
32019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
321d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.cursor() - 1;
3223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
3233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = nibble2(opcodeUnit);
3243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = nibble3(opcodeUnit);
3253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int target = (short) in.read(); // sign-extend
326740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
327740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
328d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    baseAddress + target, 0L,
329740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
3303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
333d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            short relativeTarget = insn.getTargetUnit(out.cursor());
3343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
3353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(),
3363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             makeByte(insn.getA(), insn.getB())),
337d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    relativeTarget);
3383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
3403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_22S() {
3423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
34319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
3443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
3453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = nibble2(opcodeUnit);
3463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = nibble3(opcodeUnit);
3473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = (short) in.read(); // sign-extend
348740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
349740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
350d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
351740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
3523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
3553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
3563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(),
3573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             makeByte(insn.getA(), insn.getB())),
3583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getLiteralUnit());
3593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
3613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_22C() {
3633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
36419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
3653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
3663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = nibble2(opcodeUnit);
3673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = nibble3(opcodeUnit);
3683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.read();
3693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            IndexType indexType = OpcodeInfo.getIndexType(opcode);
370740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
371740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, index, indexType,
372d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
373740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
3743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
3773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
3783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(),
3793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             makeByte(insn.getA(), insn.getB())),
3803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getIndexUnit());
3813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
3833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_22CS() {
3853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
38619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
3873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
3883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = nibble2(opcodeUnit);
3893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = nibble3(opcodeUnit);
3903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.read();
391740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
392740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, index, IndexType.FIELD_OFFSET,
393d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
394740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
3953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
3963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
3973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
3983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
3993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(),
4003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                             makeByte(insn.getA(), insn.getB())),
4013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getIndexUnit());
4023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
4043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_30T() {
4063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
40719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
408d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.cursor() - 1;
4093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
4103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = byte1(opcodeUnit); // should be zero
4113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int target = in.readInt();
412740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
413740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
414d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    baseAddress + target, literal);
4153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
418d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int relativeTarget = insn.getTarget(out.cursor());
419d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(insn.getOpcodeUnit(),
420d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    unit0(relativeTarget), unit1(relativeTarget));
4213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
4233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_32X() {
4253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
42619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
4273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
4283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = byte1(opcodeUnit); // should be zero
4293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = in.read();
4303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = in.read();
431740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
432740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
433d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
434740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
4353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
4383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(insn.getOpcodeUnit(), insn.getAUnit(), insn.getBUnit());
4393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
4413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_31I() {
4433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
44419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
4453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
4463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
4473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = in.readInt();
448740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
449740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
450d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
451740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
4523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
4553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = insn.getLiteralInt();
4563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
4573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
4583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(literal),
4593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(literal));
4603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
4623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_31T() {
4643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
46519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
466d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.cursor() - 1;
4673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
4683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
469d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int target = baseAddress + in.readInt();
470d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
471d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            /*
472d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein             * Switch instructions need to "forward" their addresses to their
473d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein             * payload target instructions.
474d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein             */
475d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            switch (opcode) {
476d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case Opcodes.PACKED_SWITCH:
477d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case Opcodes.SPARSE_SWITCH: {
478d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    in.setBaseAddress(target, baseAddress);
479d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    break;
480d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                }
481d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
482d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
483740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
484740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
485d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    target, 0L,
486740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
4873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
490d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int relativeTarget = insn.getTarget(out.cursor());
4913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
4923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
493d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    unit0(relativeTarget), unit1(relativeTarget));
4943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
4953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
4963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
4973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_31C() {
4983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
49919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
5013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
5023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.readInt();
5033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            IndexType indexType = OpcodeInfo.getIndexType(opcode);
504740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
505740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, index, indexType,
506d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
507740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
5083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = insn.getIndex();
5123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
5133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
5143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(index),
5153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(index));
5163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_35C() {
5203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
52119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            return decodeRegisterList(this, opcodeUnit, in);
5233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            encodeRegisterList(insn, out);
5273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_35MS() {
5313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
53219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            return decodeRegisterList(this, opcodeUnit, in);
5343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            encodeRegisterList(insn, out);
5383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_35MI() {
5423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
54319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            return decodeRegisterList(this, opcodeUnit, in);
5453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            encodeRegisterList(insn, out);
5493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_3RC() {
5533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
55419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            return decodeRegisterRange(this, opcodeUnit, in);
5563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            encodeRegisterRange(insn, out);
5603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_3RMS() {
5643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
56519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            return decodeRegisterRange(this, opcodeUnit, in);
5673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            encodeRegisterRange(insn, out);
5713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_3RMI() {
5753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
57619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            return decodeRegisterRange(this, opcodeUnit, in);
5783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            encodeRegisterRange(insn, out);
5823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
5843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_51L() {
5863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
58719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
5883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int opcode = byte0(opcodeUnit);
5893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte1(opcodeUnit);
5903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            long literal = in.readLong();
591740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
592740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcode, 0, null,
593d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
594740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
5953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
5963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
5973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
5983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = insn.getLiteralInt();
5993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
6003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getOpcode(), insn.getA()),
6013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(literal),
6023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(literal),
6033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit2(literal),
6043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit3(literal));
6053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
6073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_33X() {
6093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
61019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
6113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int ab = in.read();
6123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte0(ab);
6133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = byte1(ab);
6143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int c = in.read();
615740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ThreeRegisterDecodedInstruction(
616740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, 0, null,
617d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
618740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b, c);
6193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
6223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
6233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getOpcodeUnit(),
6243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getA(), insn.getB()),
6253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getCUnit());
6263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
6283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_32S() {
6303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
63119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
6323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int ab = in.read();
6333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = byte0(ab);
6343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = byte1(ab);
6353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = (short) in.read(); // sign-extend
636740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
637740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, 0, null,
638d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal,
639740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
6403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
6433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
6443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getOpcodeUnit(),
6453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    codeUnit(insn.getA(), insn.getB()),
6463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getLiteralUnit());
6473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
6493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_40SC() {
6513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
65219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
6533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            // Note: We use the literal field to hold the decoded AA value.
6543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.readInt();
6553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int literal = in.read();
656740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new ZeroRegisterDecodedInstruction(
657740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, index, IndexType.VARIES,
658d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, literal);
6593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
6623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = insn.getIndex();
6633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
6643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getOpcodeUnit(),
6653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(index),
6663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(index),
6673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getLiteralUnit());
6683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
6703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_41C() {
6723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
67319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
6743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.readInt();
6753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = in.read();
6763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
677740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new OneRegisterDecodedInstruction(
678740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, index, indexType,
679d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
680740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a);
6813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
6843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = insn.getIndex();
6853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
6863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getOpcodeUnit(),
6873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(index),
6883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(index),
6893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getAUnit());
6903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
6913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
6923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
6933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_52C() {
6943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
69519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
6963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.readInt();
6973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = in.read();
6983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int b = in.read();
6993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
700740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new TwoRegisterDecodedInstruction(
701740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, index, indexType,
702d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
703740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, b);
7043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
7053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
7063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
7073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = insn.getIndex();
7083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
7093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getOpcodeUnit(),
7103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(index),
7113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(index),
7123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getAUnit(),
7133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getBUnit());
7143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
7153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    },
7163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
7173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    FORMAT_5RC() {
7183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
71919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein                CodeInput in) throws EOFException {
7203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = in.readInt();
7213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int registerCount = in.read();
7223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int a = in.read();
7233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
724740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            return new RegisterRangeDecodedInstruction(
725740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    this, opcodeUnit, index, indexType,
726d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    0, 0L,
727740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                    a, registerCount);
7283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
7293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
7303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
7313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int index = insn.getIndex();
7323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            out.write(
7333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getOpcodeUnit(),
7343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit0(index),
7353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    unit1(index),
7363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getRegisterCountUnit(),
7373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                    insn.getAUnit());
7383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
73932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    },
74032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
74132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    FORMAT_PACKED_SWITCH_PAYLOAD() {
74232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
74332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein                CodeInput in) throws EOFException {
744d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.baseAddressForCursor();
74532dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            int size = in.read();
746d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int firstKey = in.readInt();
747d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int[] targets = new int[size];
74832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
749d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            for (int i = 0; i < size; i++) {
750d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                targets[i] = baseAddress + in.readInt();
75132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            }
75232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
753d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            return new PackedSwitchPayloadDecodedInstruction(
754d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    this, opcodeUnit, firstKey, targets);
75532dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        }
75632dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
75732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
758d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            PackedSwitchPayloadDecodedInstruction payload =
759d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                (PackedSwitchPayloadDecodedInstruction) insn;
760d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int[] targets = payload.getTargets();
761d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = out.baseAddressForCursor();
762d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
763d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(payload.getOpcodeUnit());
764d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(asUnsignedUnit(targets.length));
765d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.writeInt(payload.getFirstKey());
766d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
767d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            for (int target : targets) {
768d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                out.writeInt(target - baseAddress);
769d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
77032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        }
77132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    },
77232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
77332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    FORMAT_SPARSE_SWITCH_PAYLOAD() {
77432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
77532dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein                CodeInput in) throws EOFException {
776d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = in.baseAddressForCursor();
77732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            int size = in.read();
778d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int[] keys = new int[size];
779d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int[] targets = new int[size];
78032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
781d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            for (int i = 0; i < size; i++) {
782d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                keys[i] = in.readInt();
783d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
78432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
785d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            for (int i = 0; i < size; i++) {
786d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                targets[i] = baseAddress + in.readInt();
78732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            }
78832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
789d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            return new SparseSwitchPayloadDecodedInstruction(
790d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    this, opcodeUnit, keys, targets);
79132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        }
79232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
79332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
794d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            SparseSwitchPayloadDecodedInstruction payload =
795d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                (SparseSwitchPayloadDecodedInstruction) insn;
796d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int[] keys = payload.getKeys();
797d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int[] targets = payload.getTargets();
798d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            int baseAddress = out.baseAddressForCursor();
799d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
800d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(payload.getOpcodeUnit());
801d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(asUnsignedUnit(targets.length));
802d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
803d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            for (int key : keys) {
804d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                out.writeInt(key);
805d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
806d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
807d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            for (int target : targets) {
808d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                out.writeInt(target - baseAddress);
809d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
81032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        }
81132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    },
81232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
81332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein    FORMAT_FILL_ARRAY_DATA_PAYLOAD() {
81432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        @Override public DecodedInstruction decode(int opcodeUnit,
81532dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein                CodeInput in) throws EOFException {
81632dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            int elementWidth = in.read();
81732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            int size = in.readInt();
81832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
819d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            switch (elementWidth) {
820d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 1: {
821d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    byte[] array = new byte[size];
822d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    boolean even = true;
823d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    for (int i = 0, value = 0; i < size; i++, even = !even) {
824d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        if (even) {
825d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                            value = in.read();
826d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        }
827d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        array[i] = (byte) (value & 0xff);
828d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        value >>= 8;
829d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    }
830d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    return new FillArrayDataPayloadDecodedInstruction(
831d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                            this, opcodeUnit, array);
832d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                }
833d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 2: {
834d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    short[] array = new short[size];
835d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    for (int i = 0; i < size; i++) {
836d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        array[i] = (short) in.read();
837d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    }
838d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    return new FillArrayDataPayloadDecodedInstruction(
839d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                            this, opcodeUnit, array);
840d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                }
841d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 4: {
842d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    int[] array = new int[size];
843d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    for (int i = 0; i < size; i++) {
844d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        array[i] = in.readInt();
845d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    }
846d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    return new FillArrayDataPayloadDecodedInstruction(
847d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                            this, opcodeUnit, array);
848d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                }
849d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 8: {
850d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    long[] array = new long[size];
851d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    for (int i = 0; i < size; i++) {
852d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        array[i] = in.readLong();
853d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    }
854d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    return new FillArrayDataPayloadDecodedInstruction(
855d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                            this, opcodeUnit, array);
856d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                }
85732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein            }
85832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
859d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            throw new DexException("bogus element_width: "
860d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    + Hex.u2(elementWidth));
86132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        }
86232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein
86332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        @Override public void encode(DecodedInstruction insn, CodeOutput out) {
864d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            FillArrayDataPayloadDecodedInstruction payload =
865d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                (FillArrayDataPayloadDecodedInstruction) insn;
866d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            short elementWidth = payload.getElementWidthUnit();
867d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            Object data = payload.getData();
868d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
869d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(payload.getOpcodeUnit());
870d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.write(elementWidth);
871d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            out.writeInt(payload.getSize());
872d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
873d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            switch (elementWidth) {
874d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 1: out.write((byte[]) data);  break;
875d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 2: out.write((short[]) data); break;
876d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 4: out.write((int[]) data);   break;
877d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                case 8: out.write((long[]) data);  break;
878d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                default: {
879d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                    throw new DexException("bogus element_width: "
880d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                            + Hex.u2(elementWidth));
881d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                }
882d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
88332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein        }
8843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    };
8853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
8863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
8873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Decodes an instruction specified by the given opcode unit, reading
8883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * any required additional code units from the given input source.
8893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
89019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein    public abstract DecodedInstruction decode(int opcodeUnit, CodeInput in)
89119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein        throws EOFException;
8923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
8933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
8943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Encodes the given instruction.
8953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
8963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    public abstract void encode(DecodedInstruction insn, CodeOutput out);
8973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
8983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
8993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Helper method that decodes any of the register-list formats.
9003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
9013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static DecodedInstruction decodeRegisterList(
90219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein            InstructionCodec format, int opcodeUnit, CodeInput in)
90319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein            throws EOFException {
9043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int opcode = byte0(opcodeUnit);
9053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int e = nibble2(opcodeUnit);
9063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int registerCount = nibble3(opcodeUnit);
9073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int index = in.read();
9083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int abcd = in.read();
9093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int a = nibble0(abcd);
9103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int b = nibble1(abcd);
9113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int c = nibble2(abcd);
9123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int d = nibble3(abcd);
9133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        IndexType indexType = OpcodeInfo.getIndexType(opcode);
914740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
915740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        // TODO: Having to switch like this is less than ideal.
916740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        switch (registerCount) {
917740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            case 0:
918740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                return new ZeroRegisterDecodedInstruction(
919740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        format, opcode, index, indexType,
920d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        0, 0L);
921740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            case 1:
922740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                return new OneRegisterDecodedInstruction(
923740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        format, opcode, index, indexType,
924d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        0, 0L,
925740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        a);
926740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            case 2:
927740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                return new TwoRegisterDecodedInstruction(
928740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        format, opcode, index, indexType,
929d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        0, 0L,
930740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        a, b);
931740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            case 3:
932740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                return new ThreeRegisterDecodedInstruction(
933740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        format, opcode, index, indexType,
934d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        0, 0L,
935740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        a, b, c);
936740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            case 4:
937740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                return new FourRegisterDecodedInstruction(
938740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        format, opcode, index, indexType,
939d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        0, 0L,
940740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        a, b, c, d);
941740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein            case 5:
942740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                return new FiveRegisterDecodedInstruction(
943740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        format, opcode, index, indexType,
944d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                        0, 0L,
945740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                        a, b, c, d, e);
946740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        }
947740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein
948740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        throw new DexException("bogus registerCount: "
949740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                + Hex.uNibble(registerCount));
9503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
9513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
9523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
9533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Helper method that encodes any of the register-list formats.
9543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
9553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static void encodeRegisterList(DecodedInstruction insn,
9563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            CodeOutput out) {
9573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        out.write(codeUnit(insn.getOpcode(),
9583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                        makeByte(insn.getE(), insn.getRegisterCount())),
9593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                insn.getIndexUnit(),
9603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                codeUnit(insn.getA(), insn.getB(), insn.getC(), insn.getD()));
9613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
9623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
9633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
9643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Helper method that decodes any of the three-unit register-range formats.
9653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
9663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static DecodedInstruction decodeRegisterRange(
96719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein            InstructionCodec format, int opcodeUnit, CodeInput in)
96819cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein            throws EOFException {
9693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int opcode = byte0(opcodeUnit);
9703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int registerCount = byte1(opcodeUnit);
9713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int index = in.read();
9723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        int a = in.read();
9733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        IndexType indexType = OpcodeInfo.getIndexType(opcode);
974740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein        return new RegisterRangeDecodedInstruction(
975740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                format, opcode, index, indexType,
976d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                0, 0L,
977740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein                a, registerCount);
9783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
9793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
9803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    /**
9813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     * Helper method that encodes any of the three-unit register-range formats.
9823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein     */
9833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static void encodeRegisterRange(DecodedInstruction insn,
9843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            CodeOutput out) {
9853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        out.write(codeUnit(insn.getOpcode(), insn.getRegisterCount()),
9863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                insn.getIndexUnit(),
9873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                insn.getAUnit());
9883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
9893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
9903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short codeUnit(int lowByte, int highByte) {
9913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((lowByte & ~0xff) != 0) {
9923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus lowByte");
9933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
9943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
9953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((highByte & ~0xff) != 0) {
9963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus highByte");
9973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
9983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
9993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) (lowByte | (highByte << 8));
10003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short codeUnit(int nibble0, int nibble1, int nibble2,
10033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            int nibble3) {
10043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((nibble0 & ~0xf) != 0) {
10053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus nibble0");
10063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
10073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((nibble1 & ~0xf) != 0) {
10093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus nibble1");
10103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
10113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((nibble2 & ~0xf) != 0) {
10133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus nibble2");
10143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
10153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((nibble3 & ~0xf) != 0) {
10173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus nibble3");
10183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
10193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) (nibble0 | (nibble1 << 4)
10213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein                | (nibble2 << 8) | (nibble3 << 12));
10223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int makeByte(int lowNibble, int highNibble) {
10253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((lowNibble & ~0xf) != 0) {
10263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus lowNibble");
10273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
10283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        if ((highNibble & ~0xf) != 0) {
10303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein            throw new IllegalArgumentException("bogus highNibble");
10313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        }
10323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return lowNibble | (highNibble << 4);
10343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
1036d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    private static short asUnsignedUnit(int value) {
1037d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        if ((value & ~0xffff) != 0) {
1038d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            throw new IllegalArgumentException("bogus unsigned code unit");
1039d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        }
1040d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
1041d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        return (short) value;
1042d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
1043d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
10443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short unit0(int value) {
10453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) value;
10463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short unit1(int value) {
10493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) (value >> 16);
10503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short unit0(long value) {
10533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) value;
10543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short unit1(long value) {
10573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) (value >> 16);
10583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short unit2(long value) {
10613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) (value >> 32);
10623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static short unit3(long value) {
10653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (short) (value >> 48);
10663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int byte0(int value) {
10693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return value & 0xff;
10703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int byte1(int value) {
10733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (value >> 8) & 0xff;
10743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int byte2(int value) {
10773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (value >> 16) & 0xff;
10783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int byte3(int value) {
10813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return value >>> 24;
10823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int nibble0(int value) {
10853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return value & 0xf;
10863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int nibble1(int value) {
10893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (value >> 4) & 0xf;
10903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int nibble2(int value) {
10933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (value >> 8) & 0xf;
10943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein
10963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    private static int nibble3(int value) {
10973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein        return (value >> 12) & 0xf;
10983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein    }
10993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein}
1100