comparison graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegister.java @ 4199:aaac4894175c

Renamed cri packages from sun to oracle.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 03 Jan 2012 16:29:28 +0100
parents graal/com.oracle.max.cri/src/com/sun/cri/ci/CiRegister.java@bc8527f3071c
children 12c63380e7ff
comparison
equal deleted inserted replaced
4198:8c9c0e1eaab1 4199:aaac4894175c
1 /*
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.max.cri.ci;
24
25 import java.io.*;
26 import java.util.*;
27
28 /**
29 * Represents a target machine register.
30 */
31 public final class CiRegister implements Comparable<CiRegister>, Serializable {
32
33 /**
34 *
35 */
36 private static final long serialVersionUID = -7213269157816016300L;
37
38 /**
39 * Invalid register.
40 */
41 public static final CiRegister None = new CiRegister(-1, -1, 0, "noreg");
42
43 /**
44 * Frame pointer of the current method. All spill slots and outgoing stack-based arguments
45 * are addressed relative to this register.
46 */
47 public static final CiRegister Frame = new CiRegister(-2, -2, 0, "framereg", RegisterFlag.CPU);
48
49 public static final CiRegister CallerFrame = new CiRegister(-3, -3, 0, "callerframereg", RegisterFlag.CPU);
50
51 /**
52 * The identifier for this register that is unique across all the registers in a {@link CiArchitecture}.
53 * A valid register has {@code number > 0}.
54 */
55 public final int number;
56
57 /**
58 * The mnemonic of this register.
59 */
60 public final String name;
61
62 /**
63 * The actual encoding in a target machine instruction for this register, which may or
64 * may not be the same as {@link #number}.
65 */
66 public final int encoding;
67
68 /**
69 * The size of the stack slot used to spill the value of this register.
70 */
71 public final int spillSlotSize;
72
73 /**
74 * The set of {@link RegisterFlag} values associated with this register.
75 */
76 private final int flags;
77
78 /**
79 * An array of {@link CiRegisterValue} objects, for this register, with one entry
80 * per {@link CiKind}, indexed by {@link CiKind#ordinal}.
81 */
82 private final CiRegisterValue[] values;
83
84 /**
85 * Attributes that characterize a register in a useful way.
86 *
87 */
88 public enum RegisterFlag {
89 /**
90 * Denotes an integral (i.e. non floating point) register.
91 */
92 CPU,
93
94 /**
95 * Denotes a register whose lowest order byte can be addressed separately.
96 */
97 Byte,
98
99 /**
100 * Denotes a floating point register.
101 */
102 FPU;
103
104 public final int mask = 1 << (ordinal() + 1);
105 }
106
107 /**
108 * Creates a {@code CiRegister} instance.
109 *
110 * @param number unique identifier for the register
111 * @param encoding the target machine encoding for the register
112 * @param spillSlotSize the size of the stack slot used to spill the value of the register
113 * @param name the mnemonic name for the register
114 * @param flags the set of {@link RegisterFlag} values for the register
115 */
116 public CiRegister(int number, int encoding, int spillSlotSize, String name, RegisterFlag... flags) {
117 this.number = number;
118 this.name = name;
119 this.spillSlotSize = spillSlotSize;
120 this.flags = createMask(flags);
121 this.encoding = encoding;
122
123 values = new CiRegisterValue[CiKind.VALUES.length];
124 for (CiKind kind : CiKind.VALUES) {
125 values[kind.ordinal()] = new CiRegisterValue(kind, this);
126 }
127 }
128
129 private static int createMask(RegisterFlag... flags) {
130 int result = 0;
131 for (RegisterFlag f : flags) {
132 result |= f.mask;
133 }
134 return result;
135 }
136
137 public boolean isSet(RegisterFlag f) {
138 return (flags & f.mask) != 0;
139 }
140
141 /**
142 * Gets this register as a {@linkplain CiRegisterValue value} with a specified kind.
143 * @param kind the specified kind
144 * @return the {@link CiRegisterValue}
145 */
146 public CiRegisterValue asValue(CiKind kind) {
147 return values[kind.ordinal()];
148 }
149
150 /**
151 * Gets this register as a {@linkplain CiRegisterValue value} with no particular kind.
152 * @return a {@link CiRegisterValue} with {@link CiKind#Illegal} kind.
153 */
154 public CiRegisterValue asValue() {
155 return asValue(CiKind.Illegal);
156 }
157
158 /**
159 * Determines if this is a valid register.
160 * @return {@code true} iff this register is valid
161 */
162 public boolean isValid() {
163 return number >= 0;
164 }
165
166 /**
167 * Determines if this a floating point register.
168 */
169 public boolean isFpu() {
170 return isSet(RegisterFlag.FPU);
171 }
172
173 /**
174 * Determines if this a general purpose register.
175 */
176 public boolean isCpu() {
177 return isSet(RegisterFlag.CPU);
178 }
179
180 /**
181 * Determines if this register has the {@link RegisterFlag#Byte} attribute set.
182 * @return {@code true} iff this register has the {@link RegisterFlag#Byte} attribute set.
183 */
184 public boolean isByte() {
185 return isSet(RegisterFlag.Byte);
186 }
187
188 /**
189 * Categorizes a set of registers by {@link RegisterFlag}.
190 *
191 * @param registers a list of registers to be categorized
192 * @return a map from each {@link RegisterFlag} constant to the list of registers for which the flag is
193 * {@linkplain #isSet(RegisterFlag) set}
194 */
195 public static EnumMap<RegisterFlag, CiRegister[]> categorize(CiRegister[] registers) {
196 EnumMap<RegisterFlag, CiRegister[]> result = new EnumMap<>(RegisterFlag.class);
197 for (RegisterFlag flag : RegisterFlag.values()) {
198 ArrayList<CiRegister> list = new ArrayList<>();
199 for (CiRegister r : registers) {
200 if (r.isSet(flag)) {
201 list.add(r);
202 }
203 }
204 result.put(flag, list.toArray(new CiRegister[list.size()]));
205 }
206 return result;
207 }
208
209 /**
210 * Gets the maximum register {@linkplain #number number} in a given set of registers.
211 *
212 * @param registers the set of registers to process
213 * @return the maximum register number for any register in {@code registers}
214 */
215 public static int maxRegisterNumber(CiRegister[] registers) {
216 int max = Integer.MIN_VALUE;
217 for (CiRegister r : registers) {
218 if (r.number > max) {
219 max = r.number;
220 }
221 }
222 return max;
223 }
224
225 /**
226 * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
227 *
228 * @param registers the set of registers to process
229 * @return the maximum register encoding for any register in {@code registers}
230 */
231 public static int maxRegisterEncoding(CiRegister[] registers) {
232 int max = Integer.MIN_VALUE;
233 for (CiRegister r : registers) {
234 if (r.encoding > max) {
235 max = r.encoding;
236 }
237 }
238 return max;
239 }
240
241 @Override
242 public String toString() {
243 return name;
244 }
245
246 @Override
247 public int compareTo(CiRegister o) {
248 if (number < o.number) {
249 return -1;
250 }
251 if (number > o.number) {
252 return 1;
253 }
254 return 0;
255 }
256
257 }