1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.rop.code; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.Type; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.TypeList; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.FixedSizeList; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.BitSet; 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * List of {@link RegisterSpec} instances. 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class RegisterSpecList 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson extends FixedSizeList implements TypeList { 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} no-element instance */ 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final RegisterSpecList EMPTY = new RegisterSpecList(0); 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Makes a single-element instance. 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec {@code non-null;} the element 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static RegisterSpecList make(RegisterSpec spec) { 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(1); 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(0, spec); 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Makes a two-element instance. 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec0 {@code non-null;} the first element 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec1 {@code non-null;} the second element 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static RegisterSpecList make(RegisterSpec spec0, 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec spec1) { 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(2); 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(0, spec0); 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(1, spec1); 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Makes a three-element instance. 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec0 {@code non-null;} the first element 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec1 {@code non-null;} the second element 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec2 {@code non-null;} the third element 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1, 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec spec2) { 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(3); 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(0, spec0); 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(1, spec1); 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(2, spec2); 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Makes a four-element instance. 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec0 {@code non-null;} the first element 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec1 {@code non-null;} the second element 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec2 {@code non-null;} the third element 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec3 {@code non-null;} the fourth element 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static RegisterSpecList make(RegisterSpec spec0, RegisterSpec spec1, 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec spec2, 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec spec3) { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(4); 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(0, spec0); 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(1, spec1); 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(2, spec2); 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set(3, spec3); 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. All indices initially contain {@code null}. 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param size the size of the list 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList(int size) { 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(size); 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Type getType(int n) { 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return get(n).getType().getType(); 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getWordCount() { 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int result = 0; 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result += getType(i).getCategory(); 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public TypeList withAddedType(Type type) { 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new UnsupportedOperationException("unsupported"); 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the indicated element. It is an error to call this with the 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * index for an element which was never set; if you do that, this 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * will throw {@code NullPointerException}. 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param n {@code >= 0, < size();} which element 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the indicated element 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpec get(int n) { 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (RegisterSpec) get0(n); 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a RegisterSpec in this list that uses the specified register, 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * or null if there is none in this list. 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param reg Register to find 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return RegisterSpec that uses argument or null. 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpec specForRegister(int reg) { 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec rs; 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson rs = get(i); 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (rs.getReg() == reg) { 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return rs; 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the index of a RegisterSpec in this list that uses the specified 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * register, or -1 if none in this list uses the register. 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param reg Register to find 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return index of RegisterSpec or -1 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int indexOfRegister(int reg) { 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec rs; 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson rs = get(i); 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (rs.getReg() == reg) { 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return i; 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return -1; 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the element at the given index. 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param n {@code >= 0, < size();} which element 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec {@code non-null;} the value to store 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void set(int n, RegisterSpec spec) { 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson set0(n, spec); 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the minimum required register count implied by this 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * instance. This is equal to the highest register number referred 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * to plus the widest width (largest category) of the type used in 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * that register. 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the required registers size 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getRegistersSize() { 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int result = 0; 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec spec = (RegisterSpec) get0(i); 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (spec != null) { 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int min = spec.getNextReg(); 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (min > result) { 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = min; 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a new instance, which is the same as this instance, 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * except that it has an additional element prepended to the original. 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Mutability of the result is inherited from the original. 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param spec {@code non-null;} the new first spec (to prepend) 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList withFirst(RegisterSpec spec) { 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(sz + 1); 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i + 1, get0(i)); 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(0, spec); 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a new instance, which is the same as this instance, 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * except that its first element is removed. Mutability of the 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * result is inherited from the original. 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList withoutFirst() { 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int newSize = size() - 1; 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (newSize == 0) { 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return EMPTY; 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(newSize); 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < newSize; i++) { 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i, get0(i + 1)); 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a new instance, which is the same as this instance, 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * except that its last element is removed. Mutability of the 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * result is inherited from the original. 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList withoutLast() { 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int newSize = size() - 1; 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (newSize == 0) { 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return EMPTY; 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(newSize); 283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < newSize; i++) { 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i, get0(i)); 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 292579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 293579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 296579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns a new instance, which contains a subset of the elements 297579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * specified by the given BitSet. Indexes in the BitSet with a zero 298579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * are included, while indexes with a one are excluded. Mutability 299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * of the result is inherited from the original. 300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param exclusionSet {@code non-null;} set of registers to exclude 302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList subset(BitSet exclusionSet) { 305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int newSize = size() - exclusionSet.cardinality(); 306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (newSize == 0) { 308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return EMPTY; 309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 310579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(newSize); 312579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int newIndex = 0; 314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int oldIndex = 0; oldIndex < size(); oldIndex++) { 315579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!exclusionSet.get(oldIndex)) { 316579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(newIndex, get0(oldIndex)); 317579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson newIndex++; 318579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 321579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns an instance that is identical to this one, except that 330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * all register numbers are offset by the given amount. Mutability 331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * of the result is inherited from the original. 332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param delta the amount to offset the register numbers by 334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList withOffset(int delta) { 337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sz == 0) { 340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Don't bother making a new zero-element instance. 341579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return this; 342579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 343579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(sz); 345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec one = (RegisterSpec) get0(i); 348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (one != null) { 349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i, one.withOffset(delta)); 350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 356579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 357579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 358579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 359579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns an instance that is identical to this one, except that 362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * all incompatible register numbers are renumbered sequentially from 363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the given base, with the first number duplicated if indicated. If 364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * a null BitSet is given, it indicates all registers are compatible. 365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param base the base register number 367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param duplicateFirst whether to duplicate the first number 368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param compatRegs {@code null-ok;} either a {@code non-null} set of 369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * compatible registers, or {@code null} to indicate all registers are 370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * compatible 371579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public RegisterSpecList withExpandedRegisters(int base, 374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean duplicateFirst, 375579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson BitSet compatRegs) { 376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 377579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sz == 0) { 379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Don't bother making a new zero-element instance. 380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return this; 381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList result = new RegisterSpecList(sz); 384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 386579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec one = (RegisterSpec) get0(i); 387579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean replace = (compatRegs == null) ? true : !compatRegs.get(i); 388579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 389579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (replace) { 390579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i, one.withReg(base)); 391579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!duplicateFirst) { 392579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson base += one.getCategory(); 393579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 394579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 395579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i, one); 396579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 397579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 398579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (duplicateFirst) { 399579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson duplicateFirst = false; 400579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 401579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 402579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 403579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 404579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 405579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 406579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 407579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 408579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 409579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 410