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