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.type.Type; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.FixedSizeList; 22dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhaoimport java.util.BitSet; 23dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * List of {@link RegisterSpec} instances. 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class RegisterSpecList 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extends FixedSizeList implements TypeList { 2999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} no-element instance */ 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final RegisterSpecList EMPTY = new RegisterSpecList(0); 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes a single-element instance. 34de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec {@code non-null;} the element 3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static RegisterSpecList make(RegisterSpec spec) { 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(1); 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(0, spec); 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes a two-element instance. 46de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec0 {@code non-null;} the first element 4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec1 {@code non-null;} the second element 4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static RegisterSpecList make(RegisterSpec spec0, 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec1) { 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(2); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(0, spec0); 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(1, spec1); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes a three-element instance. 61de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 6299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec0 {@code non-null;} the first element 6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec1 {@code non-null;} the second element 6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec2 {@code non-null;} the third element 6599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1, 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec2) { 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(3); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(0, spec0); 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(1, spec1); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(2, spec2); 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes a four-element instance. 78de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec0 {@code non-null;} the first element 8099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec1 {@code non-null;} the second element 8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec2 {@code non-null;} the third element 8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec3 {@code non-null;} the fourth element 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 RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1, 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec2, 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec3) { 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(4); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(0, spec0); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(1, spec1); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(2, spec2); 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(3, spec3); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 9799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Constructs an instance. All indices initially contain {@code null}. 98de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param size the size of the list 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList(int size) { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(size); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 1069dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Type getType(int n) { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return get(n).getType().getType(); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 1129dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getWordCount() { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = 0; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result += getType(i).getCategory(); 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 1259dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson @Override 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeList withAddedType(Type type) { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnsupportedOperationException("unsupported"); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the indicated element. It is an error to call this with the 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * index for an element which was never set; if you do that, this 13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * will throw {@code NullPointerException}. 134de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0, < size();} which element 13699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the indicated element 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec get(int n) { 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (RegisterSpec) get0(n); 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a RegisterSpec in this list that uses the specified register, 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or null if there is none in this list. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg Register to find 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return RegisterSpec that uses argument or null. 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpec specForRegister(int reg) { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec rs; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rs = get(i); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (rs.getReg() == reg) { 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return rs; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the index of a RegisterSpec in this list that uses the specified 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register, or -1 if none in this list uses the register. 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg Register to find 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return index of RegisterSpec or -1 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int indexOfRegister(int reg) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec rs; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rs = get(i); 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (rs.getReg() == reg) { 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro return -1; 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the element at the given index. 186de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0, < size();} which element 18899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec {@code non-null;} the value to store 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void set(int n, RegisterSpec spec) { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set0(n, spec); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the minimum required register count implied by this 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance. This is equal to the highest register number referred 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to plus the widest width (largest category) of the type used in 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that register. 199de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the required registers size 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getRegistersSize() { 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = 0; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = (RegisterSpec) get0(i); 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec != null) { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int min = spec.getNextReg(); 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (min > result) { 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = min; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a new instance, which is the same as this instance, 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * except that it has an additional element prepended to the original. 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Mutability of the result is inherited from the original. 223de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 22499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param spec {@code non-null;} the new first spec (to prepend) 22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList withFirst(RegisterSpec spec) { 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(sz + 1); 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set0(i + 1, get0(i)); 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set0(0, spec); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isImmutable()) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a new instance, which is the same as this instance, 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * except that its first element is removed. Mutability of the 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result is inherited from the original. 247de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 24899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList withoutFirst() { 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newSize = size() - 1; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newSize == 0) { 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return EMPTY; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(newSize); 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < newSize; i++) { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set0(i, get0(i + 1)); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isImmutable()) { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a new instance, which is the same as this instance, 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * except that its last element is removed. Mutability of the 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result is inherited from the original. 274de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 27599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList withoutLast() { 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newSize = size() - 1; 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newSize == 0) { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return EMPTY; 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(newSize); 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < newSize; i++) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set0(i, get0(i)); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isImmutable()) { 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 298dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * Returns a new instance, which contains a subset of the elements 299dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * specified by the given BitSet. Indexes in the BitSet with a zero 300dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * are included, while indexes with a one are excluded. Mutability 301dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * of the result is inherited from the original. 302dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * 303dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * @param exclusionSet {@code non-null;} set of registers to exclude 304dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * @return {@code non-null;} an appropriately-constructed instance 305dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao */ 306dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao public RegisterSpecList subset(BitSet exclusionSet) { 307dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao int newSize = size() - exclusionSet.cardinality(); 308dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 309dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao if (newSize == 0) { 310dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao return EMPTY; 311dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao } 312dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 313dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao RegisterSpecList result = new RegisterSpecList(newSize); 314dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 315dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao int newIndex = 0; 316dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao for (int oldIndex = 0; oldIndex < size(); oldIndex++) { 317dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao if (!exclusionSet.get(oldIndex)) { 318dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao result.set0(newIndex, get0(oldIndex)); 319dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao newIndex++; 320dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao } 321dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao } 322dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 323dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao if (isImmutable()) { 324dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao result.setImmutable(); 325dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao } 326dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 327dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao return result; 328dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao } 329dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 330dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao /** 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all register numbers are offset by the given amount. Mutability 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the result is inherited from the original. 334de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param delta the amount to offset the register numbers by 33699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList withOffset(int delta) { 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz == 0) { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Don't bother making a new zero-element instance. 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(sz); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec one = (RegisterSpec) get0(i); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (one != null) { 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set0(i, one.withOffset(delta)); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isImmutable()) { 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns an instance that is identical to this one, except that 364dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * all incompatible register numbers are renumbered sequentially from 365dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * the given base, with the first number duplicated if indicated. If 366d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier * a null BitSet is given, it indicates all registers are incompatible. 367de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param base the base register number 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param duplicateFirst whether to duplicate the first number 370dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * @param compatRegs {@code null-ok;} either a {@code non-null} set of 371dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao * compatible registers, or {@code null} to indicate all registers are 372d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier * incompatible 37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} an appropriately-constructed instance 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 375dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao public RegisterSpecList withExpandedRegisters(int base, 376dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao boolean duplicateFirst, 377dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao BitSet compatRegs) { 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = size(); 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz == 0) { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Don't bother making a new zero-element instance. 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 385d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier Expander expander = new Expander(this, compatRegs, base, duplicateFirst); 386dd79e4e11fa20d6677b70ce6618a8653a1f3520djeffhao 38776e15e367ae1189b6f641ba8d16ca92bd179dac0mikaelpeltier for (int regIdx = 0; regIdx < sz; regIdx++) { 38876e15e367ae1189b6f641ba8d16ca92bd179dac0mikaelpeltier expander.expandRegister(regIdx); 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 391d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier return expander.getResult(); 392d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 393d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 394d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private static class Expander { 3959dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson private final BitSet compatRegs; 3969dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson private final RegisterSpecList regSpecList; 397d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private int base; 3989dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson private final RegisterSpecList result; 399d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private boolean duplicateFirst; 400d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 401d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private Expander(RegisterSpecList regSpecList, BitSet compatRegs, int base, 402d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier boolean duplicateFirst) { 403d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier this.regSpecList = regSpecList; 404d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier this.compatRegs = compatRegs; 405d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier this.base = base; 406d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier this.result = new RegisterSpecList(regSpecList.size()); 407d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier this.duplicateFirst = duplicateFirst; 408d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 409d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 410d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private void expandRegister(int regIdx) { 411d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier expandRegister(regIdx, (RegisterSpec) regSpecList.get0(regIdx)); 412d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 413d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 414d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private void expandRegister(int regIdx, RegisterSpec registerToExpand) { 415d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier boolean replace = (compatRegs == null) ? true : !compatRegs.get(regIdx); 416d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier RegisterSpec expandedReg; 417d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 418d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier if (replace) { 419d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier expandedReg = registerToExpand.withReg(base); 420d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier if (!duplicateFirst) { 421d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier base += expandedReg.getCategory(); 422d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 423d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } else { 424d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier expandedReg = registerToExpand; 425d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 426d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 4270e44f19ba0c5682635d12165a7f8a926ffe50f5eBenoit Lamarche // Reset duplicateFirst when the first register has been dealt with. 4280e44f19ba0c5682635d12165a7f8a926ffe50f5eBenoit Lamarche duplicateFirst = false; 4290e44f19ba0c5682635d12165a7f8a926ffe50f5eBenoit Lamarche 430d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier result.set0(regIdx, expandedReg); 431d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 432d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier 433d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier private RegisterSpecList getResult() { 434d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier if (regSpecList.isImmutable()) { 435d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier result.setImmutable(); 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 439d0c62c2a778d1c9148077c869f6313723f57eddcmikaelpeltier } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 442