Form21c.java revision 579d7739c53a2707ad711a2d2cae46d7d782f061
1fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/*
2fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * Copyright (C) 2007 The Android Open Source Project
3fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek *
4fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * Licensed under the Apache License, Version 2.0 (the "License");
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * you may not use this file except in compliance with the License.
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner * You may obtain a copy of the License at
7fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek *
8fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek *      http://www.apache.org/licenses/LICENSE-2.0
9fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek *
10fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * Unless required by applicable law or agreed to in writing, software
11fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * distributed under the License is distributed on an "AS IS" BASIS,
12fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * See the License for the specific language governing permissions and
14fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek * limitations under the License.
15cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek */
16cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek
17cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenekpackage com.android.dx.dex.code.form;
18852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
197dba8607e59096014b7139ff20ef00870041d518Ted Kremenekimport com.android.dx.dex.code.CstInsn;
20ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenekimport com.android.dx.dex.code.DalvInsn;
21852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekimport com.android.dx.dex.code.InsnFormat;
22ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenekimport com.android.dx.rop.code.RegisterSpec;
23c1581a0d64b0ee4f822ed2fca4442a111d03569aHartmut Kaiserimport com.android.dx.rop.code.RegisterSpecList;
24fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekimport com.android.dx.rop.cst.Constant;
25e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerimport com.android.dx.rop.cst.CstFieldRef;
26e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerimport com.android.dx.rop.cst.CstString;
27e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnerimport com.android.dx.rop.cst.CstType;
28fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekimport com.android.dx.util.AnnotatedOutput;
2942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
3063f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenekimport java.util.BitSet;
3142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
3242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/**
33e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner * Instruction format {@code 21c}. See the instruction format spec
34e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump * for details.
35e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump */
36852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekpublic final class Form21c extends InsnFormat {
37852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    /** {@code non-null;} unique instance of this class */
38852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    public static final InsnFormat THE_ONE = new Form21c();
39852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
40852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    /**
41852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek     * Constructs an instance. This class is not publicly
42852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek     * instantiable. Use {@link #THE_ONE}.
43852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek     */
44852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    private Form21c() {
45852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek        // This space intentionally left blank.
46852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    }
47fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
48fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    /** {@inheritDoc} */
49fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    @Override
50fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    public String insnArgString(DalvInsn insn) {
51fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        RegisterSpecList regs = insn.getRegisters();
52fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        return regs.get(0).regString() + ", " + cstString(insn);
53fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
54fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
55fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    /** {@inheritDoc} */
56fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    @Override
57fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    public String insnCommentString(DalvInsn insn, boolean noteIndices) {
58fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        if (noteIndices) {
59fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            return cstComment(insn);
60fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        } else {
61fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            return "";
62fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        }
63fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
64fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
65fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    /** {@inheritDoc} */
66fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    @Override
67fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    public int codeSize() {
689cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek        return 2;
699cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek    }
70fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
71fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    /** {@inheritDoc} */
726c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    @Override
73852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek    public boolean isCompatible(DalvInsn insn) {
746c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        if (!(insn instanceof CstInsn)) {
756c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek            return false;
76ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek        }
77ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek
786c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        RegisterSpecList regs = insn.getRegisters();
796c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        RegisterSpec reg;
806c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
816c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        switch (regs.size()) {
826c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek            case 1: {
83852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                reg = regs.get(0);
84852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                break;
85852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek            }
866c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek            case 2: {
876c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                /*
886c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                 * This format is allowed for ops that are effectively
896c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                 * 2-arg but where the two args are identical.
906c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                 */
916c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                reg = regs.get(0);
926c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                if (reg.getReg() != regs.get(1).getReg()) {
936c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                    return false;
946c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                }
956c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                break;
96852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek            }
976c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek            default: {
986c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek                return false;
996c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek            }
1006c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        }
1016c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
1026c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        if (!unsignedFitsInByte(reg.getReg())) {
1036c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek            return false;
1046c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        }
105fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
1066c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        CstInsn ci = (CstInsn) insn;
1079cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek        int cpi = ci.getIndex();
1089cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek        Constant cst = ci.getConstant();
1099cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek
1109cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek        if (! unsignedFitsInShort(cpi)) {
1113575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek            return false;
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
1139cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek
114fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        return (cst instanceof CstType) ||
115fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            (cst instanceof CstFieldRef) ||
1163575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek            (cst instanceof CstString);
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1183575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek
1193575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    /** {@inheritDoc} */
1203575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    @Override
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    public BitSet compatibleRegs(DalvInsn insn) {
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        RegisterSpecList regs = insn.getRegisters();
123fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        int sz = regs.size();
124fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        BitSet bits = new BitSet(sz);
125fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        boolean compat = unsignedFitsInByte(regs.get(0).getReg());
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
127fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek        if (sz == 1) {
128fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            bits.set(0, compat);
129ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek        } else {
130fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            if (regs.get(0).getReg() == regs.get(1).getReg()) {
131fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek                bits.set(0, compat);
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                bits.set(1, compat);
133fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek            }
134ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek        }
135ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek
136ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek        return bits;
1377177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar    }
138fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
139fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    /** {@inheritDoc} */
1406c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    @Override
1416c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    public void writeTo(AnnotatedOutput out, DalvInsn insn) {
1426c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        RegisterSpecList regs = insn.getRegisters();
1436c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek        int cpi = ((CstInsn) insn).getIndex();
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
145852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek        write(out,
146852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek              opcodeUnit(insn, regs.get(0).getReg()),
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              (short) cpi);
148fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
149fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
150fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek