Mercurial > hg > truffle
comparison graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/Register.java @ 21556:48c1ebd24120
renamed com.oracle.graal.api[meta|code] modules to com.oracle.jvmci.[meta|code] (JBS:GRAAL-53)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 27 May 2015 00:36:16 +0200 |
parents | graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java@edb88f5425e6 |
children |
comparison
equal
deleted
inserted
replaced
21555:d12eaef9af72 | 21556:48c1ebd24120 |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2014, 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.jvmci.code; | |
24 | |
25 import com.oracle.jvmci.meta.*; | |
26 | |
27 /** | |
28 * Represents a target machine register. | |
29 */ | |
30 public final class Register implements Comparable<Register> { | |
31 | |
32 public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL"); | |
33 | |
34 /** | |
35 * Invalid register. | |
36 */ | |
37 public static final Register None = new Register(-1, -1, "noreg", SPECIAL); | |
38 | |
39 /** | |
40 * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are | |
41 * addressed relative to this register. | |
42 */ | |
43 public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL); | |
44 | |
45 public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL); | |
46 | |
47 /** | |
48 * The identifier for this register that is unique across all the registers in a | |
49 * {@link Architecture}. A valid register has {@code number > 0}. | |
50 */ | |
51 public final int number; | |
52 | |
53 /** | |
54 * The mnemonic of this register. | |
55 */ | |
56 public final String name; | |
57 | |
58 /** | |
59 * The actual encoding in a target machine instruction for this register, which may or may not | |
60 * be the same as {@link #number}. | |
61 */ | |
62 public final int encoding; | |
63 | |
64 /** | |
65 * The assembler calls this method to get the register's encoding. | |
66 */ | |
67 public int encoding() { | |
68 return encoding; | |
69 } | |
70 | |
71 /** | |
72 * A platform specific register category that describes which values can be stored in a | |
73 * register. | |
74 */ | |
75 private final RegisterCategory registerCategory; | |
76 | |
77 /** | |
78 * A platform specific register type that describes which values can be stored in a register. | |
79 */ | |
80 public static class RegisterCategory { | |
81 | |
82 private final String name; | |
83 | |
84 private final int referenceMapOffset; | |
85 private final int referenceMapShift; | |
86 | |
87 public RegisterCategory(String name) { | |
88 this(name, 0, 0); | |
89 } | |
90 | |
91 public RegisterCategory(String name, int referenceMapOffset) { | |
92 this(name, referenceMapOffset, 0); | |
93 } | |
94 | |
95 public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) { | |
96 this.name = name; | |
97 this.referenceMapOffset = referenceMapOffset; | |
98 this.referenceMapShift = referenceMapShift; | |
99 } | |
100 | |
101 @Override | |
102 public String toString() { | |
103 return name; | |
104 } | |
105 | |
106 @Override | |
107 public int hashCode() { | |
108 return 23 + name.hashCode(); | |
109 } | |
110 | |
111 @Override | |
112 public boolean equals(Object obj) { | |
113 if (obj instanceof RegisterCategory) { | |
114 RegisterCategory that = (RegisterCategory) obj; | |
115 return this.referenceMapOffset == that.referenceMapOffset && this.referenceMapShift == that.referenceMapShift && this.name.equals(that.name); | |
116 } | |
117 return false; | |
118 } | |
119 } | |
120 | |
121 /** | |
122 * Creates a {@link Register} instance. | |
123 * | |
124 * @param number unique identifier for the register | |
125 * @param encoding the target machine encoding for the register | |
126 * @param name the mnemonic name for the register | |
127 * @param registerCategory the register category | |
128 */ | |
129 public Register(int number, int encoding, String name, RegisterCategory registerCategory) { | |
130 this.number = number; | |
131 this.name = name; | |
132 this.registerCategory = registerCategory; | |
133 this.encoding = encoding; | |
134 } | |
135 | |
136 public RegisterCategory getRegisterCategory() { | |
137 return registerCategory; | |
138 } | |
139 | |
140 /** | |
141 * Get the start index of this register in the {@link ReferenceMap}. | |
142 */ | |
143 public int getReferenceMapIndex() { | |
144 return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset; | |
145 } | |
146 | |
147 /** | |
148 * Gets this register as a {@linkplain RegisterValue value} with a specified kind. | |
149 * | |
150 * @param kind the specified kind | |
151 * @return the {@link RegisterValue} | |
152 */ | |
153 public RegisterValue asValue(LIRKind kind) { | |
154 return new RegisterValue(kind, this); | |
155 } | |
156 | |
157 /** | |
158 * Gets this register as a {@linkplain RegisterValue value} with no particular kind. | |
159 * | |
160 * @return a {@link RegisterValue} with {@link Kind#Illegal} kind. | |
161 */ | |
162 public RegisterValue asValue() { | |
163 return asValue(LIRKind.Illegal); | |
164 } | |
165 | |
166 /** | |
167 * Determines if this is a valid register. | |
168 * | |
169 * @return {@code true} iff this register is valid | |
170 */ | |
171 public boolean isValid() { | |
172 return number >= 0; | |
173 } | |
174 | |
175 /** | |
176 * Gets the maximum register {@linkplain #number number} in a given set of registers. | |
177 * | |
178 * @param registers the set of registers to process | |
179 * @return the maximum register number for any register in {@code registers} | |
180 */ | |
181 public static int maxRegisterNumber(Register[] registers) { | |
182 int max = Integer.MIN_VALUE; | |
183 for (Register r : registers) { | |
184 if (r.number > max) { | |
185 max = r.number; | |
186 } | |
187 } | |
188 return max; | |
189 } | |
190 | |
191 /** | |
192 * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers. | |
193 * | |
194 * @param registers the set of registers to process | |
195 * @return the maximum register encoding for any register in {@code registers} | |
196 */ | |
197 public static int maxRegisterEncoding(Register[] registers) { | |
198 int max = Integer.MIN_VALUE; | |
199 for (Register r : registers) { | |
200 if (r.encoding > max) { | |
201 max = r.encoding; | |
202 } | |
203 } | |
204 return max; | |
205 } | |
206 | |
207 @Override | |
208 public String toString() { | |
209 return name; | |
210 } | |
211 | |
212 @Override | |
213 public int compareTo(Register o) { | |
214 if (number < o.number) { | |
215 return -1; | |
216 } | |
217 if (number > o.number) { | |
218 return 1; | |
219 } | |
220 return 0; | |
221 } | |
222 | |
223 @Override | |
224 public int hashCode() { | |
225 return 17 + name.hashCode(); | |
226 } | |
227 | |
228 @Override | |
229 public boolean equals(Object obj) { | |
230 if (obj instanceof Register) { | |
231 Register other = (Register) obj; | |
232 if (number == other.number) { | |
233 assert name.equals(other.name); | |
234 assert encoding == other.encoding; | |
235 assert registerCategory.equals(other.registerCategory); | |
236 return true; | |
237 } | |
238 } | |
239 return false; | |
240 } | |
241 } |