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