Mercurial > hg > truffle
comparison src/cpu/sparc/vm/cppInterpreter_sparc.cpp @ 123:9e5a7340635e
6688137: c++ interpreter fails on 64bit sparc
Summary: Misc. 64bit and endian fixes for sparc
Reviewed-by: never, kvn, rasbold
Contributed-by: volker.simonis@gmail.com
author | sgoldman |
---|---|
date | Thu, 17 Apr 2008 07:16:03 -0700 |
parents | a61af66fc99e |
children | d1605aabd0a1 |
comparison
equal
deleted
inserted
replaced
119:d1a5218d7eaf | 123:9e5a7340635e |
---|---|
157 __ st(O0, L1_scratch, 0); | 157 __ st(O0, L1_scratch, 0); |
158 __ sub(L1_scratch, wordSize, L1_scratch); | 158 __ sub(L1_scratch, wordSize, L1_scratch); |
159 break; | 159 break; |
160 case T_LONG : | 160 case T_LONG : |
161 #ifndef _LP64 | 161 #ifndef _LP64 |
162 #if !defined(_LP64) && defined(COMPILER2) | 162 #if defined(COMPILER2) |
163 // All return values are where we want them, except for Longs. C2 returns | 163 // All return values are where we want them, except for Longs. C2 returns |
164 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. | 164 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. |
165 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit | 165 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit |
166 // build even if we are returning from interpreted we just do a little | 166 // build even if we are returning from interpreted we just do a little |
167 // stupid shuffing. | 167 // stupid shuffing. |
171 __ stx(G1, L1_scratch, -wordSize); | 171 __ stx(G1, L1_scratch, -wordSize); |
172 #else | 172 #else |
173 // native result is in O0, O1 | 173 // native result is in O0, O1 |
174 __ st(O1, L1_scratch, 0); // Low order | 174 __ st(O1, L1_scratch, 0); // Low order |
175 __ st(O0, L1_scratch, -wordSize); // High order | 175 __ st(O0, L1_scratch, -wordSize); // High order |
176 #endif /* !_LP64 && COMPILER2 */ | 176 #endif /* COMPILER2 */ |
177 #else | 177 #else |
178 __ stx(O0, L1_scratch, 0); | 178 __ stx(O0, L1_scratch, -wordSize); |
179 __ breakpoint_trap(); | |
180 #endif | 179 #endif |
181 __ sub(L1_scratch, 2*wordSize, L1_scratch); | 180 __ sub(L1_scratch, 2*wordSize, L1_scratch); |
182 break; | 181 break; |
183 | 182 |
184 case T_INT : | 183 case T_INT : |
235 address entry = __ pc(); | 234 address entry = __ pc(); |
236 switch (type) { | 235 switch (type) { |
237 case T_VOID: break; | 236 case T_VOID: break; |
238 break; | 237 break; |
239 case T_FLOAT : | 238 case T_FLOAT : |
240 __ breakpoint_trap(Assembler::zero); | |
241 case T_BOOLEAN: | 239 case T_BOOLEAN: |
242 case T_CHAR : | 240 case T_CHAR : |
243 case T_BYTE : | 241 case T_BYTE : |
244 case T_SHORT : | 242 case T_SHORT : |
245 case T_INT : | 243 case T_INT : |
253 // return top two words on current expression stack to caller's expression stack | 251 // return top two words on current expression stack to caller's expression stack |
254 // The caller's expression stack is adjacent to the current frame manager's intepretState | 252 // The caller's expression stack is adjacent to the current frame manager's intepretState |
255 // except we allocated one extra word for this intepretState so we won't overwrite it | 253 // except we allocated one extra word for this intepretState so we won't overwrite it |
256 // when we return a two word result. | 254 // when we return a two word result. |
257 #ifdef _LP64 | 255 #ifdef _LP64 |
258 __ breakpoint_trap(); | |
259 // Hmm now that longs are in one entry should "_ptr" really be "x"? | |
260 __ ld_ptr(O0, 0, O2); | 256 __ ld_ptr(O0, 0, O2); |
261 __ ld_ptr(O0, wordSize, O3); | |
262 __ st_ptr(O3, O1, 0); | |
263 __ st_ptr(O2, O1, -wordSize); | 257 __ st_ptr(O2, O1, -wordSize); |
264 #else | 258 #else |
265 __ ld(O0, 0, O2); | 259 __ ld(O0, 0, O2); |
266 __ ld(O0, wordSize, O3); | 260 __ ld(O0, wordSize, O3); |
267 __ st(O3, O1, 0); | 261 __ st(O3, O1, 0); |
317 // return top two words on current expression stack to caller's expression stack | 311 // return top two words on current expression stack to caller's expression stack |
318 // The caller's expression stack is adjacent to the current frame manager's interpretState | 312 // The caller's expression stack is adjacent to the current frame manager's interpretState |
319 // except we allocated one extra word for this intepretState so we won't overwrite it | 313 // except we allocated one extra word for this intepretState so we won't overwrite it |
320 // when we return a two word result. | 314 // when we return a two word result. |
321 #ifdef _LP64 | 315 #ifdef _LP64 |
322 __ breakpoint_trap(); | |
323 // Hmm now that longs are in one entry should "_ptr" really be "x"? | |
324 __ ld_ptr(O0, 0, O0->after_save()); | 316 __ ld_ptr(O0, 0, O0->after_save()); |
325 __ ld_ptr(O0, wordSize, O1->after_save()); | |
326 #else | 317 #else |
327 __ ld(O0, wordSize, O1->after_save()); | 318 __ ld(O0, wordSize, O1->after_save()); |
328 __ ld(O0, 0, O0->after_save()); | 319 __ ld(O0, 0, O0->after_save()); |
329 #endif | 320 #endif |
330 #if defined(COMPILER2) && !defined(_LP64) | 321 #if defined(COMPILER2) && !defined(_LP64) |
1371 __ cmp(L1_scratch, L4_scratch); | 1362 __ cmp(L1_scratch, L4_scratch); |
1372 __ br(Assembler::notEqual, false, Assembler::pt, loop); | 1363 __ br(Assembler::notEqual, false, Assembler::pt, loop); |
1373 __ delayed()->ld_ptr(L1_scratch, entry_size, L3_scratch); | 1364 __ delayed()->ld_ptr(L1_scratch, entry_size, L3_scratch); |
1374 | 1365 |
1375 // now zero the slot so we can find it. | 1366 // now zero the slot so we can find it. |
1376 __ st(G0, L4_scratch, BasicObjectLock::obj_offset_in_bytes()); | 1367 __ st_ptr(G0, L4_scratch, BasicObjectLock::obj_offset_in_bytes()); |
1377 | 1368 |
1378 } | 1369 } |
1379 | 1370 |
1380 // Initial entry to C++ interpreter from the call_stub. | 1371 // Initial entry to C++ interpreter from the call_stub. |
1381 // This entry point is called the frame manager since it handles the generation | 1372 // This entry point is called the frame manager since it handles the generation |
1711 __ ld_ptr(STATE(_result._to_call._callee), L4_scratch); // called method | 1702 __ ld_ptr(STATE(_result._to_call._callee), L4_scratch); // called method |
1712 __ ld_ptr(STATE(_stack), L1_scratch); // get top of java expr stack | 1703 __ ld_ptr(STATE(_stack), L1_scratch); // get top of java expr stack |
1713 __ lduh(L4_scratch, in_bytes(methodOopDesc::size_of_parameters_offset()), L2_scratch); // get parameter size | 1704 __ lduh(L4_scratch, in_bytes(methodOopDesc::size_of_parameters_offset()), L2_scratch); // get parameter size |
1714 __ sll(L2_scratch, LogBytesPerWord, L2_scratch ); // parameter size in bytes | 1705 __ sll(L2_scratch, LogBytesPerWord, L2_scratch ); // parameter size in bytes |
1715 __ add(L1_scratch, L2_scratch, L1_scratch); // stack destination for result | 1706 __ add(L1_scratch, L2_scratch, L1_scratch); // stack destination for result |
1716 __ ld_ptr(L4_scratch, in_bytes(methodOopDesc::result_index_offset()), L3_scratch); // called method result type index | 1707 __ ld(L4_scratch, in_bytes(methodOopDesc::result_index_offset()), L3_scratch); // called method result type index |
1717 | 1708 |
1718 // tosca is really just native abi | 1709 // tosca is really just native abi |
1719 __ set((intptr_t)CppInterpreter::_tosca_to_stack, L4_scratch); | 1710 __ set((intptr_t)CppInterpreter::_tosca_to_stack, L4_scratch); |
1720 __ sll(L3_scratch, LogBytesPerWord, L3_scratch); | 1711 __ sll(L3_scratch, LogBytesPerWord, L3_scratch); |
1721 __ ld_ptr(L4_scratch, L3_scratch, Lscratch); // get typed result converter address | 1712 __ ld_ptr(L4_scratch, L3_scratch, Lscratch); // get typed result converter address |
1755 // other thing that makes it easy is that the top of the caller's stack is stored in STATE(_locals) | 1746 // other thing that makes it easy is that the top of the caller's stack is stored in STATE(_locals) |
1756 // for the current activation | 1747 // for the current activation |
1757 | 1748 |
1758 __ ld_ptr(STATE(_prev_link), L1_scratch); | 1749 __ ld_ptr(STATE(_prev_link), L1_scratch); |
1759 __ ld_ptr(STATE(_method), L2_scratch); // get method just executed | 1750 __ ld_ptr(STATE(_method), L2_scratch); // get method just executed |
1760 __ ld_ptr(L2_scratch, in_bytes(methodOopDesc::result_index_offset()), L2_scratch); | 1751 __ ld(L2_scratch, in_bytes(methodOopDesc::result_index_offset()), L2_scratch); |
1761 __ tst(L1_scratch); | 1752 __ tst(L1_scratch); |
1762 __ brx(Assembler::zero, false, Assembler::pt, return_to_initial_caller); | 1753 __ brx(Assembler::zero, false, Assembler::pt, return_to_initial_caller); |
1763 __ delayed()->sll(L2_scratch, LogBytesPerWord, L2_scratch); | 1754 __ delayed()->sll(L2_scratch, LogBytesPerWord, L2_scratch); |
1764 | 1755 |
1765 // Copy result to callers java stack | 1756 // Copy result to callers java stack |
1921 __ ld_ptr(STATE(_stack_limit), L1_scratch); | 1912 __ ld_ptr(STATE(_stack_limit), L1_scratch); |
1922 | 1913 |
1923 // compute the unused java stack size | 1914 // compute the unused java stack size |
1924 __ sub(Gargs, L1_scratch, L2_scratch); // compute unused space | 1915 __ sub(Gargs, L1_scratch, L2_scratch); // compute unused space |
1925 | 1916 |
1926 // Round down the unused space to that stack is always aligned | 1917 // Round down the unused space to that stack is always 16-byte aligned |
1927 // by making the unused space a multiple of the size of a long. | 1918 // by making the unused space a multiple of the size of two longs. |
1928 | 1919 |
1929 __ and3(L2_scratch, -BytesPerLong, L2_scratch); | 1920 __ and3(L2_scratch, -2*BytesPerLong, L2_scratch); |
1930 | 1921 |
1931 // Now trim the stack | 1922 // Now trim the stack |
1932 __ add(SP, L2_scratch, SP); | 1923 __ add(SP, L2_scratch, SP); |
1933 | 1924 |
1934 | 1925 |
2174 if (interpreter_frame != NULL) { | 2165 if (interpreter_frame != NULL) { |
2175 | 2166 |
2176 // MUCHO HACK | 2167 // MUCHO HACK |
2177 | 2168 |
2178 intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words); | 2169 intptr_t* frame_bottom = interpreter_frame->sp() - (full_frame_words - frame_words); |
2170 // 'interpreter_frame->sp()' is unbiased while 'frame_bottom' must be a biased value in 64bit mode. | |
2171 assert(((intptr_t)frame_bottom & 0xf) == 0, "SP biased in layout_activation"); | |
2172 frame_bottom = (intptr_t*)((intptr_t)frame_bottom - STACK_BIAS); | |
2179 | 2173 |
2180 /* Now fillin the interpreterState object */ | 2174 /* Now fillin the interpreterState object */ |
2181 | 2175 |
2182 interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); | 2176 interpreterState cur_state = (interpreterState) ((intptr_t)interpreter_frame->fp() - sizeof(BytecodeInterpreter)); |
2183 | 2177 |