< 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,44 ****
--- 24,68 ----
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,108 ****
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();
}
--- 118,127 ----
*** 124,137 ****
}
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};
// @formatter:off
private final Register[] callerSaveRegisters;
/**
* Registers saved by the callee. This lists all L and I registers which are saved in the
* register window.
--- 143,164 ----
}
private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
! 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,181 ****
}
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);
}
--- 198,207 ----
*** 221,231 ****
case Long:
case Object:
return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
case Double:
case Float:
! return fpuFloatParameterRegisters;
default:
throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
}
}
--- 247,257 ----
case Long:
case Object:
return hotspotType == HotSpotCallingConventionType.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
case Double:
case Float:
! return fpuFloatJavaParameterRegisters;
default:
throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
}
}
*** 234,247 ****
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
int currentFloating = 0;
int currentStackOffset = 0;
for (int i = 0; i < parameterTypes.length; i++) {
final JavaKind kind = parameterTypes[i].getJavaKind().getStackKind();
!
switch (kind) {
case Byte:
case Boolean:
case Short:
case Char:
--- 260,299 ----
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,303 ****
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Double:
! if (currentFloating < fpuFloatParameterRegisters.length) {
if (currentFloating % 2 != 0) {
// Make register number even to be a double reg
currentFloating++;
}
! Register register = fpuDoubleParameterRegisters[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++];
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();
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);
}
private static int roundUp(int number, int mod) {
return ((number + mod - 1) / mod) * mod;
}
--- 304,350 ----
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Double:
! if (currentFloating < fpuFloatJavaParameterRegisters.length) {
if (currentFloating % 2 != 0) {
// Make register number even to be a double reg
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 < 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);
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()));
! return new CallingConvention(currentStackOffset, returnLocation, locations);
}
private static int roundUp(int number, int mod) {
return ((number + mod - 1) / mod) * mod;
}
< prev index next >