61 import static jdk.vm.ci.sparc.SPARC.o2;
62 import static jdk.vm.ci.sparc.SPARC.o3;
63 import static jdk.vm.ci.sparc.SPARC.o4;
64 import static jdk.vm.ci.sparc.SPARC.o5;
65 import static jdk.vm.ci.sparc.SPARC.sp;
66
67 import java.util.ArrayList;
68 import java.util.Arrays;
69 import java.util.Collections;
70 import java.util.HashSet;
71 import java.util.List;
72
73 import jdk.vm.ci.code.Architecture;
74 import jdk.vm.ci.code.CallingConvention;
75 import jdk.vm.ci.code.CallingConvention.Type;
76 import jdk.vm.ci.code.Register;
77 import jdk.vm.ci.code.RegisterAttributes;
78 import jdk.vm.ci.code.RegisterConfig;
79 import jdk.vm.ci.code.StackSlot;
80 import jdk.vm.ci.code.TargetDescription;
81 import jdk.vm.ci.common.JVMCIError;
82 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
83 import jdk.vm.ci.hotspot.HotSpotVMConfig;
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.LIRKind;
88 import jdk.vm.ci.meta.PlatformKind;
89 import jdk.vm.ci.sparc.SPARC;
90
91 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
92
93 private final Architecture architecture;
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 */
194
195 @Override
196 public boolean areAllAllocatableRegistersCallerSaved() {
197 return false;
198 }
199
200 @Override
201 public Register getRegisterForRole(int index) {
202 throw new UnsupportedOperationException();
203 }
204
205 @Override
206 public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
207 HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
208 if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
209 return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, target);
210 }
211 if (type == HotSpotCallingConventionType.JavaCallee) {
212 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
213 }
214 throw JVMCIError.shouldNotReachHere();
215 }
216
217 @Override
218 public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
219 HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
220 switch (kind) {
221 case Boolean:
222 case Byte:
223 case Short:
224 case Char:
225 case Int:
226 case Long:
227 case Object:
228 return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
229 case Double:
230 case Float:
231 return fpuFloatParameterRegisters;
232 default:
233 throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
234 }
235 }
236
237 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
238 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
239
240 int currentGeneral = 0;
241 int currentFloating = 0;
242 int currentStackOffset = 0;
243
244 for (int i = 0; i < parameterTypes.length; i++) {
245 final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
246
247 switch (kind) {
248 case Byte:
249 case Boolean:
250 case Short:
251 case Char:
252 case Int:
253 case Long:
258 }
259 break;
260 case Double:
261 if (currentFloating < fpuFloatParameterRegisters.length) {
262 if (currentFloating % 2 != 0) {
263 // Make register number even to be a double reg
264 currentFloating++;
265 }
266 Register register = fpuDoubleParameterRegisters[currentFloating];
267 currentFloating += 2; // Only every second is a double register
268 locations[i] = register.asValue(target.getLIRKind(kind));
269 }
270 break;
271 case Float:
272 if (currentFloating < fpuFloatParameterRegisters.length) {
273 Register register = fpuFloatParameterRegisters[currentFloating++];
274 locations[i] = register.asValue(target.getLIRKind(kind));
275 }
276 break;
277 default:
278 throw JVMCIError.shouldNotReachHere();
279 }
280
281 if (locations[i] == null) {
282 LIRKind lirKind = target.getLIRKind(kind);
283 // Stack slot is always aligned to its size in bytes but minimum wordsize
284 int typeSize = lirKind.getPlatformKind().getSizeInBytes();
285 currentStackOffset = roundUp(currentStackOffset, typeSize);
286 int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
287 locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
288 currentStackOffset += typeSize;
289 }
290 }
291
292 JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
293 AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
294
295 int outArgSpillArea;
296 if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
297 // Space for native callee which may spill our outgoing arguments
298 outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
|
61 import static jdk.vm.ci.sparc.SPARC.o2;
62 import static jdk.vm.ci.sparc.SPARC.o3;
63 import static jdk.vm.ci.sparc.SPARC.o4;
64 import static jdk.vm.ci.sparc.SPARC.o5;
65 import static jdk.vm.ci.sparc.SPARC.sp;
66
67 import java.util.ArrayList;
68 import java.util.Arrays;
69 import java.util.Collections;
70 import java.util.HashSet;
71 import java.util.List;
72
73 import jdk.vm.ci.code.Architecture;
74 import jdk.vm.ci.code.CallingConvention;
75 import jdk.vm.ci.code.CallingConvention.Type;
76 import jdk.vm.ci.code.Register;
77 import jdk.vm.ci.code.RegisterAttributes;
78 import jdk.vm.ci.code.RegisterConfig;
79 import jdk.vm.ci.code.StackSlot;
80 import jdk.vm.ci.code.TargetDescription;
81 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
82 import jdk.vm.ci.hotspot.HotSpotVMConfig;
83 import jdk.vm.ci.meta.AllocatableValue;
84 import jdk.vm.ci.meta.JavaKind;
85 import jdk.vm.ci.meta.JavaType;
86 import jdk.vm.ci.meta.LIRKind;
87 import jdk.vm.ci.meta.PlatformKind;
88 import jdk.vm.ci.sparc.SPARC;
89
90 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
91
92 private final Architecture architecture;
93
94 private final Register[] allocatable;
95
96 private final RegisterAttributes[] attributesMap;
97
98 /**
99 * Does native code (C++ code) spill arguments in registers to the parent frame?
100 */
193
194 @Override
195 public boolean areAllAllocatableRegistersCallerSaved() {
196 return false;
197 }
198
199 @Override
200 public Register getRegisterForRole(int index) {
201 throw new UnsupportedOperationException();
202 }
203
204 @Override
205 public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
206 HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
207 if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
208 return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, target);
209 }
210 if (type == HotSpotCallingConventionType.JavaCallee) {
211 return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
212 }
213 throw new InternalError("should not reach here");
214 }
215
216 @Override
217 public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
218 HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
219 switch (kind) {
220 case Boolean:
221 case Byte:
222 case Short:
223 case Char:
224 case Int:
225 case Long:
226 case Object:
227 return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
228 case Double:
229 case Float:
230 return fpuFloatParameterRegisters;
231 default:
232 throw new InternalError("Unknown JavaKind " + kind);
233 }
234 }
235
236 private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
237 AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
238
239 int currentGeneral = 0;
240 int currentFloating = 0;
241 int currentStackOffset = 0;
242
243 for (int i = 0; i < parameterTypes.length; i++) {
244 final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
245
246 switch (kind) {
247 case Byte:
248 case Boolean:
249 case Short:
250 case Char:
251 case Int:
252 case Long:
257 }
258 break;
259 case Double:
260 if (currentFloating < fpuFloatParameterRegisters.length) {
261 if (currentFloating % 2 != 0) {
262 // Make register number even to be a double reg
263 currentFloating++;
264 }
265 Register register = fpuDoubleParameterRegisters[currentFloating];
266 currentFloating += 2; // Only every second is a double register
267 locations[i] = register.asValue(target.getLIRKind(kind));
268 }
269 break;
270 case Float:
271 if (currentFloating < fpuFloatParameterRegisters.length) {
272 Register register = fpuFloatParameterRegisters[currentFloating++];
273 locations[i] = register.asValue(target.getLIRKind(kind));
274 }
275 break;
276 default:
277 throw new InternalError("should not reach here");
278 }
279
280 if (locations[i] == null) {
281 LIRKind lirKind = target.getLIRKind(kind);
282 // Stack slot is always aligned to its size in bytes but minimum wordsize
283 int typeSize = lirKind.getPlatformKind().getSizeInBytes();
284 currentStackOffset = roundUp(currentStackOffset, typeSize);
285 int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
286 locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
287 currentStackOffset += typeSize;
288 }
289 }
290
291 JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
292 AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
293
294 int outArgSpillArea;
295 if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
296 // Space for native callee which may spill our outgoing arguments
297 outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
|