1b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com/*
2b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * [The "BSD licence"]
300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke)
4b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * All rights reserved.
5b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com *
6b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without
7b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions
8b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * are met:
9b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright
10b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer.
11b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright
12b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer in the
13b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com *    documentation and/or other materials provided with the distribution.
14b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products
15b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com *    derived from this software without specific prior written permission.
16b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com *
17b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com */
28b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
29b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.compackage org.jf.baksmali.Adaptors.Format;
30b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
31754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruverimport org.jf.baksmali.Adaptors.MethodDefinition;
324f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruverimport org.jf.baksmali.Adaptors.MethodDefinition.InvalidSwitchPayload;
33b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.comimport org.jf.baksmali.Adaptors.MethodItem;
34e88723c666db87d414e126ac6d94d683d86ad28dBen Gruverimport org.jf.baksmali.Renderers.LongRenderer;
355a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport org.jf.baksmali.BaksmaliOptions;
364f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruverimport org.jf.dexlib2.Opcode;
37f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruverimport org.jf.dexlib2.ReferenceType;
38db7795ffaa2d8804d84623a79d406f8c8686c1b8Ben Gruverimport org.jf.dexlib2.VerificationError;
39f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruverimport org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex;
40754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruverimport org.jf.dexlib2.iface.instruction.*;
41db7795ffaa2d8804d84623a79d406f8c8686c1b8Ben Gruverimport org.jf.dexlib2.iface.instruction.formats.Instruction20bc;
424f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruverimport org.jf.dexlib2.iface.instruction.formats.Instruction31t;
432363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverimport org.jf.dexlib2.iface.instruction.formats.UnknownInstruction;
44f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruverimport org.jf.dexlib2.iface.reference.Reference;
454f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruverimport org.jf.dexlib2.util.ReferenceUtil;
464f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruverimport org.jf.util.ExceptionWithContext;
474b72225e9d81201838f387171a68a832486903f9JesusFreke@JesusFreke.comimport org.jf.util.IndentingWriter;
4858d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smithimport org.jf.util.NumberUtils;
49b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
50754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruverimport javax.annotation.Nonnull;
516eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.comimport java.io.IOException;
527e9231a211bf00451229d88edb5c7fbd5085f73eJeff Smithimport java.util.Map;
53b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
54b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.compublic class InstructionMethodItem<T extends Instruction> extends MethodItem {
55754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver    @Nonnull protected final MethodDefinition methodDef;
56754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver    @Nonnull protected final T instruction;
57b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
58754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver    public InstructionMethodItem(@Nonnull MethodDefinition methodDef, int codeAddress, @Nonnull T instruction) {
59b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com        super(codeAddress);
60754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        this.methodDef = methodDef;
61b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com        this.instruction = instruction;
62b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
63b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
64da69b22d6fe70d082b18858aea0d15ec383f1865JesusFreke@JesusFreke.com    public double getSortOrder() {
65b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com        //instructions should appear after everything except an "end try" label and .catch directive
66b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com        return 100;
67b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
68b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
694f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver    private boolean isAllowedOdex(@Nonnull Opcode opcode) {
705a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver        BaksmaliOptions options = methodDef.classDef.options;
714f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (options.allowOdex) {
724f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            return true;
734f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
744f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
754f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (methodDef.classDef.options.apiLevel >= 14) {
764f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            return false;
774f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
784f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
793124e94d4b298a1cfc2c9aaeb29c1b0b19dcb504Ben Gruver        return opcode.isVolatileFieldAccessor() || opcode == Opcode.THROW_VERIFICATION_ERROR;
804f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver    }
814f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
82afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath    private String writeInvalidItemIndex(InvalidItemIndex ex, int type, IndentingWriter writer)
83afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            throws IOException {
84afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath        writer.write("#");
85afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath        writer.write(ex.getMessage());
86afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath        writer.write("\n");
87afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath        return String.format("%s@%d", ReferenceType.toString(type), ex.getInvalidIndex());
88afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath    }
89afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath
90b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    @Override
910b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    public boolean writeTo(IndentingWriter writer) throws IOException {
924f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        Opcode opcode = instruction.getOpcode();
934f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        String verificationErrorName = null;
944f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        String referenceString = null;
95afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath        String referenceString2 = null;
964f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
974f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        boolean commentOutInstruction = false;
984f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
994f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (instruction instanceof Instruction20bc) {
1004f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            int verificationError = ((Instruction20bc)instruction).getVerificationError();
1014f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            verificationErrorName = VerificationError.getVerificationErrorName(verificationError);
1024f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            if (verificationErrorName == null) {
1034f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write("#was invalid verification error type: ");
1044f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.printSignedIntAsDec(verificationError);
1054f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write("\n");
1064f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                verificationErrorName = "generic-error";
1074f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            }
1084f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
1094f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
110f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver        if (instruction instanceof ReferenceInstruction) {
1114f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            ReferenceInstruction referenceInstruction = (ReferenceInstruction)instruction;
112afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            String classContext = null;
1133735d4778fdfc6e544650f1e3ced82606fb34e81Ben Gruver            if (methodDef.classDef.options.implicitReferences) {
114afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                classContext = methodDef.method.getDefiningClass();
115afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            }
116afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath
117f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver            try {
1184f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                Reference reference = referenceInstruction.getReference();
119d33fd6773cc3e527b4dbb79245796d556b7facdeBen Gruver                referenceString = ReferenceUtil.getReferenceString(reference, classContext);
1204f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                assert referenceString != null;
121f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver            } catch (InvalidItemIndex ex) {
1224f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                commentOutInstruction = true;
123afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                referenceString = writeInvalidItemIndex(ex, referenceInstruction.getReferenceType(),
124afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                        writer);
1254f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            } catch (ReferenceType.InvalidReferenceTypeException ex) {
1264f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write("#invalid reference type: ");
1274f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.printSignedIntAsDec(ex.getReferenceType());
1284f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                commentOutInstruction = true;
1294f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
1304f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                referenceString = "invalid_reference";
131f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver            }
132afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath
133afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            if (instruction instanceof DualReferenceInstruction) {
134afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                DualReferenceInstruction dualReferenceInstruction =
135afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                        (DualReferenceInstruction) instruction;
136afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                try {
137afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    Reference reference2 = dualReferenceInstruction.getReference2();
138afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    referenceString2 = ReferenceUtil.getReferenceString(reference2, classContext);
139afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                } catch (InvalidItemIndex ex) {
140afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    commentOutInstruction = true;
141afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    referenceString2 = writeInvalidItemIndex(ex,
142afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                            dualReferenceInstruction.getReferenceType2(), writer);
143afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                } catch (ReferenceType.InvalidReferenceTypeException ex) {
144afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    writer.write("#invalid reference type: ");
145afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    writer.printSignedIntAsDec(ex.getReferenceType());
146afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    commentOutInstruction = true;
147afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath
148afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                    referenceString2 = "invalid_reference";
149afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                }
150afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            }
151f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver        }
152f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver
1534f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (instruction instanceof Instruction31t) {
154bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver            boolean validPayload = true;
155bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver
1564f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            switch (instruction.getOpcode()) {
1574f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                case PACKED_SWITCH:
158bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    int baseAddress = methodDef.getPackedSwitchBaseAddress(
159bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                            this.codeAddress + ((Instruction31t)instruction).getCodeOffset());
160bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    if (baseAddress == -1) {
161bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                        validPayload = false;
162bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    }
1634f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                    break;
1644f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                case SPARSE_SWITCH:
165bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    baseAddress = methodDef.getSparseSwitchBaseAddress(
166bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                            this.codeAddress + ((Instruction31t)instruction).getCodeOffset());
167bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    if (baseAddress == -1) {
168bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                        validPayload = false;
169bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    }
1704f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                    break;
1714f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                case FILL_ARRAY_DATA:
172bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    try {
173bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                        methodDef.findPayloadOffset(this.codeAddress + ((Instruction31t)instruction).getCodeOffset(),
174bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                                Opcode.ARRAY_PAYLOAD);
175bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    } catch (InvalidSwitchPayload ex) {
176bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                        validPayload = false;
177bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                    }
1784f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                    break;
1794f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                default:
1804f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                    throw new ExceptionWithContext("Invalid 31t opcode: %s", instruction.getOpcode());
1814f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            }
1824f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
183bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver            if (!validPayload) {
184bd6385f06205cdf98269eb4a2412000b35ac9d62Ben Gruver                writer.write("#invalid payload reference\n");
1854f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                commentOutInstruction = true;
1864f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            }
1874f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
1884f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
1894f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (opcode.odexOnly()) {
1904f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            if (!isAllowedOdex(opcode)) {
1914f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write("#disallowed odex opcode\n");
1924f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                commentOutInstruction = true;
1934f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            }
1944f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
1954f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
1964f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (commentOutInstruction) {
1974f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            writer.write("#");
1984f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
1994f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
200754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        switch (instruction.getOpcode().format) {
2016eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format10t:
2026eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2036eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2046eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeTargetLabel(writer);
2054f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2066eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format10x:
2072363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver                if (instruction instanceof UnknownInstruction) {
208a9ce1cf3ecff57b00c14bf86b2c688823c918a05Ben Gruver                    writer.write("#unknown opcode: 0x");
2092363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver                    writer.printUnsignedLongAsHex(((UnknownInstruction)instruction).getOriginalOpcode());
210a9ce1cf3ecff57b00c14bf86b2c688823c918a05Ben Gruver                    writer.write('\n');
2112363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver                }
2126eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2134f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2146eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format11n:
2156eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2166eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2176eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2186eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2196eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeLiteral(writer);
2204f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2216eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format11x:
2226eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2236eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2246eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2254f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2266eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format12x:
2276eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2286eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2296eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2306eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2316eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
2324f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
233db7795ffaa2d8804d84623a79d406f8c8686c1b8Ben Gruver            case Format20bc:
234bbe539f2d2cdfdd814fcdc0057dcdf454ae153d3Ben Gruver                writeOpcode(writer);
235bbe539f2d2cdfdd814fcdc0057dcdf454ae153d3Ben Gruver                writer.write(' ');
2364f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write(verificationErrorName);
237bbe539f2d2cdfdd814fcdc0057dcdf454ae153d3Ben Gruver                writer.write(", ");
2384f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write(referenceString);
2394f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2406eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format20t:
2416eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format30t:
2426eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2436eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2446eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeTargetLabel(writer);
2454f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2466eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format21c:
2476eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format31c:
2486eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2496eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2506eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2516eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2524f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write(referenceString);
2534f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
254754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver            case Format21ih:
255754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver            case Format21lh:
2566eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format21s:
2576eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format31i:
2586eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format51l:
2596eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2606eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2616eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2626eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2636eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeLiteral(writer);
26458d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                if (instruction.getOpcode().setsWideRegister()) {
2650b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith                    writeCommentIfLikelyDouble(writer);
26658d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                } else {
2670b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith                    boolean isResourceId = writeCommentIfResourceId(writer);
2680b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith                    if (!isResourceId) writeCommentIfLikelyFloat(writer);
26958d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                }
2704f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2716eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format21t:
2726eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format31t:
2736eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2746eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2756eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2766eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2776eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeTargetLabel(writer);
2784f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2796eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format22b:
2806eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format22s:
2816eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2826eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2836eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2846eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2856eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
2866eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2876eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeLiteral(writer);
2884f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
2896eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format22c:
2906eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
2916eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
2926eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
2936eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2946eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
2956eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
2964f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write(referenceString);
2974f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
298e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver            case Format22cs:
2996eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3006eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3016eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
3026eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3036eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
3046eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3056eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFieldOffset(writer);
3064f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3076eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format22t:
3086eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3096eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3106eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
3116eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3126eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
3136eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3146eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeTargetLabel(writer);
3154f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3166eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format22x:
3176eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format32x:
3186eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3196eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3206eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
3216eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3226eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
3234f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3246eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format23x:
3256eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3266eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3276eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeFirstRegister(writer);
3286eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3296eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeSecondRegister(writer);
3306eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3316eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeThirdRegister(writer);
3324f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3336eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format35c:
3346eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3356eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3366eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeInvokeRegisters(writer);
3376eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3384f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write(referenceString);
3394f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3402a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver            case Format35mi:
341b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writeOpcode(writer);
342b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writer.write(' ');
343b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writeInvokeRegisters(writer);
344b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writer.write(", ");
345b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writeInlineIndex(writer);
3464f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3476eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format35ms:
3486eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3496eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3506eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeInvokeRegisters(writer);
3516eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3526eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeVtableIndex(writer);
3534f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3546eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format3rc:
3556eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3566eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3576eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeInvokeRangeRegisters(writer);
3586eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3594f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                writer.write(referenceString);
3604f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
36161277b50b39015efe38c9cc5c79b31f6dd35c1f6Ben Gruver            case Format3rmi:
362b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writeOpcode(writer);
363b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writer.write(' ');
364b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writeInvokeRangeRegisters(writer);
365b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writer.write(", ");
366b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                writeInlineIndex(writer);
3674f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
3686eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            case Format3rms:
3696eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeOpcode(writer);
3706eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(' ');
3716eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeInvokeRangeRegisters(writer);
3726eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
3736eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeVtableIndex(writer);
3744f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                break;
375afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            case Format45cc:
376afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writeOpcode(writer);
377afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(' ');
378afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writeInvokeRegisters(writer);
379afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(", ");
380afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(referenceString);
381afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(", ");
382afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(referenceString2);
383afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                break;
384afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath            case Format4rcc:
385afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writeOpcode(writer);
386afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(' ');
387afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writeInvokeRangeRegisters(writer);
388afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(", ");
389afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(referenceString);
390afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(", ");
391afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                writer.write(referenceString2);
392afc1f1593936326e1c99f8328bbce8b495865000Narayan Kamath                break;
3934f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            default:
3944f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                assert false;
3954f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver                return false;
3964f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        }
3974f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
3984f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        if (commentOutInstruction) {
3994f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver            writer.write("\nnop");
4000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
4014f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver
4024f2620415d505a35d2d14b866cde10a54b1b7c8cBen Gruver        return true;
403b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
404b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4050b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeOpcode(IndentingWriter writer) throws IOException {
406754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        writer.write(instruction.getOpcode().name);
407b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
408b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4090b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeTargetLabel(IndentingWriter writer) throws IOException {
410db7795ffaa2d8804d84623a79d406f8c8686c1b8Ben Gruver        //this method is overridden by OffsetInstructionMethodItem, and should only be called for the formats that
4116eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        //have a target
4126eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        throw new RuntimeException();
4136eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com    }
414b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4150b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeRegister(IndentingWriter writer, int registerNumber) throws IOException {
416754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        methodDef.registerFormatter.writeTo(writer, registerNumber);
417b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
418b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4190b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeFirstRegister(IndentingWriter writer) throws IOException {
420754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        writeRegister(writer, ((OneRegisterInstruction)instruction).getRegisterA());
4216eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com    }
422b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4230b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeSecondRegister(IndentingWriter writer) throws IOException {
4246eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        writeRegister(writer, ((TwoRegisterInstruction)instruction).getRegisterB());
425b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
426b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4270b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeThirdRegister(IndentingWriter writer) throws IOException {
428754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        writeRegister(writer, ((ThreeRegisterInstruction) instruction).getRegisterC());
429b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
430b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4310b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeInvokeRegisters(IndentingWriter writer) throws IOException {
4326eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        FiveRegisterInstruction instruction = (FiveRegisterInstruction)this.instruction;
433754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        final int regCount = instruction.getRegisterCount();
4346eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com
4356eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        writer.write('{');
4366eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        switch (regCount) {
437b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com            case 1:
438754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writeRegister(writer, instruction.getRegisterC());
4396eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                break;
440b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com            case 2:
441754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writeRegister(writer, instruction.getRegisterC());
4426eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
443754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writeRegister(writer, instruction.getRegisterD());
4446eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                break;
445b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com            case 3:
446754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writeRegister(writer, instruction.getRegisterC());
447754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writer.write(", ");
4486eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterD());
4496eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
4506eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterE());
4516eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                break;
452b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com            case 4:
453754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writeRegister(writer, instruction.getRegisterC());
454754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writer.write(", ");
4556eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterD());
4566eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
4576eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterE());
4586eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
4596eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterF());
4606eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                break;
461b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com            case 5:
462754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writeRegister(writer, instruction.getRegisterC());
463754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver                writer.write(", ");
4646eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterD());
4656eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
4666eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterE());
4676eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
4686eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterF());
4696eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writer.write(", ");
4706eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                writeRegister(writer, instruction.getRegisterG());
4716eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com                break;
472b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com        }
4736eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        writer.write('}');
474b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
475b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4760b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeInvokeRangeRegisters(IndentingWriter writer) throws IOException {
4776eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        RegisterRangeInstruction instruction = (RegisterRangeInstruction)this.instruction;
4786eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com
479754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        int regCount = instruction.getRegisterCount();
4806eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        if (regCount == 0) {
4816eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            writer.write("{}");
4826eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        } else {
4836eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com            int startRegister = instruction.getStartRegister();
484754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver            methodDef.registerFormatter.writeRegisterRange(writer, startRegister, startRegister+regCount-1);
4856eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        }
4866eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com    }
487b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4880b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeLiteral(IndentingWriter writer) throws IOException {
489754b3c4dc009b7a02e39001560c3f0fd6a7cc2c0Ben Gruver        LongRenderer.writeSignedIntOrLongTo(writer, ((WideLiteralInstruction)instruction).getWideLiteral());
490b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
491b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com
4920b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith    protected void writeCommentIfLikelyFloat(IndentingWriter writer) throws IOException {
4930b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith        writeCommentIfLikelyFloat(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());
49458d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith    }
49558d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith
4960b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith    protected void writeCommentIfLikelyFloat(IndentingWriter writer, int val) throws IOException {
49758d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith        if (NumberUtils.isLikelyFloat(val)) {
49858d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            writer.write("    # ");
49958d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            float fval = Float.intBitsToFloat(val);
50058d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            if (fval == Float.POSITIVE_INFINITY)
50158d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Float.POSITIVE_INFINITY");
50258d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (fval == Float.NEGATIVE_INFINITY)
50358d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Float.NEGATIVE_INFINITY");
504681222d39137afb0bcfa88e17fc3a5fbdfe7a4c3Andreas Gampe            else if (Float.isNaN(fval))
50558d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Float.NaN");
50658d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (fval == Float.MAX_VALUE)
50758d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Float.MAX_VALUE");
50858d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (fval == (float)Math.PI)
50958d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("(float)Math.PI");
51058d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (fval == (float)Math.E)
51158d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("(float)Math.E");
51258d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else {
51358d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write(Float.toString(fval));
51458d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write('f');
51558d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            }
51658d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith        }
51758d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith    }
51858d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith
5190b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith    protected void writeCommentIfLikelyDouble(IndentingWriter writer) throws IOException {
5200b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith        writeCommentIfLikelyDouble(writer, ((WideLiteralInstruction)instruction).getWideLiteral());
521eb0b009971653400809fa43c51d2ce99cb5c52b9Jeff Smith    }
522eb0b009971653400809fa43c51d2ce99cb5c52b9Jeff Smith
5230b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith    protected void writeCommentIfLikelyDouble(IndentingWriter writer, long val) throws IOException {
52458d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith        if (NumberUtils.isLikelyDouble(val)) {
52558d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            writer.write("    # ");
52658d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            double dval = Double.longBitsToDouble(val);
52758d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            if (dval == Double.POSITIVE_INFINITY)
52858d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Double.POSITIVE_INFINITY");
52958d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (dval == Double.NEGATIVE_INFINITY)
53058d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Double.NEGATIVE_INFINITY");
531681222d39137afb0bcfa88e17fc3a5fbdfe7a4c3Andreas Gampe            else if (Double.isNaN(dval))
53258d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Double.NaN");
53358d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (dval == Double.MAX_VALUE)
53458d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Double.MAX_VALUE");
53558d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (dval == Math.PI)
53658d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Math.PI");
53758d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else if (dval == Math.E)
53858d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write("Math.E");
53958d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith            else
54058d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith                writer.write(Double.toString(dval));
54158d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith        }
54258d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith    }
54358d2efb8e51db3f5cec63256030db3d3f98789e7Jeff Smith
5440b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith    protected boolean writeCommentIfResourceId(IndentingWriter writer) throws IOException {
5450b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith        return writeCommentIfResourceId(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());
546eb0b009971653400809fa43c51d2ce99cb5c52b9Jeff Smith    }
547eb0b009971653400809fa43c51d2ce99cb5c52b9Jeff Smith
5480b836342e21b4de21d1d452d5b43b54a364a35c6Jeff Smith    protected boolean writeCommentIfResourceId(IndentingWriter writer, int val) throws IOException {
549eb0b009971653400809fa43c51d2ce99cb5c52b9Jeff Smith        Map<Integer,String> resourceIds = methodDef.classDef.options.resourceIds;
55020b7bbf63e7c689316b8fbc28ecd1212ab4fe6b9Jeff Smith        String resource = resourceIds.get(Integer.valueOf(val));
55120b7bbf63e7c689316b8fbc28ecd1212ab4fe6b9Jeff Smith        if (resource != null) {
5527e9231a211bf00451229d88edb5c7fbd5085f73eJeff Smith            writer.write("    # ");
55320b7bbf63e7c689316b8fbc28ecd1212ab4fe6b9Jeff Smith            writer.write(resource);
5549cc35b2d05c6d97cc753b9cc956ea93a8b176c19Jeff Smith            return true;
5557e9231a211bf00451229d88edb5c7fbd5085f73eJeff Smith        }
5569cc35b2d05c6d97cc753b9cc956ea93a8b176c19Jeff Smith        return false;
5577e9231a211bf00451229d88edb5c7fbd5085f73eJeff Smith    }
558e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver
559e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver    protected void writeFieldOffset(IndentingWriter writer) throws IOException {
5606eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        writer.write("field@0x");
561e88723c666db87d414e126ac6d94d683d86ad28dBen Gruver        writer.printUnsignedLongAsHex(((FieldOffsetInstruction)instruction).getFieldOffset());
562b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com    }
5630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
564b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver    protected void writeInlineIndex(IndentingWriter writer) throws IOException {
5652a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver        writer.write("inline@");
5662a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver        writer.printSignedIntAsDec(((InlineIndexInstruction)instruction).getInlineIndex());
5672a91d72a1534dd8171d8296ce8312de4bd603451Ben Gruver    }
568b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver
5690b2f7d6a57e90424b3ee455c041aab3996c05f2cJesusFreke@JesusFreke.com    protected void writeVtableIndex(IndentingWriter writer) throws IOException {
5708a151ae671f6d5c99d55779005580834b49187f0Ben Gruver        writer.write("vtable@");
5718a151ae671f6d5c99d55779005580834b49187f0Ben Gruver        writer.printSignedIntAsDec(((VtableIndexInstruction)instruction).getVtableIndex());
5728a151ae671f6d5c99d55779005580834b49187f0Ben Gruver    }
573b2e1e2067d5179b0ec38c76a5191909f5a7dc1ccJesusFreke@JesusFreke.com}
574