1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.code; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Representation of an opcode. 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class Dop { 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** DalvOps.MIN_VALUE..DalvOps.MAX_VALUE; the opcode value itself */ 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int opcode; 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** DalvOps.MIN_VALUE..DalvOps.MAX_VALUE; the opcode family */ 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int family; 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} the instruction format */ 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final InsnFormat format; 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** whether this opcode uses a result register */ 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final boolean hasResult; 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} the name */ 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final String name; 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param opcode {@code DalvOps.MIN_VALUE..DalvOps.MAX_VALUE;} the opcode 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * value itself 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param family {@code DalvOps.MIN_VALUE..DalvOps.MAX_VALUE;} the opcode family 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param format {@code non-null;} the instruction format 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param hasResult whether the opcode has a result register; if so it 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * is always the first register 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param name {@code non-null;} the name 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Dop(int opcode, int family, InsnFormat format, 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul boolean hasResult, String name) { 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((opcode < DalvOps.MIN_VALUE) || (opcode > DalvOps.MAX_VALUE)) { 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bogus opcode"); 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((family < DalvOps.MIN_VALUE) || (family > DalvOps.MAX_VALUE)) { 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bogus family"); 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (format == null) { 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("format == null"); 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (name == null) { 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("name == null"); 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.opcode = opcode; 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.family = family; 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.format = format; 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.hasResult = hasResult; 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.name = name; 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String toString() { 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return name; 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the opcode value. 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code DalvOps.MIN_VALUE..DalvOps.MAX_VALUE;} the opcode value 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getOpcode() { 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return opcode; 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the opcode family. The opcode family is the unmarked (no 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * "/...") opcode that has equivalent semantics to this one. 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code DalvOps.MIN_VALUE..DalvOps.MAX_VALUE;} the opcode family 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getFamily() { 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return family; 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the instruction format. 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the instruction format 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public InsnFormat getFormat() { 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return format; 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns whether this opcode uses a result register. 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code true} iff this opcode uses a result register 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean hasResult() { 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return hasResult; 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the opcode name. 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the opcode name 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String getName() { 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return name; 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the opcode for the opposite test of this instance. This is only 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * valid for opcodes which are in fact tests. 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the opposite test 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Dop getOppositeTest() { 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul switch (opcode) { 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_EQ: return Dops.IF_NE; 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_NE: return Dops.IF_EQ; 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_LT: return Dops.IF_GE; 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_GE: return Dops.IF_LT; 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_GT: return Dops.IF_LE; 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_LE: return Dops.IF_GT; 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_EQZ: return Dops.IF_NEZ; 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_NEZ: return Dops.IF_EQZ; 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_LTZ: return Dops.IF_GEZ; 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_GEZ: return Dops.IF_LTZ; 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_GTZ: return Dops.IF_LEZ; 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul case DalvOps.IF_LEZ: return Dops.IF_GTZ; 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("bogus opcode: " + this); 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 151