src/cpu/sparc/vm/sharedRuntime_sparc.cpp

changeset 7210
318cc6fdae90
parent 6723
0bf37f737702
child 7535
7ae4e26cb1e0
child 8313
c66164388d38
     1.1 --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Sep 08 17:47:43 2014 +0200
     1.2 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Sep 18 11:46:33 2014 -0700
     1.3 @@ -1128,51 +1128,82 @@
     1.4      // Hoist any int/ptr/long's in the first 6 to int regs.
     1.5      // Hoist any flt/dbl's in the first 16 dbl regs.
     1.6      int j = 0;                  // Count of actual args, not HALVES
     1.7 -    for( int i=0; i<total_args_passed; i++, j++ ) {
     1.8 -      switch( sig_bt[i] ) {
     1.9 +    VMRegPair param_array_reg;  // location of the argument in the parameter array
    1.10 +    for (int i = 0; i < total_args_passed; i++, j++) {
    1.11 +      param_array_reg.set_bad();
    1.12 +      switch (sig_bt[i]) {
    1.13        case T_BOOLEAN:
    1.14        case T_BYTE:
    1.15        case T_CHAR:
    1.16        case T_INT:
    1.17        case T_SHORT:
    1.18 -        regs[i].set1( int_stk_helper( j ) ); break;
    1.19 +        regs[i].set1(int_stk_helper(j));
    1.20 +        break;
    1.21        case T_LONG:
    1.22 -        assert( sig_bt[i+1] == T_VOID, "expecting half" );
    1.23 +        assert(sig_bt[i+1] == T_VOID, "expecting half");
    1.24        case T_ADDRESS: // raw pointers, like current thread, for VM calls
    1.25        case T_ARRAY:
    1.26        case T_OBJECT:
    1.27        case T_METADATA:
    1.28 -        regs[i].set2( int_stk_helper( j ) );
    1.29 +        regs[i].set2(int_stk_helper(j));
    1.30          break;
    1.31        case T_FLOAT:
    1.32 -        if ( j < 16 ) {
    1.33 -          // V9ism: floats go in ODD registers
    1.34 -          regs[i].set1(as_FloatRegister(1 + (j<<1))->as_VMReg());
    1.35 -        } else {
    1.36 -          // V9ism: floats go in ODD stack slot
    1.37 -          regs[i].set1(VMRegImpl::stack2reg(1 + (j<<1)));
    1.38 +        // Per SPARC Compliance Definition 2.4.1, page 3P-12 available here
    1.39 +        // http://www.sparc.org/wp-content/uploads/2014/01/SCD.2.4.1.pdf.gz
    1.40 +        //
    1.41 +        // "When a callee prototype exists, and does not indicate variable arguments,
    1.42 +        // floating-point values assigned to locations %sp+BIAS+128 through %sp+BIAS+248
    1.43 +        // will be promoted to floating-point registers"
    1.44 +        //
    1.45 +        // By "promoted" it means that the argument is located in two places, an unused
    1.46 +        // spill slot in the "parameter array" (starts at %sp+BIAS+128), and a live
    1.47 +        // float register.  In most cases, there are 6 or fewer arguments of any type,
    1.48 +        // and the standard parameter array slots (%sp+BIAS+128 to %sp+BIAS+176 exclusive)
    1.49 +        // serve as shadow slots.  Per the spec floating point registers %d6 to %d16
    1.50 +        // require slots beyond that (up to %sp+BIAS+248).
    1.51 +        //
    1.52 +        {
    1.53 +          // V9ism: floats go in ODD registers and stack slots
    1.54 +          int float_index = 1 + (j << 1);
    1.55 +          param_array_reg.set1(VMRegImpl::stack2reg(float_index));
    1.56 +          if (j < 16) {
    1.57 +            regs[i].set1(as_FloatRegister(float_index)->as_VMReg());
    1.58 +          } else {
    1.59 +            regs[i] = param_array_reg;
    1.60 +          }
    1.61          }
    1.62          break;
    1.63        case T_DOUBLE:
    1.64 -        assert( sig_bt[i+1] == T_VOID, "expecting half" );
    1.65 -        if ( j < 16 ) {
    1.66 -          // V9ism: doubles go in EVEN/ODD regs
    1.67 -          regs[i].set2(as_FloatRegister(j<<1)->as_VMReg());
    1.68 -        } else {
    1.69 -          // V9ism: doubles go in EVEN/ODD stack slots
    1.70 -          regs[i].set2(VMRegImpl::stack2reg(j<<1));
    1.71 +        {
    1.72 +          assert(sig_bt[i + 1] == T_VOID, "expecting half");
    1.73 +          // V9ism: doubles go in EVEN/ODD regs and stack slots
    1.74 +          int double_index = (j << 1);
    1.75 +          param_array_reg.set2(VMRegImpl::stack2reg(double_index));
    1.76 +          if (j < 16) {
    1.77 +            regs[i].set2(as_FloatRegister(double_index)->as_VMReg());
    1.78 +          } else {
    1.79 +            // V9ism: doubles go in EVEN/ODD stack slots
    1.80 +            regs[i] = param_array_reg;
    1.81 +          }
    1.82          }
    1.83          break;
    1.84 -      case T_VOID:  regs[i].set_bad(); j--; break; // Do not count HALVES
    1.85 +      case T_VOID:
    1.86 +        regs[i].set_bad();
    1.87 +        j--;
    1.88 +        break; // Do not count HALVES
    1.89        default:
    1.90          ShouldNotReachHere();
    1.91        }
    1.92 -      if (regs[i].first()->is_stack()) {
    1.93 -        int off =  regs[i].first()->reg2stack();
    1.94 +      // Keep track of the deepest parameter array slot.
    1.95 +      if (!param_array_reg.first()->is_valid()) {
    1.96 +        param_array_reg = regs[i];
    1.97 +      }
    1.98 +      if (param_array_reg.first()->is_stack()) {
    1.99 +        int off = param_array_reg.first()->reg2stack();
   1.100          if (off > max_stack_slots) max_stack_slots = off;
   1.101        }
   1.102 -      if (regs[i].second()->is_stack()) {
   1.103 -        int off =  regs[i].second()->reg2stack();
   1.104 +      if (param_array_reg.second()->is_stack()) {
   1.105 +        int off = param_array_reg.second()->reg2stack();
   1.106          if (off > max_stack_slots) max_stack_slots = off;
   1.107        }
   1.108      }
   1.109 @@ -1180,8 +1211,8 @@
   1.110  #else // _LP64
   1.111      // V8 convention: first 6 things in O-regs, rest on stack.
   1.112      // Alignment is willy-nilly.
   1.113 -    for( int i=0; i<total_args_passed; i++ ) {
   1.114 -      switch( sig_bt[i] ) {
   1.115 +    for (int i = 0; i < total_args_passed; i++) {
   1.116 +      switch (sig_bt[i]) {
   1.117        case T_ADDRESS: // raw pointers, like current thread, for VM calls
   1.118        case T_ARRAY:
   1.119        case T_BOOLEAN:
   1.120 @@ -1192,23 +1223,23 @@
   1.121        case T_OBJECT:
   1.122        case T_METADATA:
   1.123        case T_SHORT:
   1.124 -        regs[i].set1( int_stk_helper( i ) );
   1.125 +        regs[i].set1(int_stk_helper(i));
   1.126          break;
   1.127        case T_DOUBLE:
   1.128        case T_LONG:
   1.129 -        assert( sig_bt[i+1] == T_VOID, "expecting half" );
   1.130 -        regs[i].set_pair( int_stk_helper( i+1 ), int_stk_helper( i ) );
   1.131 +        assert(sig_bt[i + 1] == T_VOID, "expecting half");
   1.132 +        regs[i].set_pair(int_stk_helper(i + 1), int_stk_helper(i));
   1.133          break;
   1.134        case T_VOID: regs[i].set_bad(); break;
   1.135        default:
   1.136          ShouldNotReachHere();
   1.137        }
   1.138        if (regs[i].first()->is_stack()) {
   1.139 -        int off =  regs[i].first()->reg2stack();
   1.140 +        int off = regs[i].first()->reg2stack();
   1.141          if (off > max_stack_slots) max_stack_slots = off;
   1.142        }
   1.143        if (regs[i].second()->is_stack()) {
   1.144 -        int off =  regs[i].second()->reg2stack();
   1.145 +        int off = regs[i].second()->reg2stack();
   1.146          if (off > max_stack_slots) max_stack_slots = off;
   1.147        }
   1.148      }
   1.149 @@ -1357,11 +1388,10 @@
   1.150      const Register rOop = src.first()->as_Register();
   1.151      const Register rHandle = L5;
   1.152      int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset;
   1.153 -    int offset = oop_slot*VMRegImpl::stack_slot_size;
   1.154 -    Label skip;
   1.155 +    int offset = oop_slot * VMRegImpl::stack_slot_size;
   1.156      __ st_ptr(rOop, SP, offset + STACK_BIAS);
   1.157      if (is_receiver) {
   1.158 -      *receiver_offset = oop_slot * VMRegImpl::stack_slot_size;
   1.159 +       *receiver_offset = offset;
   1.160      }
   1.161      map->set_oop(VMRegImpl::stack2reg(oop_slot));
   1.162      __ add(SP, offset + STACK_BIAS, rHandle);

mercurial