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.util.MutabilityControl; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set of {@link RegisterSpec} instances, where a given register number 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * may appear only once in the set. 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class RegisterSpecSet 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extends MutabilityControl { 2799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} no-element instance */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final RegisterSpecSet EMPTY = new RegisterSpecSet(0); 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 3199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} array of register specs, where each element is 3299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null} or is an instance whose {@code reg} 33de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * matches the array index 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final RegisterSpec[] specs; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= -1;} size of the set or {@code -1} if not yet calculated */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int size; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. The instance is initially empty. 42de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param maxSize {@code >= 0;} the maximum register number (exclusive) that 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * may be represented in this instance 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecSet(int maxSize) { 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(maxSize != 0); 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.specs = new RegisterSpec[maxSize]; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.size = 0; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean equals(Object other) { 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(other instanceof RegisterSpecSet)) { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecSet otherSet = (RegisterSpecSet) other; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec[] otherSpecs = otherSet.specs; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = specs.length; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((len != otherSpecs.length) || (size() != otherSet.size())) { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec s1 = specs[i]; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec s2 = otherSpecs[i]; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (s1 == s2) { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((s1 == null) || !s1.equals(s2)) { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int hashCode() { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = specs.length; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hash = 0; 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = specs[i]; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int oneHash = (spec == null) ? 0 : spec.hashCode(); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hash = (hash * 31) + oneHash; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hash; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = specs.length; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(len * 25); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('{'); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean any = false; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = specs[i]; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec != null) { 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (any) { 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(", "); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project any = true; 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(spec); 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('}'); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 122de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the maximum number of registers that may be in this instance, which 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is also the maximum-plus-one of register numbers that may be 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * represented. 128de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the maximum size 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMaxSize() { 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return specs.length; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the current size of this instance. 137de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 13899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the size 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int size() { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = size; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result < 0) { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = specs.length; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (specs[i] != null) { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result++; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = result; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the element with the given register number, if any. 161de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 16299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param reg {@code >= 0;} the desired register number 16399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the element with the given register number or 16499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null} if there is none 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec get(int reg) { 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return specs[reg]; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ArrayIndexOutOfBoundsException ex) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Translate the exception. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus reg"); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the element with the same register number as the given 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * spec, if any. This is just a convenient shorthand for 17899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code get(spec.getReg())}. 179de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec {@code non-null;} spec with the desired register number 18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the element with the matching register number or 18299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null} if there is none 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec get(RegisterSpec spec) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return get(spec.getReg()); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the spec in this set that's currently associated with a 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given local (type, name, and signature), or {@code null} if there is 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * none. This ignores the register number of the given spec but 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * matches on everything else. 193de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 19499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec {@code non-null;} local to look for 19599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} first register found that matches, if any 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec findMatchingLocal(RegisterSpec spec) { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length = specs.length; 199de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int reg = 0; reg < length; reg++) { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec s = specs[reg]; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (s == null) { 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec.matchesVariable(s)) { 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return s; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the spec in this set that's currently associated with a given 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * local (name and signature), or {@code null} if there is none. 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 21999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code non-null;} local item to search for 22099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} first register found with matching name and signature 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec localItemToSpec(LocalItem local) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length = specs.length; 224de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int reg = 0; reg < length; reg++) { 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = specs[reg]; 227de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((spec != null) && local.equals(spec.getLocalItem())) { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return spec; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Removes a spec from the set. Only the register number 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the parameter is significant. 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 24099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param toRemove {@code non-null;} register to remove. 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void remove(RegisterSpec toRemove) { 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project specs[toRemove.getReg()] = null; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = -1; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ArrayIndexOutOfBoundsException ex) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Translate the exception. 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus reg"); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Puts the given spec into the set. If there is already an element in 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the set with the same register number, it is replaced. Additionally, 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the previous element is for a category-2 register, then that 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * previous element is nullified. Finally, if the given spec is for 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a category-2 register, then the immediately subsequent element 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is nullified. 259de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 26099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec {@code non-null;} the register spec to put in the instance 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void put(RegisterSpec spec) { 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec == null) { 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("spec == null"); 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = -1; 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg = spec.getReg(); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project specs[reg] = spec; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reg > 0) { 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int prevReg = reg - 1; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec prevSpec = specs[prevReg]; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((prevSpec != null) && (prevSpec.getCategory() == 2)) { 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project specs[prevReg] = null; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec.getCategory() == 2) { 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project specs[reg + 1] = null; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ArrayIndexOutOfBoundsException ex) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Translate the exception. 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("spec.getReg() out of range"); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Put the entire contents of the given set into this one. 294de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 29599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param set {@code non-null;} the set to put into this instance 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void putAll(RegisterSpecSet set) { 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int max = set.getMaxSize(); 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < max; i++) { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = set.get(i); 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec != null) { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project put(spec); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Intersects this instance with the given one, modifying this 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. The intersection consists of the pairwise 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link RegisterSpec#intersect} of corresponding elements from 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this instance and the given one where both are non-null. 313de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 31499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param other {@code non-null;} set to intersect with 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param localPrimary whether local variables are primary to 31699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the intersection; if {@code true}, then the only non-null 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result elements occur when registers being intersected have 31899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * equal names (or both have {@code null} names) 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void intersect(RegisterSpecSet other, boolean localPrimary) { 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec[] otherSpecs = other.specs; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int thisLen = specs.length; 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = Math.min(thisLen, otherSpecs.length); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size = -1; 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = specs[i]; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec == null) { 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec intersection = 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spec.intersect(otherSpecs[i], localPrimary); 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (intersection != spec) { 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project specs[i] = intersection; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = len; i < thisLen; i++) { 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project specs[i] = null; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all register numbers are offset by the given amount. Mutability 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the result is inherited from the original. 352de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param delta the amount to offset the register numbers by 35499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecSet withOffset(int delta) { 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = specs.length; 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecSet result = new RegisterSpecSet(len + delta); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = specs[i]; 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec != null) { 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.put(spec.withOffset(delta)); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.size = size; 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isImmutable()) { 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes and return a mutable copy of this instance. 378de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 37999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the mutable copy 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecSet mutableCopy() { 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = specs.length; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecSet copy = new RegisterSpecSet(len); 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < len; i++) { 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = specs[i]; 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec != null) { 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copy.put(spec); 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copy.size = size; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return copy; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 397