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.rop.code; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstUtf8; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ToHuman; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combination of a register number and a type, used as the sources and 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destinations of register-based operations. 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class RegisterSpec 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project implements TypeBearer, ToHuman, Comparable<RegisterSpec> { 3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} string to prefix register numbers with */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final String PREFIX = "v"; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} intern table for instances */ 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final HashMap<Object, RegisterSpec> theInterns = 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new HashMap<Object, RegisterSpec>(1000); 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} common comparison instance used while interning */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final ForComparison theInterningItem = new ForComparison(); 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} register number */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int reg; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} type loaded or stored */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final TypeBearer type; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} local variable info associated with this register, if any */ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final LocalItem local; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Intern the given triple as an instance of this class. 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} the type (or possibly actual value) which 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is loaded from or stored to the indicated register 5899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} the associated local variable, if any 5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static RegisterSpec intern(int reg, TypeBearer type, 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalItem local) { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project theInterningItem.set(reg, type, local); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec found = theInterns.get(theInterningItem); 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (found != null) { 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return found; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project found = theInterningItem.toRegisterSpec(); 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project theInterns.put(found, found); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return found; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance for the given register number and type, with 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * no variable info. This method is allowed to return shared 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instances (but doesn't necessarily do so). 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} the type (or possibly actual value) which 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is loaded from or stored to the indicated register 8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static RegisterSpec make(int reg, TypeBearer type) { 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return intern(reg, type, null); 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance for the given register number, type, and 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * variable info. This method is allowed to return shared 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instances (but doesn't necessarily do so). 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} the type (or possibly actual value) which 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is loaded from or stored to the indicated register 9799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code non-null;} the associated local variable 9899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static RegisterSpec make(int reg, TypeBearer type, 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalItem local) { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (local == null) { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("local == null"); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return intern(reg, type, local); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance for the given register number, type, and 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * variable info. This method is allowed to return shared 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instances (but doesn't necessarily do so). 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 11599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} the type (or possibly actual value) which 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is loaded from or stored to the indicated register 11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} the associated variable info or null for 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * none 11999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static RegisterSpec makeLocalOptional( 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg, TypeBearer type, LocalItem local) { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return intern(reg, type, local); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the string form for the given register number. 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static String regString(int reg) { 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return PREFIX + reg; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. This constructor is private. Use 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #make}. 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 14199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 14299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} the type (or possibly actual value) which 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is loaded from or stored to the indicated register 14499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} the associated local variable, if any 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private RegisterSpec(int reg, TypeBearer type, LocalItem local) { 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reg < 0) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("reg < 0"); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type == null) { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("type == null"); 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.reg = reg; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.type = type; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.local = local; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object other) { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(other instanceof RegisterSpec)) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (other instanceof ForComparison) { 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ForComparison fc = (ForComparison) other; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return equals(fc.reg, fc.type, fc.local); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = (RegisterSpec) other; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return equals(spec.reg, spec.type, spec.local); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Like {@code equals}, but only consider the simple types of the 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registers. That is, this compares {@code getType()} on the types 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to ignore whatever arbitrary extra stuff might be carried around 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by an outer {@link TypeBearer}. 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param other {@code null-ok;} spec to compare to 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return {@code true} iff {@code this} and {@code other} are equal 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the stated way 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equalsUsingSimpleType(RegisterSpec other) { 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!matchesVariable(other)) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (reg == other.reg); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Like {@link #equalsUsingSimpleType} but ignoring the register number. 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is useful to determine if two instances refer to the "same" 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * local variable. 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 19899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param other {@code null-ok;} spec to compare to 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return {@code true} iff {@code this} and {@code other} are equal 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the stated way 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean matchesVariable(RegisterSpec other) { 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (other == null) { 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getType().equals(other.type.getType()) 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && ((local == other.local) 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || ((local != null) && local.equals(other.local))); 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #equals} and {@link #ForComparison.equals}, 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which actually does the test. 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg value of the instance variable, for another instance 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param type value of the instance variable, for another instance 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param local value of the instance variable, for another instance 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return whether this instance is equal to one with the given 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * values 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean equals(int reg, TypeBearer type, LocalItem local) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (this.reg == reg) 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && this.type.equals(type) 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && ((this.local == local) 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || ((this.local != null) && this.local.equals(local))); 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compares by (in priority order) register number, unwrapped type 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (that is types not {@link TypeBearer}s, and local info. 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 23399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param other {@code non-null;} spec to compare to 23499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code -1..1;} standard result of comparison 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int compareTo(RegisterSpec other) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (this.reg < other.reg) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (this.reg > other.reg) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int compare = type.getType().compareTo(other.type.getType()); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (compare != 0) { 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return compare; 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (this.local == null) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (other.local == null) ? 0 : -1; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (other.local == null) { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this.local.compareTo(other.local); 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hashCodeOf(reg, type, local); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #hashCode} and {@link #ForComparison.hashCode}, 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which actually does the calculation. 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg value of the instance variable 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param type value of the instance variable 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param local value of the instance variable 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the hash code 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static int hashCodeOf(int reg, TypeBearer type, LocalItem local) { 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hash = (local != null) ? local.hashCode() : 0; 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hash = (hash * 31 + type.hashCode()) * 31 + reg; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hash; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toString0(false); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toString0(true); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Type getType() { 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getType(); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeBearer getFrameType() { 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getFrameType(); 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final int getBasicType() { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getBasicType(); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final int getBasicFrameType() { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getBasicFrameType(); 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final boolean isConstant() { 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the register number. 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 31999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the register number 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getReg() { 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return reg; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the type (or actual value) which is loaded from or stored 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the register associated with this instance. 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 32999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the type 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeBearer getTypeBearer() { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the variable info associated with this instance, if any. 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 33899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the variable info, or {@code null} if this 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance has none 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public LocalItem getLocalItem() { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return local; 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the next available register number after the one in this 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. This is equal to the register number plus the width 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (category) of the type used. Among other things, this may also 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be used to determine the minimum required register count 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * implied by this instance. 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 35299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the required registers size 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getNextReg() { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return reg + getCategory(); 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the category of this instance's type. This is just a convenient 36099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * shorthand for {@code getType().getCategory()}. 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #isCategory1 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #isCategory2 36499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code 1..2;} the category of this instance's type 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getCategory() { 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getType().getCategory(); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether this instance's type is category 1. This is just a 37299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * convenient shorthand for {@code getType().isCategory1()}. 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #getCategory 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #isCategory2 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return whether or not this instance's type is of category 1 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isCategory1() { 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getType().isCategory1(); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether this instance's type is category 2. This is just a 38499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * convenient shorthand for {@code getType().isCategory2()}. 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #getCategory 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #isCategory1 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return whether or not this instance's type is of category 2 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isCategory2() { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.getType().isCategory2(); 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the string form for just the register number of this instance. 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 39799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the register string form 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String regString() { 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return regString(reg); 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is the intersection between this instance 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and the given one, if any. The intersection is defined as follows: 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <ul> 40899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * <li>If {@code other} is {@code null}, then the result 40999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * is {@code null}. 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li>If the register numbers don't match, then the intersection 41199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * is {@code null}. Otherwise, the register number of the 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * intersection is the same as the one in the two instances.</li> 41399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * <li>If the types returned by {@code getType()} are not 41499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code equals()}, then the intersection is null.</li> 41599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * <li>If the type bearers returned by {@code getTypeBearer()} 41699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * are {@code equals()}, then the intersection's type bearer 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is the one from this instance. Otherwise, the intersection's 41899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * type bearer is the {@code getType()} of this instance.</li> 41999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * <li>If the locals are {@code equals()}, then the local info 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the intersection is the local info of this instance. Otherwise, 42199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the local info of the intersection is {@code null}.</li> 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </ul> 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 42499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param other {@code null-ok;} instance to intersect with (or {@code null}) 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param localPrimary whether local variables are primary to the 42699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * intersection; if {@code true}, then the only non-null 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * results occur when registers being intersected have equal local 42899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * infos (or both have {@code null} local infos) 42999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the intersection 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec intersect(RegisterSpec other, boolean localPrimary) { 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (this == other) { 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Easy out. 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((other == null) || (reg != other.getReg())) { 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalItem resultLocal = 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((local == null) || !local.equals(other.getLocalItem())) 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ? null : local; 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean sameName = (resultLocal == local); 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (localPrimary && !sameName) { 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type thisType = getType(); 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type otherType = other.getType(); 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Note: Types are always interned. 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (thisType != otherType) { 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer resultTypeBearer = 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type.equals(other.getTypeBearer()) ? type : thisType; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((resultTypeBearer == type) && sameName) { 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // It turns out that the intersection is "this" after all. 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (resultLocal == null) ? make(reg, resultTypeBearer) : 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project make(reg, resultTypeBearer, resultLocal); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that the 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register number is replaced by the given one. 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 47499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param newReg {@code >= 0;} the new register number 47599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec withReg(int newReg) { 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reg == newReg) { 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return makeLocalOptional(newReg, type, local); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the type is replaced by the given one. 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 48999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param newType {@code non-null;} the new type 49099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec withType(TypeBearer newType) { 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return makeLocalOptional(reg, newType, local); 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that the 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register number is offset by the given amount. 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param delta the amount to offset the register number by 50199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec withOffset(int delta) { 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (delta == 0) { 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return withReg(reg + delta); 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the type bearer is replaced by the actual underlying type 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (thereby stripping off non-type information) with any 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialization information stripped away as well. 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 51799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec withSimpleType() { 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer orig = type; 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type newType; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (orig instanceof Type) { 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newType = (Type) orig; 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newType = orig.getType(); 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newType.isUninitialized()) { 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newType = newType.getInitializedType(); 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newType == orig) { 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return makeLocalOptional(reg, newType, local); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one except that the 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * local variable is as specified in the parameter. 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 54499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} the local item or null for none 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return an appropriate instance 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec withLocalItem(LocalItem local) { 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((this.local== local) 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || ((this.local != null) && this.local.equals(local))) { 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return makeLocalOptional(reg, type, local); 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #toString} and {@link #toHuman}. 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param human whether to be human-oriented 56299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String toString0(boolean human) { 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(40); 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(regString()); 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(":"); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (local != null) { 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(local.toString()); 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type justType = type.getType(); 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(justType); 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (justType != type) { 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("="); 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (human && (type instanceof Constant)) { 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(((Constant) type).toHuman()); 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(type); 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Holder of register spec data for the purposes of comparison (so that 59199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code RegisterSpec} itself can still keep {@code final} 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance variables. 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class ForComparison { 59599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} register number */ 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int reg; 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} type loaded or stored */ 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private TypeBearer type; 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60155423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein /** 60255423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein * {@code null-ok;} local variable associated with this 60355423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein * register, if any 60455423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein */ 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private LocalItem local; 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set all the instance variables. 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 61099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the register number 61155423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein * @param type {@code non-null;} the type (or possibly actual 61255423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein * value) which is loaded from or stored to the indicated 61355423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein * register 61499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} the associated local variable, if any 61599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void set(int reg, TypeBearer type, LocalItem local) { 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.reg = reg; 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.type = type; 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.local = local; 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 62499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Construct a {@code RegisterSpec} of this instance's 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contents. 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 62799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec toRegisterSpec() { 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new RegisterSpec(reg, type, local); 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object other) { 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(other instanceof RegisterSpec)) { 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = (RegisterSpec) other; 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return spec.equals(reg, type, local); 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() { 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hashCodeOf(reg, type, local); 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 651