Mercurial > hg > truffle
comparison src/cpu/sparc/vm/sharedRuntime_sparc.cpp @ 20804:7848fc12602b
Merge with jdk8u40-b25
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Tue, 07 Apr 2015 14:58:49 +0200 |
parents | 33a783b15758 318cc6fdae90 |
children | 178a4927b95c |
comparison
equal
deleted
inserted
replaced
20184:84105dcdb05b | 20804:7848fc12602b |
---|---|
1152 #ifdef _LP64 | 1152 #ifdef _LP64 |
1153 // V9 convention: All things "as-if" on double-wide stack slots. | 1153 // V9 convention: All things "as-if" on double-wide stack slots. |
1154 // Hoist any int/ptr/long's in the first 6 to int regs. | 1154 // Hoist any int/ptr/long's in the first 6 to int regs. |
1155 // Hoist any flt/dbl's in the first 16 dbl regs. | 1155 // Hoist any flt/dbl's in the first 16 dbl regs. |
1156 int j = 0; // Count of actual args, not HALVES | 1156 int j = 0; // Count of actual args, not HALVES |
1157 for( int i=0; i<total_args_passed; i++, j++ ) { | 1157 VMRegPair param_array_reg; // location of the argument in the parameter array |
1158 switch( sig_bt[i] ) { | 1158 for (int i = 0; i < total_args_passed; i++, j++) { |
1159 param_array_reg.set_bad(); | |
1160 switch (sig_bt[i]) { | |
1159 case T_BOOLEAN: | 1161 case T_BOOLEAN: |
1160 case T_BYTE: | 1162 case T_BYTE: |
1161 case T_CHAR: | 1163 case T_CHAR: |
1162 case T_INT: | 1164 case T_INT: |
1163 case T_SHORT: | 1165 case T_SHORT: |
1164 regs[i].set1( int_stk_helper( j ) ); break; | 1166 regs[i].set1(int_stk_helper(j)); |
1167 break; | |
1165 case T_LONG: | 1168 case T_LONG: |
1166 assert( sig_bt[i+1] == T_VOID, "expecting half" ); | 1169 assert(sig_bt[i+1] == T_VOID, "expecting half"); |
1167 case T_ADDRESS: // raw pointers, like current thread, for VM calls | 1170 case T_ADDRESS: // raw pointers, like current thread, for VM calls |
1168 case T_ARRAY: | 1171 case T_ARRAY: |
1169 case T_OBJECT: | 1172 case T_OBJECT: |
1170 case T_METADATA: | 1173 case T_METADATA: |
1171 regs[i].set2( int_stk_helper( j ) ); | 1174 regs[i].set2(int_stk_helper(j)); |
1172 break; | 1175 break; |
1173 case T_FLOAT: | 1176 case T_FLOAT: |
1174 if ( j < 16 ) { | 1177 // Per SPARC Compliance Definition 2.4.1, page 3P-12 available here |
1175 // V9ism: floats go in ODD registers | 1178 // http://www.sparc.org/wp-content/uploads/2014/01/SCD.2.4.1.pdf.gz |
1176 regs[i].set1(as_FloatRegister(1 + (j<<1))->as_VMReg()); | 1179 // |
1177 } else { | 1180 // "When a callee prototype exists, and does not indicate variable arguments, |
1178 // V9ism: floats go in ODD stack slot | 1181 // floating-point values assigned to locations %sp+BIAS+128 through %sp+BIAS+248 |
1179 regs[i].set1(VMRegImpl::stack2reg(1 + (j<<1))); | 1182 // will be promoted to floating-point registers" |
1183 // | |
1184 // By "promoted" it means that the argument is located in two places, an unused | |
1185 // spill slot in the "parameter array" (starts at %sp+BIAS+128), and a live | |
1186 // float register. In most cases, there are 6 or fewer arguments of any type, | |
1187 // and the standard parameter array slots (%sp+BIAS+128 to %sp+BIAS+176 exclusive) | |
1188 // serve as shadow slots. Per the spec floating point registers %d6 to %d16 | |
1189 // require slots beyond that (up to %sp+BIAS+248). | |
1190 // | |
1191 { | |
1192 // V9ism: floats go in ODD registers and stack slots | |
1193 int float_index = 1 + (j << 1); | |
1194 param_array_reg.set1(VMRegImpl::stack2reg(float_index)); | |
1195 if (j < 16) { | |
1196 regs[i].set1(as_FloatRegister(float_index)->as_VMReg()); | |
1197 } else { | |
1198 regs[i] = param_array_reg; | |
1199 } | |
1180 } | 1200 } |
1181 break; | 1201 break; |
1182 case T_DOUBLE: | 1202 case T_DOUBLE: |
1183 assert( sig_bt[i+1] == T_VOID, "expecting half" ); | 1203 { |
1184 if ( j < 16 ) { | 1204 assert(sig_bt[i + 1] == T_VOID, "expecting half"); |
1185 // V9ism: doubles go in EVEN/ODD regs | 1205 // V9ism: doubles go in EVEN/ODD regs and stack slots |
1186 regs[i].set2(as_FloatRegister(j<<1)->as_VMReg()); | 1206 int double_index = (j << 1); |
1187 } else { | 1207 param_array_reg.set2(VMRegImpl::stack2reg(double_index)); |
1188 // V9ism: doubles go in EVEN/ODD stack slots | 1208 if (j < 16) { |
1189 regs[i].set2(VMRegImpl::stack2reg(j<<1)); | 1209 regs[i].set2(as_FloatRegister(double_index)->as_VMReg()); |
1210 } else { | |
1211 // V9ism: doubles go in EVEN/ODD stack slots | |
1212 regs[i] = param_array_reg; | |
1213 } | |
1190 } | 1214 } |
1191 break; | 1215 break; |
1192 case T_VOID: regs[i].set_bad(); j--; break; // Do not count HALVES | 1216 case T_VOID: |
1217 regs[i].set_bad(); | |
1218 j--; | |
1219 break; // Do not count HALVES | |
1193 default: | 1220 default: |
1194 ShouldNotReachHere(); | 1221 ShouldNotReachHere(); |
1195 } | 1222 } |
1196 if (regs[i].first()->is_stack()) { | 1223 // Keep track of the deepest parameter array slot. |
1197 int off = regs[i].first()->reg2stack(); | 1224 if (!param_array_reg.first()->is_valid()) { |
1225 param_array_reg = regs[i]; | |
1226 } | |
1227 if (param_array_reg.first()->is_stack()) { | |
1228 int off = param_array_reg.first()->reg2stack(); | |
1198 if (off > max_stack_slots) max_stack_slots = off; | 1229 if (off > max_stack_slots) max_stack_slots = off; |
1199 } | 1230 } |
1200 if (regs[i].second()->is_stack()) { | 1231 if (param_array_reg.second()->is_stack()) { |
1201 int off = regs[i].second()->reg2stack(); | 1232 int off = param_array_reg.second()->reg2stack(); |
1202 if (off > max_stack_slots) max_stack_slots = off; | 1233 if (off > max_stack_slots) max_stack_slots = off; |
1203 } | 1234 } |
1204 } | 1235 } |
1205 | 1236 |
1206 #else // _LP64 | 1237 #else // _LP64 |
1207 // V8 convention: first 6 things in O-regs, rest on stack. | 1238 // V8 convention: first 6 things in O-regs, rest on stack. |
1208 // Alignment is willy-nilly. | 1239 // Alignment is willy-nilly. |
1209 for( int i=0; i<total_args_passed; i++ ) { | 1240 for (int i = 0; i < total_args_passed; i++) { |
1210 switch( sig_bt[i] ) { | 1241 switch (sig_bt[i]) { |
1211 case T_ADDRESS: // raw pointers, like current thread, for VM calls | 1242 case T_ADDRESS: // raw pointers, like current thread, for VM calls |
1212 case T_ARRAY: | 1243 case T_ARRAY: |
1213 case T_BOOLEAN: | 1244 case T_BOOLEAN: |
1214 case T_BYTE: | 1245 case T_BYTE: |
1215 case T_CHAR: | 1246 case T_CHAR: |
1216 case T_FLOAT: | 1247 case T_FLOAT: |
1217 case T_INT: | 1248 case T_INT: |
1218 case T_OBJECT: | 1249 case T_OBJECT: |
1219 case T_METADATA: | 1250 case T_METADATA: |
1220 case T_SHORT: | 1251 case T_SHORT: |
1221 regs[i].set1( int_stk_helper( i ) ); | 1252 regs[i].set1(int_stk_helper(i)); |
1222 break; | 1253 break; |
1223 case T_DOUBLE: | 1254 case T_DOUBLE: |
1224 case T_LONG: | 1255 case T_LONG: |
1225 assert( sig_bt[i+1] == T_VOID, "expecting half" ); | 1256 assert(sig_bt[i + 1] == T_VOID, "expecting half"); |
1226 regs[i].set_pair( int_stk_helper( i+1 ), int_stk_helper( i ) ); | 1257 regs[i].set_pair(int_stk_helper(i + 1), int_stk_helper(i)); |
1227 break; | 1258 break; |
1228 case T_VOID: regs[i].set_bad(); break; | 1259 case T_VOID: regs[i].set_bad(); break; |
1229 default: | 1260 default: |
1230 ShouldNotReachHere(); | 1261 ShouldNotReachHere(); |
1231 } | 1262 } |
1232 if (regs[i].first()->is_stack()) { | 1263 if (regs[i].first()->is_stack()) { |
1233 int off = regs[i].first()->reg2stack(); | 1264 int off = regs[i].first()->reg2stack(); |
1234 if (off > max_stack_slots) max_stack_slots = off; | 1265 if (off > max_stack_slots) max_stack_slots = off; |
1235 } | 1266 } |
1236 if (regs[i].second()->is_stack()) { | 1267 if (regs[i].second()->is_stack()) { |
1237 int off = regs[i].second()->reg2stack(); | 1268 int off = regs[i].second()->reg2stack(); |
1238 if (off > max_stack_slots) max_stack_slots = off; | 1269 if (off > max_stack_slots) max_stack_slots = off; |
1239 } | 1270 } |
1240 } | 1271 } |
1241 #endif // _LP64 | 1272 #endif // _LP64 |
1242 | 1273 |
1381 } else { | 1412 } else { |
1382 // Oop is in an input register pass we must flush it to the stack | 1413 // Oop is in an input register pass we must flush it to the stack |
1383 const Register rOop = src.first()->as_Register(); | 1414 const Register rOop = src.first()->as_Register(); |
1384 const Register rHandle = L5; | 1415 const Register rHandle = L5; |
1385 int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset; | 1416 int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset; |
1386 int offset = oop_slot*VMRegImpl::stack_slot_size; | 1417 int offset = oop_slot * VMRegImpl::stack_slot_size; |
1387 Label skip; | |
1388 __ st_ptr(rOop, SP, offset + STACK_BIAS); | 1418 __ st_ptr(rOop, SP, offset + STACK_BIAS); |
1389 if (is_receiver) { | 1419 if (is_receiver) { |
1390 *receiver_offset = oop_slot * VMRegImpl::stack_slot_size; | 1420 *receiver_offset = offset; |
1391 } | 1421 } |
1392 map->set_oop(VMRegImpl::stack2reg(oop_slot)); | 1422 map->set_oop(VMRegImpl::stack2reg(oop_slot)); |
1393 __ add(SP, offset + STACK_BIAS, rHandle); | 1423 __ add(SP, offset + STACK_BIAS, rHandle); |
1394 #ifdef _LP64 | 1424 #ifdef _LP64 |
1395 __ movr( Assembler::rc_z, rOop, G0, rHandle ); | 1425 __ movr( Assembler::rc_z, rOop, G0, rHandle ); |