src/cpu/ppc/vm/sharedRuntime_ppc.cpp

Print this page

        

@@ -732,15 +732,12 @@
     case T_SHORT:
     case T_INT:
       // We must cast ints to longs and use full 64 bit stack slots
       // here. We do the cast in GraphKit::gen_stub() and just guard
       // here against loosing that change.
-      Unimplemented(); // TODO: PPC port
-      /*
       assert(SharedRuntime::c_calling_convention_requires_ints_as_longs(),
              "argument of type int should be promoted to type long");
-      */
       guarantee(i > 0 && sig_bt[i-1] == T_LONG,
                 "argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
                 "{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
       // Do not count halves.
       regs[i].set_bad();

@@ -828,10 +825,78 @@
 
   return round_to(stk, 2);
 }
 #endif // COMPILER2
 
+// Do we need to convert ints to longs for c calls?
+bool SharedRuntime::c_calling_convention_requires_ints_as_longs() {
+  return true;
+}
+
+// This is platform independent, but only needed on PPC64 so far.
+static int convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) {
+  assert(SharedRuntime::c_calling_convention_requires_ints_as_longs(), "");
+
+  int argcnt = in_args_count;
+  for (int in = 0; in < in_args_count; in++) {
+    BasicType bt = in_sig_bt[in];
+    switch (bt) {
+      case T_BOOLEAN:
+      case T_CHAR:
+      case T_BYTE:
+      case T_SHORT:
+      case T_INT:
+        argcnt++;
+        break;
+      default:
+        break;
+    }
+  }
+
+  return argcnt;
+}
+
+// This is platform independent, but only needed on PPC64 so far.
+static void convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
+                                     BasicType*& in_sig_bt, VMRegPair*& in_regs) {
+  assert(SharedRuntime::c_calling_convention_requires_ints_as_longs(), "");
+
+  VMRegPair *new_in_regs   = NEW_RESOURCE_ARRAY(VMRegPair, i2l_argcnt);
+  BasicType *new_in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
+
+  int argcnt = 0;
+  for (int in = 0; in < in_args_count; in++, argcnt++) {
+    BasicType bt  = in_sig_bt[in];
+    VMRegPair reg = in_regs[in];
+    switch (bt) {
+      case T_BOOLEAN:
+      case T_CHAR:
+      case T_BYTE:
+      case T_SHORT:
+      case T_INT:
+        // convert (bt) to (T_LONG,bt)
+        new_in_sig_bt[argcnt  ] = T_LONG;
+        new_in_sig_bt[argcnt+1] = bt;
+        assert(reg.first()->is_valid() && !reg.second()->is_valid(), "");
+        new_in_regs[argcnt  ].set2(reg.first());
+        new_in_regs[argcnt+1].set_bad();
+        argcnt++;
+        break;
+      default:
+        // no conversion needed
+        new_in_sig_bt[argcnt] = bt;
+        new_in_regs[argcnt]   = reg;
+        break;
+    }
+  }
+  assert(argcnt == i2l_argcnt, "must match");
+
+  in_regs = new_in_regs;
+  in_sig_bt = new_in_sig_bt;
+  in_args_count = i2l_argcnt;
+}
+
 static address gen_c2i_adapter(MacroAssembler *masm,
                             int total_args_passed,
                             int comp_args_on_stack,
                             const BasicType *sig_bt,
                             const VMRegPair *regs,