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