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