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 jdk.vm.ci.hotspot.sparc;
24
25 import static jdk.vm.ci.meta.JavaKind.Void;
26 import static jdk.vm.ci.meta.Value.ILLEGAL;
27 import static jdk.vm.ci.sparc.SPARC.REGISTER_SAFE_AREA_SIZE;
28 import static jdk.vm.ci.sparc.SPARC.d0;
29 import static jdk.vm.ci.sparc.SPARC.d2;
30 import static jdk.vm.ci.sparc.SPARC.d4;
31 import static jdk.vm.ci.sparc.SPARC.d6;
32 import static jdk.vm.ci.sparc.SPARC.f0;
33 import static jdk.vm.ci.sparc.SPARC.f1;
34 import static jdk.vm.ci.sparc.SPARC.f2;
35 import static jdk.vm.ci.sparc.SPARC.f3;
36 import static jdk.vm.ci.sparc.SPARC.f4;
37 import static jdk.vm.ci.sparc.SPARC.f5;
38 import static jdk.vm.ci.sparc.SPARC.f6;
39 import static jdk.vm.ci.sparc.SPARC.f7;
40 import static jdk.vm.ci.sparc.SPARC.g0;
41 import static jdk.vm.ci.sparc.SPARC.g2;
42 import static jdk.vm.ci.sparc.SPARC.g6;
43 import static jdk.vm.ci.sparc.SPARC.i0;
44 import static jdk.vm.ci.sparc.SPARC.i1;
45 import static jdk.vm.ci.sparc.SPARC.i2;
46 import static jdk.vm.ci.sparc.SPARC.i3;
47 import static jdk.vm.ci.sparc.SPARC.i4;
48 import static jdk.vm.ci.sparc.SPARC.i5;
49 import static jdk.vm.ci.sparc.SPARC.i6;
50 import static jdk.vm.ci.sparc.SPARC.i7;
51 import static jdk.vm.ci.sparc.SPARC.l0;
52 import static jdk.vm.ci.sparc.SPARC.l1;
53 import static jdk.vm.ci.sparc.SPARC.l2;
54 import static jdk.vm.ci.sparc.SPARC.l3;
55 import static jdk.vm.ci.sparc.SPARC.l4;
56 import static jdk.vm.ci.sparc.SPARC.l5;
57 import static jdk.vm.ci.sparc.SPARC.l6;
58 import static jdk.vm.ci.sparc.SPARC.l7;
59 import static jdk.vm.ci.sparc.SPARC.o0;
79 import jdk.vm.ci.code.StackSlot;
80 import jdk.vm.ci.code.TargetDescription;
81 import jdk.vm.ci.code.ValueKindFactory;
82 import jdk.vm.ci.common.JVMCIError;
83 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
84 import jdk.vm.ci.meta.AllocatableValue;
85 import jdk.vm.ci.meta.JavaKind;
86 import jdk.vm.ci.meta.JavaType;
87 import jdk.vm.ci.meta.PlatformKind;
88 import jdk.vm.ci.meta.ValueKind;
89 import jdk.vm.ci.sparc.SPARC;
90
91 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
92
93 private final TargetDescription target;
94
95 private final Register[] allocatable;
96
97 private final RegisterAttributes[] attributesMap;
98
99 /**
100 * Does native code (C++ code) spill arguments in registers to the parent frame?
101 */
102 private final boolean addNativeRegisterArgumentSlots;
103
104 @Override
105 public Register[] getAllocatableRegisters() {
106 return allocatable.clone();
107 }
108
109 @Override
110 public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
111 ArrayList<Register> list = new ArrayList<>();
112 for (Register reg : registers) {
113 if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
114 list.add(reg);
115 }
116 }
117 Register[] ret = list.toArray(new Register[list.size()]);
118 return ret;
119 }
120
121 @Override
122 public RegisterAttributes[] getAttributesMap() {
123 return attributesMap.clone();
124 }
125
126 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
127 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
128
129 private final Register[] fpuFloatParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
130 private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
131
132 // @formatter:off
133 private final Register[] callerSaveRegisters;
134
135 /**
136 * Registers saved by the callee. This lists all L and I registers which are saved in the
137 * register window.
138 */
139 private final Register[] calleeSaveRegisters = {
140 l0, l1, l2, l3, l4, l5, l6, l7,
141 i0, i1, i2, i3, i4, i5, i6, i7};
142 // @formatter:on
143
144 private static final Register[] reservedRegisters = {sp, g0, g2};
145
146 private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
147 Register[] allRegisters = arch.getAvailableValueRegisters();
148 Register[] registers = new Register[allRegisters.length - reservedRegisters.length - (reserveForHeapBase ? 1 : 0)];
149 List<Register> reservedRegistersList = Arrays.asList(reservedRegisters);
150
151 int idx = 0;
152 for (Register reg : allRegisters) {
156 }
157 if (reserveForHeapBase && reg.equals(g6)) {
158 // skip heap base register
159 continue;
160 }
161
162 registers[idx++] = reg;
163 }
164
165 assert idx == registers.length;
166 return registers;
167 }
168
169 public SPARCHotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops) {
170 this(target, initAllocatable(target.arch, useCompressedOops));
171 }
172
173 public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
174 this.target = target;
175 this.allocatable = allocatable.clone();
176 this.addNativeRegisterArgumentSlots = false;
177 HashSet<Register> callerSaveSet = new HashSet<>();
178 Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
179 for (Register cs : calleeSaveRegisters) {
180 callerSaveSet.remove(cs);
181 }
182 this.callerSaveRegisters = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
183 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
184 }
185
186 @Override
187 public Register[] getCallerSaveRegisters() {
188 return callerSaveRegisters;
189 }
190
191 public Register[] getCalleeSaveRegisters() {
192 return calleeSaveRegisters;
193 }
194
195 @Override
196 public boolean areAllAllocatableRegistersCallerSaved() {
206 if (type == HotSpotCallingConventionType.JavaCallee) {
207 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
208 }
209 throw JVMCIError.shouldNotReachHere();
210 }
211
212 @Override
213 public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
214 HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
215 switch (kind) {
216 case Boolean:
217 case Byte:
218 case Short:
219 case Char:
220 case Int:
221 case Long:
222 case Object:
223 return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
224 case Double:
225 case Float:
226 return fpuFloatParameterRegisters;
227 default:
228 throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
229 }
230 }
231
232 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
233 ValueKindFactory<?> valueKindFactory) {
234 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
235
236 int currentGeneral = 0;
237 int currentFloating = 0;
238 int currentStackOffset = 0;
239
240 for (int i = 0; i < parameterTypes.length; i++) {
241 final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
242
243 switch (kind) {
244 case Byte:
245 case Boolean:
246 case Short:
247 case Char:
248 case Int:
249 case Long:
250 case Object:
251 if (currentGeneral < generalParameterRegisters.length) {
252 Register register = generalParameterRegisters[currentGeneral++];
253 locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
254 }
255 break;
256 case Double:
257 if (currentFloating < fpuFloatParameterRegisters.length) {
258 if (currentFloating % 2 != 0) {
259 // Make register number even to be a double reg
260 currentFloating++;
261 }
262 Register register = fpuDoubleParameterRegisters[currentFloating];
263 currentFloating += 2; // Only every second is a double register
264 locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
265 }
266 break;
267 case Float:
268 if (currentFloating < fpuFloatParameterRegisters.length) {
269 Register register = fpuFloatParameterRegisters[currentFloating++];
270 locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
271 }
272 break;
273 default:
274 throw JVMCIError.shouldNotReachHere();
275 }
276
277 if (locations[i] == null) {
278 ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
279 // Stack slot is always aligned to its size in bytes but minimum wordsize
280 int typeSize = valueKind.getPlatformKind().getSizeInBytes();
281 currentStackOffset = roundUp(currentStackOffset, typeSize);
282 int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
283 locations[i] = StackSlot.get(valueKind, slotOffset, !type.out);
284 currentStackOffset += typeSize;
285 }
286 }
287
288 JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
289 AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
290
291 int outArgSpillArea;
292 if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
293 // Space for native callee which may spill our outgoing arguments
294 outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
295 } else {
296 outArgSpillArea = 0;
297 }
298 return new CallingConvention(currentStackOffset + outArgSpillArea, returnLocation, locations);
299 }
300
301 private static int roundUp(int number, int mod) {
302 return ((number + mod - 1) / mod) * mod;
303 }
304
305 @Override
306 public Register getReturnRegister(JavaKind kind) {
307 return getReturnRegister(kind, HotSpotCallingConventionType.JavaCallee);
308 }
309
310 private static Register getReturnRegister(JavaKind kind, HotSpotCallingConventionType type) {
311 switch (kind) {
312 case Boolean:
313 case Byte:
314 case Char:
315 case Short:
316 case Int:
317 case Long:
318 case Object:
|
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 jdk.vm.ci.hotspot.sparc;
24
25 import static jdk.vm.ci.meta.JavaKind.Void;
26 import static jdk.vm.ci.meta.Value.ILLEGAL;
27 import static jdk.vm.ci.sparc.SPARC.REGISTER_SAFE_AREA_SIZE;
28 import static jdk.vm.ci.sparc.SPARC.d0;
29 import static jdk.vm.ci.sparc.SPARC.d10;
30 import static jdk.vm.ci.sparc.SPARC.d12;
31 import static jdk.vm.ci.sparc.SPARC.d14;
32 import static jdk.vm.ci.sparc.SPARC.d16;
33 import static jdk.vm.ci.sparc.SPARC.d18;
34 import static jdk.vm.ci.sparc.SPARC.d2;
35 import static jdk.vm.ci.sparc.SPARC.d20;
36 import static jdk.vm.ci.sparc.SPARC.d22;
37 import static jdk.vm.ci.sparc.SPARC.d24;
38 import static jdk.vm.ci.sparc.SPARC.d26;
39 import static jdk.vm.ci.sparc.SPARC.d28;
40 import static jdk.vm.ci.sparc.SPARC.d30;
41 import static jdk.vm.ci.sparc.SPARC.d4;
42 import static jdk.vm.ci.sparc.SPARC.d6;
43 import static jdk.vm.ci.sparc.SPARC.d8;
44 import static jdk.vm.ci.sparc.SPARC.f0;
45 import static jdk.vm.ci.sparc.SPARC.f1;
46 import static jdk.vm.ci.sparc.SPARC.f11;
47 import static jdk.vm.ci.sparc.SPARC.f13;
48 import static jdk.vm.ci.sparc.SPARC.f15;
49 import static jdk.vm.ci.sparc.SPARC.f17;
50 import static jdk.vm.ci.sparc.SPARC.f19;
51 import static jdk.vm.ci.sparc.SPARC.f2;
52 import static jdk.vm.ci.sparc.SPARC.f21;
53 import static jdk.vm.ci.sparc.SPARC.f23;
54 import static jdk.vm.ci.sparc.SPARC.f25;
55 import static jdk.vm.ci.sparc.SPARC.f27;
56 import static jdk.vm.ci.sparc.SPARC.f29;
57 import static jdk.vm.ci.sparc.SPARC.f3;
58 import static jdk.vm.ci.sparc.SPARC.f31;
59 import static jdk.vm.ci.sparc.SPARC.f4;
60 import static jdk.vm.ci.sparc.SPARC.f5;
61 import static jdk.vm.ci.sparc.SPARC.f6;
62 import static jdk.vm.ci.sparc.SPARC.f7;
63 import static jdk.vm.ci.sparc.SPARC.f9;
64 import static jdk.vm.ci.sparc.SPARC.g0;
65 import static jdk.vm.ci.sparc.SPARC.g2;
66 import static jdk.vm.ci.sparc.SPARC.g6;
67 import static jdk.vm.ci.sparc.SPARC.i0;
68 import static jdk.vm.ci.sparc.SPARC.i1;
69 import static jdk.vm.ci.sparc.SPARC.i2;
70 import static jdk.vm.ci.sparc.SPARC.i3;
71 import static jdk.vm.ci.sparc.SPARC.i4;
72 import static jdk.vm.ci.sparc.SPARC.i5;
73 import static jdk.vm.ci.sparc.SPARC.i6;
74 import static jdk.vm.ci.sparc.SPARC.i7;
75 import static jdk.vm.ci.sparc.SPARC.l0;
76 import static jdk.vm.ci.sparc.SPARC.l1;
77 import static jdk.vm.ci.sparc.SPARC.l2;
78 import static jdk.vm.ci.sparc.SPARC.l3;
79 import static jdk.vm.ci.sparc.SPARC.l4;
80 import static jdk.vm.ci.sparc.SPARC.l5;
81 import static jdk.vm.ci.sparc.SPARC.l6;
82 import static jdk.vm.ci.sparc.SPARC.l7;
83 import static jdk.vm.ci.sparc.SPARC.o0;
103 import jdk.vm.ci.code.StackSlot;
104 import jdk.vm.ci.code.TargetDescription;
105 import jdk.vm.ci.code.ValueKindFactory;
106 import jdk.vm.ci.common.JVMCIError;
107 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
108 import jdk.vm.ci.meta.AllocatableValue;
109 import jdk.vm.ci.meta.JavaKind;
110 import jdk.vm.ci.meta.JavaType;
111 import jdk.vm.ci.meta.PlatformKind;
112 import jdk.vm.ci.meta.ValueKind;
113 import jdk.vm.ci.sparc.SPARC;
114
115 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
116
117 private final TargetDescription target;
118
119 private final Register[] allocatable;
120
121 private final RegisterAttributes[] attributesMap;
122
123 @Override
124 public Register[] getAllocatableRegisters() {
125 return allocatable.clone();
126 }
127
128 @Override
129 public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
130 ArrayList<Register> list = new ArrayList<>();
131 for (Register reg : registers) {
132 if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
133 list.add(reg);
134 }
135 }
136 Register[] ret = list.toArray(new Register[list.size()]);
137 return ret;
138 }
139
140 @Override
141 public RegisterAttributes[] getAttributesMap() {
142 return attributesMap.clone();
143 }
144
145 private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
146 private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
147
148 private final Register[] fpuFloatJavaParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
149 private final Register[] fpuDoubleJavaParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
150
151 // @formatter:off
152 private final Register[] fpuFloatNativeParameterRegisters = {
153 f1, f3, f5, f7, f9, f11, f13, f15,
154 f17, f19, f21, f23, f25, f27, f29, f31};
155
156 private final Register[] fpuDoubleNativeParameterRegisters = {
157 d0, d2, d4, d6, d8, d10, d12, d14,
158 d16, d18, d20, d22, d24, d26, d28, d30};
159
160 private final Register[] callerSaveRegisters;
161
162 /**
163 * Registers saved by the callee. This lists all L and I registers which are saved in the
164 * register window.
165 */
166 private final Register[] calleeSaveRegisters = {
167 l0, l1, l2, l3, l4, l5, l6, l7,
168 i0, i1, i2, i3, i4, i5, i6, i7};
169 // @formatter:on
170
171 private static final Register[] reservedRegisters = {sp, g0, g2};
172
173 private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
174 Register[] allRegisters = arch.getAvailableValueRegisters();
175 Register[] registers = new Register[allRegisters.length - reservedRegisters.length - (reserveForHeapBase ? 1 : 0)];
176 List<Register> reservedRegistersList = Arrays.asList(reservedRegisters);
177
178 int idx = 0;
179 for (Register reg : allRegisters) {
183 }
184 if (reserveForHeapBase && reg.equals(g6)) {
185 // skip heap base register
186 continue;
187 }
188
189 registers[idx++] = reg;
190 }
191
192 assert idx == registers.length;
193 return registers;
194 }
195
196 public SPARCHotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops) {
197 this(target, initAllocatable(target.arch, useCompressedOops));
198 }
199
200 public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
201 this.target = target;
202 this.allocatable = allocatable.clone();
203 HashSet<Register> callerSaveSet = new HashSet<>();
204 Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
205 for (Register cs : calleeSaveRegisters) {
206 callerSaveSet.remove(cs);
207 }
208 this.callerSaveRegisters = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
209 attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
210 }
211
212 @Override
213 public Register[] getCallerSaveRegisters() {
214 return callerSaveRegisters;
215 }
216
217 public Register[] getCalleeSaveRegisters() {
218 return calleeSaveRegisters;
219 }
220
221 @Override
222 public boolean areAllAllocatableRegistersCallerSaved() {
232 if (type == HotSpotCallingConventionType.JavaCallee) {
233 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
234 }
235 throw JVMCIError.shouldNotReachHere();
236 }
237
238 @Override
239 public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
240 HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
241 switch (kind) {
242 case Boolean:
243 case Byte:
244 case Short:
245 case Char:
246 case Int:
247 case Long:
248 case Object:
249 return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
250 case Double:
251 case Float:
252 return fpuFloatJavaParameterRegisters;
253 default:
254 throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
255 }
256 }
257
258 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
259 ValueKindFactory<?> valueKindFactory) {
260 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
261
262 int currentGeneral = 0;
263 int currentFloating = 0;
264 int currentStackOffset = 0;
265 boolean isNative = type == HotSpotCallingConventionType.NativeCall;
266
267 for (int i = 0; i < parameterTypes.length; i++) {
268 final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
269 if (isNative) {
270 Register[] registerSet;
271 switch (kind) {
272 case Byte:
273 case Boolean:
274 case Short:
275 case Char:
276 case Int:
277 case Long:
278 case Object:
279 registerSet = generalParameterRegisters;
280 break;
281 case Double:
282 registerSet = fpuDoubleNativeParameterRegisters;
283 break;
284 case Float:
285 registerSet = fpuFloatNativeParameterRegisters;
286 break;
287 default:
288 throw JVMCIError.shouldNotReachHere();
289 }
290 if (i < registerSet.length) {
291 locations[i] = registerSet[i].asValue(valueKindFactory.getValueKind(kind));
292 currentStackOffset += target.arch.getWordSize();
293 }
294 } else {
295 switch (kind) {
296 case Byte:
297 case Boolean:
298 case Short:
299 case Char:
300 case Int:
301 case Long:
302 case Object:
303 if (currentGeneral < generalParameterRegisters.length) {
304 Register register = generalParameterRegisters[currentGeneral++];
305 locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
306 }
307 break;
308 case Double:
309 if (currentFloating < fpuFloatJavaParameterRegisters.length) {
310 if (currentFloating % 2 != 0) {
311 // Make register number even to be a double reg
312 currentFloating++;
313 }
314 Register register = fpuDoubleJavaParameterRegisters[currentFloating];
315 currentFloating += 2; // Only every second is a double register
316 locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
317 }
318 break;
319 case Float:
320 if (currentFloating < fpuFloatJavaParameterRegisters.length) {
321 Register register = fpuFloatJavaParameterRegisters[currentFloating++];
322 locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
323 }
324 break;
325 default:
326 throw JVMCIError.shouldNotReachHere();
327 }
328 }
329
330 if (locations[i] == null) {
331 ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
332 int typeSize = valueKind.getPlatformKind().getSizeInBytes();
333 if (isNative) {
334 currentStackOffset += target.arch.getWordSize() - typeSize;
335 }
336 currentStackOffset = roundUp(currentStackOffset, typeSize);
337 int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
338 locations[i] = StackSlot.get(valueKind, slotOffset, !type.out);
339 currentStackOffset += typeSize;
340 }
341 }
342
343 JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
344 AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
345 return new CallingConvention(currentStackOffset, returnLocation, locations);
346 }
347
348 private static int roundUp(int number, int mod) {
349 return ((number + mod - 1) / mod) * mod;
350 }
351
352 @Override
353 public Register getReturnRegister(JavaKind kind) {
354 return getReturnRegister(kind, HotSpotCallingConventionType.JavaCallee);
355 }
356
357 private static Register getReturnRegister(JavaKind kind, HotSpotCallingConventionType type) {
358 switch (kind) {
359 case Boolean:
360 case Byte:
361 case Char:
362 case Short:
363 case Int:
364 case Long:
365 case Object:
|