comparison graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegisterConfig.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/CiRegisterConfig.java@319860ae697a
children 438ab53efdd0
comparison
equal deleted inserted replaced
4198:8c9c0e1eaab1 4199:aaac4894175c
1 /*
2 * Copyright (c) 2010, 2012, 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.util.*;
26
27 import com.oracle.max.cri.ci.CiCallingConvention.*;
28 import com.oracle.max.cri.ci.CiRegister.*;
29 import com.oracle.max.cri.ri.*;
30
31 /**
32 * A default implementation of {@link RiRegisterConfig}.
33 */
34 public class CiRegisterConfig implements RiRegisterConfig {
35
36 /**
37 * The object describing the callee save area of this register configuration.
38 */
39 public CiCalleeSaveLayout csl;
40
41 /**
42 * The minimum register role identifier.
43 */
44 public final int minRole;
45
46 /**
47 * The map from register role IDs to registers.
48 */
49 public final CiRegister[] registersRoleMap;
50
51 /**
52 * The set of registers that can be used by the register allocator.
53 */
54 public final CiRegister[] allocatable;
55
56 /**
57 * The set of registers that can be used by the register allocator,
58 * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register
59 * {@linkplain RegisterFlag flags}.
60 */
61 public final EnumMap<RegisterFlag, CiRegister[]> categorized;
62
63 /**
64 * The ordered set of registers used to pass integral arguments.
65 */
66 public final CiRegister[] cpuParameters;
67
68 /**
69 * The ordered set of registers used to pass floating point arguments.
70 */
71 public final CiRegister[] fpuParameters;
72
73 /**
74 * The caller saved registers.
75 */
76 public final CiRegister[] callerSave;
77
78 /**
79 * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
80 */
81 public final CiRegister frame;
82
83 /**
84 * Register for returning an integral value.
85 */
86 public final CiRegister integralReturn;
87
88 /**
89 * Register for returning a floating point value.
90 */
91 public final CiRegister floatingPointReturn;
92
93 /**
94 * The map from register {@linkplain CiRegister#number numbers} to register
95 * {@linkplain RiRegisterAttributes attributes} for this register configuration.
96 */
97 public final RiRegisterAttributes[] attributesMap;
98
99 /**
100 * The scratch register.
101 */
102 public final CiRegister scratch;
103
104 /**
105 * The frame offset of the first stack argument for each calling convention {@link CiCallingConvention.Type}.
106 */
107 public final int[] stackArg0Offsets = new int[CiCallingConvention.Type.VALUES.length];
108
109 public CiRegisterConfig(
110 CiRegister frame,
111 CiRegister integralReturn,
112 CiRegister floatingPointReturn,
113 CiRegister scratch,
114 CiRegister[] allocatable,
115 CiRegister[] callerSave,
116 CiRegister[] parameters,
117 CiCalleeSaveLayout csl,
118 CiRegister[] allRegisters,
119 Map<Integer, CiRegister> roles) {
120 this.frame = frame;
121 this.csl = csl;
122 this.allocatable = allocatable;
123 this.callerSave = callerSave;
124 assert !Arrays.asList(allocatable).contains(scratch);
125 this.scratch = scratch;
126 EnumMap<RegisterFlag, CiRegister[]> categorizedParameters = CiRegister.categorize(parameters);
127 this.cpuParameters = categorizedParameters.get(RegisterFlag.CPU);
128 this.fpuParameters = categorizedParameters.get(RegisterFlag.FPU);
129 categorized = CiRegister.categorize(allocatable);
130 attributesMap = RiRegisterAttributes.createMap(this, allRegisters);
131 this.floatingPointReturn = floatingPointReturn;
132 this.integralReturn = integralReturn;
133 int minRoleId = Integer.MAX_VALUE;
134 int maxRoleId = Integer.MIN_VALUE;
135 for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
136 int id = e.getKey();
137 assert id >= 0;
138 if (minRoleId > id) {
139 minRoleId = id;
140 }
141 if (maxRoleId < id) {
142 maxRoleId = id;
143 }
144 }
145 registersRoleMap = new CiRegister[(maxRoleId - minRoleId) + 1];
146 for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
147 int id = e.getKey();
148 registersRoleMap[id] = e.getValue();
149 }
150 minRole = minRoleId;
151 }
152
153 public CiRegisterConfig(CiRegisterConfig src, CiCalleeSaveLayout csl) {
154 this.frame = src.frame;
155 this.csl = csl;
156 this.allocatable = src.allocatable;
157 this.callerSave = src.callerSave;
158 this.scratch = src.scratch;
159 this.cpuParameters = src.cpuParameters;
160 this.fpuParameters = src.fpuParameters;
161 this.categorized = src.categorized;
162 this.attributesMap = src.attributesMap;
163 this.floatingPointReturn = src.floatingPointReturn;
164 this.integralReturn = src.integralReturn;
165 this.registersRoleMap = src.registersRoleMap;
166 this.minRole = src.minRole;
167 System.arraycopy(src.stackArg0Offsets, 0, stackArg0Offsets, 0, stackArg0Offsets.length);
168 }
169
170 public CiRegister getReturnRegister(CiKind kind) {
171 if (kind.isDouble() || kind.isFloat()) {
172 return floatingPointReturn;
173 }
174 return integralReturn;
175 }
176
177 public CiRegister getFrameRegister() {
178 return frame;
179 }
180
181 public CiRegister getScratchRegister() {
182 return scratch;
183 }
184
185 /**
186 * {@inheritDoc}
187 *
188 * This implementation assigns all available registers to parameters before assigning
189 * any stack slots to parameters.
190 */
191 public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly) {
192 CiValue[] locations = new CiValue[parameters.length];
193
194 int currentGeneral = 0;
195 int currentXMM = 0;
196 int currentStackOffset = stackArg0Offsets[type.ordinal()];
197
198 for (int i = 0; i < parameters.length; i++) {
199 final CiKind kind = parameters[i];
200
201 switch (kind) {
202 case Byte:
203 case Boolean:
204 case Short:
205 case Char:
206 case Int:
207 case Long:
208 case Object:
209 if (!stackOnly && currentGeneral < cpuParameters.length) {
210 CiRegister register = cpuParameters[currentGeneral++];
211 locations[i] = register.asValue(kind);
212 }
213 break;
214
215 case Float:
216 case Double:
217 if (!stackOnly && currentXMM < fpuParameters.length) {
218 CiRegister register = fpuParameters[currentXMM++];
219 locations[i] = register.asValue(kind);
220 }
221 break;
222
223 default:
224 throw new InternalError("Unexpected parameter kind: " + kind);
225 }
226
227 if (locations[i] == null) {
228 locations[i] = CiStackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
229 currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
230 }
231 }
232
233 return new CiCallingConvention(locations, currentStackOffset);
234 }
235
236 public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
237 if (flag == RegisterFlag.CPU) {
238 return cpuParameters;
239 }
240 assert flag == RegisterFlag.FPU;
241 return fpuParameters;
242 }
243
244 public CiRegister[] getAllocatableRegisters() {
245 return allocatable;
246 }
247
248 public EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters() {
249 return categorized;
250 }
251
252 public CiRegister[] getCallerSaveRegisters() {
253 return callerSave;
254 }
255
256 public CiCalleeSaveLayout getCalleeSaveLayout() {
257 return csl;
258 }
259
260 public RiRegisterAttributes[] getAttributesMap() {
261 return attributesMap;
262 }
263
264 public CiRegister getRegisterForRole(int id) {
265 return registersRoleMap[id - minRole];
266 }
267
268 @Override
269 public String toString() {
270 StringBuilder roleMap = new StringBuilder();
271 for (int i = 0; i < registersRoleMap.length; ++i) {
272 CiRegister reg = registersRoleMap[i];
273 if (reg != null) {
274 if (roleMap.length() != 0) {
275 roleMap.append(", ");
276 }
277 roleMap.append(i + minRole).append(" -> ").append(reg);
278 }
279 }
280 StringBuilder stackArg0OffsetsMap = new StringBuilder();
281 for (Type t : Type.VALUES) {
282 if (stackArg0OffsetsMap.length() != 0) {
283 stackArg0OffsetsMap.append(", ");
284 }
285 stackArg0OffsetsMap.append(t).append(" -> ").append(stackArg0Offsets[t.ordinal()]);
286 }
287 String res = String.format(
288 "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
289 "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
290 "CalleeSave: " + getCalleeSaveLayout() + "%n" +
291 "CPU Params: " + Arrays.toString(cpuParameters) + "%n" +
292 "FPU Params: " + Arrays.toString(fpuParameters) + "%n" +
293 "VMRoles: " + roleMap + "%n" +
294 "stackArg0: " + stackArg0OffsetsMap + "%n" +
295 "Scratch: " + getScratchRegister() + "%n");
296 return res;
297 }
298 }