comparison graal/com.oracle.max.cri/src/com/sun/cri/ci/CiRegister.java @ 3733:e233f5660da4

Added Java files from Maxine project.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 17 Dec 2011 19:59:18 +0100
parents
children bc8527f3071c
comparison
equal deleted inserted replaced
3732:3e2e8b8abdaf 3733:e233f5660da4
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.sun.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 * Invalid register.
35 */
36 public static final CiRegister None = new CiRegister(-1, -1, 0, "noreg");
37
38 /**
39 * Frame pointer of the current method. All spill slots and outgoing stack-based arguments
40 * are addressed relative to this register.
41 */
42 public static final CiRegister Frame = new CiRegister(-2, -2, 0, "framereg", RegisterFlag.CPU);
43
44 public static final CiRegister CallerFrame = new CiRegister(-3, -3, 0, "callerframereg", RegisterFlag.CPU);
45
46 /**
47 * The identifier for this register that is unique across all the registers in a {@link CiArchitecture}.
48 * A valid register has {@code number > 0}.
49 */
50 public final int number;
51
52 /**
53 * The mnemonic of this register.
54 */
55 public final String name;
56
57 /**
58 * The actual encoding in a target machine instruction for this register, which may or
59 * may not be the same as {@link #number}.
60 */
61 public final int encoding;
62
63 /**
64 * The size of the stack slot used to spill the value of this register.
65 */
66 public final int spillSlotSize;
67
68 /**
69 * The set of {@link RegisterFlag} values associated with this register.
70 */
71 private final int flags;
72
73 /**
74 * An array of {@link CiRegisterValue} objects, for this register, with one entry
75 * per {@link CiKind}, indexed by {@link CiKind#ordinal}.
76 */
77 private final CiRegisterValue[] values;
78
79 /**
80 * Attributes that characterize a register in a useful way.
81 *
82 */
83 public enum RegisterFlag {
84 /**
85 * Denotes an integral (i.e. non floating point) register.
86 */
87 CPU,
88
89 /**
90 * Denotes a register whose lowest order byte can be addressed separately.
91 */
92 Byte,
93
94 /**
95 * Denotes a floating point register.
96 */
97 FPU;
98
99 public final int mask = 1 << (ordinal() + 1);
100 }
101
102 /**
103 * Creates a {@code CiRegister} instance.
104 *
105 * @param number unique identifier for the register
106 * @param encoding the target machine encoding for the register
107 * @param spillSlotSize the size of the stack slot used to spill the value of the register
108 * @param name the mnemonic name for the register
109 * @param flags the set of {@link RegisterFlag} values for the register
110 */
111 public CiRegister(int number, int encoding, int spillSlotSize, String name, RegisterFlag... flags) {
112 this.number = number;
113 this.name = name;
114 this.spillSlotSize = spillSlotSize;
115 this.flags = createMask(flags);
116 this.encoding = encoding;
117
118 values = new CiRegisterValue[CiKind.VALUES.length];
119 for (CiKind kind : CiKind.VALUES) {
120 values[kind.ordinal()] = new CiRegisterValue(kind, this);
121 }
122 }
123
124 private int createMask(RegisterFlag... flags) {
125 int result = 0;
126 for (RegisterFlag f : flags) {
127 result |= f.mask;
128 }
129 return result;
130 }
131
132 public boolean isSet(RegisterFlag f) {
133 return (flags & f.mask) != 0;
134 }
135
136 /**
137 * Gets this register as a {@linkplain CiRegisterValue value} with a specified kind.
138 * @param kind the specified kind
139 * @return the {@link CiRegisterValue}
140 */
141 public CiRegisterValue asValue(CiKind kind) {
142 return values[kind.ordinal()];
143 }
144
145 /**
146 * Gets this register as a {@linkplain CiRegisterValue value} with no particular kind.
147 * @return a {@link CiRegisterValue} with {@link CiKind#Illegal} kind.
148 */
149 public CiRegisterValue asValue() {
150 return asValue(CiKind.Illegal);
151 }
152
153 /**
154 * Determines if this is a valid register.
155 * @return {@code true} iff this register is valid
156 */
157 public boolean isValid() {
158 return number >= 0;
159 }
160
161 /**
162 * Determines if this a floating point register.
163 */
164 public boolean isFpu() {
165 return isSet(RegisterFlag.FPU);
166 }
167
168 /**
169 * Determines if this a general purpose register.
170 */
171 public boolean isCpu() {
172 return isSet(RegisterFlag.CPU);
173 }
174
175 /**
176 * Determines if this register has the {@link RegisterFlag#Byte} attribute set.
177 * @return {@code true} iff this register has the {@link RegisterFlag#Byte} attribute set.
178 */
179 public boolean isByte() {
180 return isSet(RegisterFlag.Byte);
181 }
182
183 /**
184 * Categorizes a set of registers by {@link RegisterFlag}.
185 *
186 * @param registers a list of registers to be categorized
187 * @return a map from each {@link RegisterFlag} constant to the list of registers for which the flag is
188 * {@linkplain #isSet(RegisterFlag) set}
189 */
190 public static EnumMap<RegisterFlag, CiRegister[]> categorize(CiRegister[] registers) {
191 EnumMap<RegisterFlag, CiRegister[]> result = new EnumMap<RegisterFlag, CiRegister[]>(RegisterFlag.class);
192 for (RegisterFlag flag : RegisterFlag.values()) {
193 ArrayList<CiRegister> list = new ArrayList<CiRegister>();
194 for (CiRegister r : registers) {
195 if (r.isSet(flag)) {
196 list.add(r);
197 }
198 }
199 result.put(flag, list.toArray(new CiRegister[list.size()]));
200 }
201 return result;
202 }
203
204 /**
205 * Gets the maximum register {@linkplain #number number} in a given set of registers.
206 *
207 * @param registers the set of registers to process
208 * @return the maximum register number for any register in {@code registers}
209 */
210 public static int maxRegisterNumber(CiRegister[] registers) {
211 int max = Integer.MIN_VALUE;
212 for (CiRegister r : registers) {
213 if (r.number > max) {
214 max = r.number;
215 }
216 }
217 return max;
218 }
219
220 /**
221 * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
222 *
223 * @param registers the set of registers to process
224 * @return the maximum register encoding for any register in {@code registers}
225 */
226 public static int maxRegisterEncoding(CiRegister[] registers) {
227 int max = Integer.MIN_VALUE;
228 for (CiRegister r : registers) {
229 if (r.encoding > max) {
230 max = r.encoding;
231 }
232 }
233 return max;
234 }
235
236 @Override
237 public String toString() {
238 return name;
239 }
240
241 @Override
242 public int compareTo(CiRegister o) {
243 if (number < o.number) {
244 return -1;
245 }
246 if (number > o.number) {
247 return 1;
248 }
249 return 0;
250 }
251
252 }