comparison graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegisterConfig.java @ 5506:56860d3f9f39

More refactorings and renamings in preparation of ci/ri split.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 07 Jun 2012 18:12:01 +0200
parents graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRegisterConfig.java@438ab53efdd0
children dc71b06d09f8
comparison
equal deleted inserted replaced
5505:28af6dff047f 5506:56860d3f9f39
1 /* 1 /*
2 * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. 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. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
27 import com.oracle.max.cri.ci.CiCallingConvention.*; 27 import com.oracle.max.cri.ci.CiCallingConvention.*;
28 import com.oracle.max.cri.ci.CiRegister.*; 28 import com.oracle.max.cri.ci.CiRegister.*;
29 import com.oracle.max.cri.ri.*; 29 import com.oracle.max.cri.ri.*;
30 30
31 /** 31 /**
32 * A default implementation of {@link RiRegisterConfig}. 32 * A register configuration binds roles and {@linkplain CiRegisterAttributes attributes}
33 * to physical registers.
33 */ 34 */
34 public class CiRegisterConfig implements RiRegisterConfig { 35 public interface CiRegisterConfig {
35 36
36 /** 37 /**
37 * The object describing the callee save area of this register configuration. 38 * Gets the register to be used for returning a value of a given kind.
38 */ 39 */
39 public CiCalleeSaveLayout csl; 40 CiRegister getReturnRegister(RiKind kind);
40 41
41 /** 42 /**
42 * The minimum register role identifier. 43 * Gets the register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
43 */ 44 */
44 public final int minRole; 45 CiRegister getFrameRegister();
46
47 CiRegister getScratchRegister();
45 48
46 /** 49 /**
47 * The map from register role IDs to registers. 50 * Gets the calling convention describing how arguments are passed.
51 *
52 * @param type the type of calling convention being requested
53 * @param parameters the types of the arguments of the call
54 * @param target the target platform
55 * @param stackOnly ignore registers
48 */ 56 */
49 public final CiRegister[] registersRoleMap; 57 CiCallingConvention getCallingConvention(Type type, RiKind[] parameters, CiTarget target, boolean stackOnly);
50 58
51 /** 59 /**
52 * The set of registers that can be used by the register allocator. 60 * Gets the ordered set of registers that are can be used to pass parameters
61 * according to a given calling convention.
62 *
63 * @param type the type of calling convention
64 * @param flag specifies whether registers for {@linkplain RegisterFlag#CPU integral} or
65 * {@linkplain} RegisterFlag#FPU floating point} parameters are being requested
66 * @return the ordered set of registers that may be used to pass parameters in a call conforming to {@code type}
53 */ 67 */
54 public final CiRegister[] allocatable; 68 CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag);
55 69
56 /** 70 /**
57 * The set of registers that can be used by the register allocator, 71 * Gets 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 */ 72 */
61 public final EnumMap<RegisterFlag, CiRegister[]> categorized; 73 CiRegister[] getAllocatableRegisters();
62 74
63 /** 75 /**
64 * The ordered set of registers used to pass integral arguments. 76 * Gets the set of registers that can be used by the register allocator,
77 * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register {@linkplain RegisterFlag flags}.
78 *
79 * @return a map from each {@link RegisterFlag} constant to the list of {@linkplain #getAllocatableRegisters()
80 * allocatable} registers for which the flag is {@linkplain #isSet(RegisterFlag) set}
81 *
65 */ 82 */
66 public final CiRegister[] cpuParameters; 83 EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters();
67 84
68 /** 85 /**
69 * The ordered set of registers used to pass floating point arguments. 86 * Gets the registers whose values must be preserved by a method across any call it makes.
70 */ 87 */
71 public final CiRegister[] fpuParameters; 88 CiRegister[] getCallerSaveRegisters();
72 89
73 /** 90 /**
74 * The caller saved registers. 91 * Gets the layout of the callee save area of this register configuration.
92 *
93 * @return {@code null} if there is no callee save area
75 */ 94 */
76 public final CiRegister[] callerSave; 95 CiCalleeSaveLayout getCalleeSaveLayout();
77 96
78 /** 97 /**
79 * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound. 98 * Gets a map from register {@linkplain CiRegister#number numbers} to register
99 * {@linkplain CiRegisterAttributes attributes} for this register configuration.
100 *
101 * @return an array where an element at index i holds the attributes of the register whose number is i
102 * @see CiRegister#categorize(CiRegister[])
80 */ 103 */
81 public final CiRegister frame; 104 CiRegisterAttributes[] getAttributesMap();
82 105
83 /** 106 /**
84 * Register for returning an integral value. 107 * Gets the register corresponding to a runtime-defined role.
108 *
109 * @param id the identifier of a runtime-defined register role
110 * @return the register playing the role specified by {@code id}
85 */ 111 */
86 public final CiRegister integralReturn; 112 CiRegister getRegisterForRole(int id);
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(RiKind 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, RiKind[] 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 RiKind 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 } 113 }