< prev index next >
src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java
Print this page
rev 28792 : 8159368: [JVMCI] SPARChotSpotRegisterConfig.callingConvention gives incorrect calling convention for native calls containing fp args
rev 28793 : Take up comments from roland
@@ -24,21 +24,45 @@
import static jdk.vm.ci.meta.JavaKind.Void;
import static jdk.vm.ci.meta.Value.ILLEGAL;
import static jdk.vm.ci.sparc.SPARC.REGISTER_SAFE_AREA_SIZE;
import static jdk.vm.ci.sparc.SPARC.d0;
+import static jdk.vm.ci.sparc.SPARC.d10;
+import static jdk.vm.ci.sparc.SPARC.d12;
+import static jdk.vm.ci.sparc.SPARC.d14;
+import static jdk.vm.ci.sparc.SPARC.d16;
+import static jdk.vm.ci.sparc.SPARC.d18;
import static jdk.vm.ci.sparc.SPARC.d2;
+import static jdk.vm.ci.sparc.SPARC.d20;
+import static jdk.vm.ci.sparc.SPARC.d22;
+import static jdk.vm.ci.sparc.SPARC.d24;
+import static jdk.vm.ci.sparc.SPARC.d26;
+import static jdk.vm.ci.sparc.SPARC.d28;
+import static jdk.vm.ci.sparc.SPARC.d30;
import static jdk.vm.ci.sparc.SPARC.d4;
import static jdk.vm.ci.sparc.SPARC.d6;
+import static jdk.vm.ci.sparc.SPARC.d8;
import static jdk.vm.ci.sparc.SPARC.f0;
import static jdk.vm.ci.sparc.SPARC.f1;
+import static jdk.vm.ci.sparc.SPARC.f11;
+import static jdk.vm.ci.sparc.SPARC.f13;
+import static jdk.vm.ci.sparc.SPARC.f15;
+import static jdk.vm.ci.sparc.SPARC.f17;
+import static jdk.vm.ci.sparc.SPARC.f19;
import static jdk.vm.ci.sparc.SPARC.f2;
+import static jdk.vm.ci.sparc.SPARC.f21;
+import static jdk.vm.ci.sparc.SPARC.f23;
+import static jdk.vm.ci.sparc.SPARC.f25;
+import static jdk.vm.ci.sparc.SPARC.f27;
+import static jdk.vm.ci.sparc.SPARC.f29;
import static jdk.vm.ci.sparc.SPARC.f3;
+import static jdk.vm.ci.sparc.SPARC.f31;
import static jdk.vm.ci.sparc.SPARC.f4;
import static jdk.vm.ci.sparc.SPARC.f5;
import static jdk.vm.ci.sparc.SPARC.f6;
import static jdk.vm.ci.sparc.SPARC.f7;
+import static jdk.vm.ci.sparc.SPARC.f9;
import static jdk.vm.ci.sparc.SPARC.g0;
import static jdk.vm.ci.sparc.SPARC.g2;
import static jdk.vm.ci.sparc.SPARC.g6;
import static jdk.vm.ci.sparc.SPARC.i0;
import static jdk.vm.ci.sparc.SPARC.i1;
@@ -94,15 +118,10 @@
private final Register[] allocatable;
private final RegisterAttributes[] attributesMap;
- /**
- * Does native code (C++ code) spill arguments in registers to the parent frame?
- */
- private final boolean addNativeRegisterArgumentSlots;
-
@Override
public Register[] getAllocatableRegisters() {
return allocatable.clone();
}
@@ -124,14 +143,22 @@
}
private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
- private final Register[] fpuFloatParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
- private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
+ private final Register[] fpuFloatJavaParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
+ private final Register[] fpuDoubleJavaParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
// @formatter:off
+ private final Register[] fpuFloatNativeParameterRegisters = {
+ f1, f3, f5, f7, f9, f11, f13, f15,
+ f17, f19, f21, f23, f25, f27, f29, f31};
+
+ private final Register[] fpuDoubleNativeParameterRegisters = {
+ d0, d2, d4, d6, d8, d10, d12, d14,
+ d16, d18, d20, d22, d24, d26, d28, d30};
+
private final Register[] callerSaveRegisters;
/**
* Registers saved by the callee. This lists all L and I registers which are saved in the
* register window.
@@ -171,11 +198,10 @@
}
public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
this.target = target;
this.allocatable = allocatable.clone();
- this.addNativeRegisterArgumentSlots = false;
HashSet<Register> callerSaveSet = new HashSet<>();
Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
for (Register cs : calleeSaveRegisters) {
callerSaveSet.remove(cs);
}
@@ -221,11 +247,11 @@
case Long:
case Object:
return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
case Double:
case Float:
- return fpuFloatParameterRegisters;
+ return fpuFloatJavaParameterRegisters;
default:
throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
}
}
@@ -234,14 +260,40 @@
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
int currentFloating = 0;
int currentStackOffset = 0;
+ boolean isNative = type == HotSpotCallingConventionType.NativeCall;
for (int i = 0; i < parameterTypes.length; i++) {
final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
-
+ if (isNative) {
+ Register[] registerSet;
+ switch (kind) {
+ case Byte:
+ case Boolean:
+ case Short:
+ case Char:
+ case Int:
+ case Long:
+ case Object:
+ registerSet = generalParameterRegisters;
+ break;
+ case Double:
+ registerSet = fpuDoubleNativeParameterRegisters;
+ break;
+ case Float:
+ registerSet = fpuFloatNativeParameterRegisters;
+ break;
+ default:
+ throw JVMCIError.shouldNotReachHere();
+ }
+ if (i < registerSet.length) {
+ locations[i] = registerSet[i].asValue(valueKindFactory.getValueKind(kind));
+ currentStackOffset += target.arch.getWordSize();
+ }
+ } else {
switch (kind) {
case Byte:
case Boolean:
case Short:
case Char:
@@ -252,52 +304,47 @@
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Double:
- if (currentFloating < fpuFloatParameterRegisters.length) {
+ if (currentFloating < fpuFloatJavaParameterRegisters.length) {
if (currentFloating % 2 != 0) {
// Make register number even to be a double reg
currentFloating++;
}
- Register register = fpuDoubleParameterRegisters[currentFloating];
+ Register register = fpuDoubleJavaParameterRegisters[currentFloating];
currentFloating += 2; // Only every second is a double register
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Float:
- if (currentFloating < fpuFloatParameterRegisters.length) {
- Register register = fpuFloatParameterRegisters[currentFloating++];
+ if (currentFloating < fpuFloatJavaParameterRegisters.length) {
+ Register register = fpuFloatJavaParameterRegisters[currentFloating++];
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
default:
throw JVMCIError.shouldNotReachHere();
}
+ }
if (locations[i] == null) {
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
- // Stack slot is always aligned to its size in bytes but minimum wordsize
int typeSize = valueKind.getPlatformKind().getSizeInBytes();
+ if (isNative) {
+ currentStackOffset += target.arch.getWordSize() - typeSize;
+ }
currentStackOffset = roundUp(currentStackOffset, typeSize);
int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
locations[i] = StackSlot.get(valueKind, slotOffset, !type.out);
currentStackOffset += typeSize;
}
}
JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
-
- int outArgSpillArea;
- if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
- // Space for native callee which may spill our outgoing arguments
- outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
- } else {
- outArgSpillArea = 0;
- }
- return new CallingConvention(currentStackOffset + outArgSpillArea, returnLocation, locations);
+ return new CallingConvention(currentStackOffset, returnLocation, locations);
}
private static int roundUp(int number, int mod) {
return ((number + mod - 1) / mod) * mod;
}
< prev index next >