< 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 >