1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.code; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornsteinimport com.android.dx.io.OpcodeInfo; 207ba91291bb6ce64691398a8751656207e8e3e98dDan Bornsteinimport com.android.dx.io.Opcodes; 217ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Representation of an opcode. 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Dop { 267ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein /** {@code Opcodes.isValid();} the opcode value itself */ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int opcode; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 297ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein /** {@code Opcodes.isValid();} the opcode family */ 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int family; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein /** 337ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * {@code Opcodes.isValid();} what opcode (by number) to try next 3425f7980a51488db2ebcd7822c83c3f4b25a2a730Dan Bornstein * when attempting to match an opcode to particular arguments; 357ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * {@code Opcodes.NO_NEXT} to indicate that this is the last 3625f7980a51488db2ebcd7822c83c3f4b25a2a730Dan Bornstein * opcode to try in a particular chain 37ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein */ 38ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein private final int nextOpcode; 39ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein 4099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the instruction format */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final InsnFormat format; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** whether this opcode uses a result register */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean hasResult; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 48de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 497ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * @param opcode {@code Opcodes.isValid();} the opcode value 5025f7980a51488db2ebcd7822c83c3f4b25a2a730Dan Bornstein * itself 517ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * @param family {@code Opcodes.isValid();} the opcode family 527ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * @param nextOpcode {@code Opcodes.isValid();} what opcode (by 5325f7980a51488db2ebcd7822c83c3f4b25a2a730Dan Bornstein * number) to try next when attempting to match an opcode to 547ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * particular arguments; {@code Opcodes.NO_NEXT} to indicate that 5525f7980a51488db2ebcd7822c83c3f4b25a2a730Dan Bornstein * this is the last opcode to try in a particular chain 5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param format {@code non-null;} the instruction format 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hasResult whether the opcode has a result register; if so it 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is always the first register 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 60ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein public Dop(int opcode, int family, int nextOpcode, InsnFormat format, 61a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein boolean hasResult) { 627ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein if (!Opcodes.isValidShape(opcode)) { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus opcode"); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 667ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein if (!Opcodes.isValidShape(family)) { 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus family"); 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 707ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein if (!Opcodes.isValidShape(nextOpcode)) { 71ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein throw new IllegalArgumentException("bogus nextOpcode"); 72ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein } 73ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (format == null) { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("format == null"); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.opcode = opcode; 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.family = family; 80ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein this.nextOpcode = nextOpcode; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.format = format; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.hasResult = hasResult; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 88a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein return getName(); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the opcode value. 93de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 947ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode value 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getOpcode() { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return opcode; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the opcode family. The opcode family is the unmarked (no 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "/...") opcode that has equivalent semantics to this one. 103de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 1047ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode family 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getFamily() { 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return family; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the instruction format. 112de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 11399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the instruction format 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public InsnFormat getFormat() { 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return format; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether this opcode uses a result register. 121de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff this opcode uses a result register 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean hasResult() { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hasResult; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the opcode name. 130de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the opcode name 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String getName() { 134a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein return OpcodeInfo.getName(opcode); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 138ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein * Gets the opcode value to try next when attempting to match an 139ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein * opcode to particular arguments. This returns {@code 1407ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * Opcodes.NO_NEXT} to indicate that this is the last opcode to 141ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein * try in a particular chain. 142ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein * 1437ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein * @return {@code Opcodes.MIN_VALUE..Opcodes.MAX_VALUE;} the opcode value 144ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein */ 145ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein public int getNextOpcode() { 146ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein return nextOpcode; 147ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein } 148ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein 149ec85aa98842a86cb68664de8149f8ff495babe79Dan Bornstein /** 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the opcode for the opposite test of this instance. This is only 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * valid for opcodes which are in fact tests. 152de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the opposite test 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Dop getOppositeTest() { 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opcode) { 1577ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_EQ: return Dops.IF_NE; 1587ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_NE: return Dops.IF_EQ; 1597ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_LT: return Dops.IF_GE; 1607ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_GE: return Dops.IF_LT; 1617ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_GT: return Dops.IF_LE; 1627ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_LE: return Dops.IF_GT; 1637ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_EQZ: return Dops.IF_NEZ; 1647ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_NEZ: return Dops.IF_EQZ; 1657ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_LTZ: return Dops.IF_GEZ; 1667ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_GEZ: return Dops.IF_LTZ; 1677ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_GTZ: return Dops.IF_LEZ; 1687ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein case Opcodes.IF_LEZ: return Dops.IF_GTZ; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus opcode: " + this); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 174