142 // 72(rbp): thread Thread* |
142 // 72(rbp): thread Thread* |
143 // |
143 // |
144 // [ return_from_Java ] <--- rsp |
144 // [ return_from_Java ] <--- rsp |
145 // [ argument word n ] |
145 // [ argument word n ] |
146 // ... |
146 // ... |
147 // -8 [ argument word 1 ] |
147 // -28 [ argument word 1 ] |
148 // -7 [ saved r15 ] <--- rsp_after_call |
148 // -27 [ saved xmm15 ] <--- rsp_after_call |
|
149 // [ saved xmm7-xmm14 ] |
|
150 // -9 [ saved xmm6 ] (each xmm register takes 2 slots) |
|
151 // -7 [ saved r15 ] |
149 // -6 [ saved r14 ] |
152 // -6 [ saved r14 ] |
150 // -5 [ saved r13 ] |
153 // -5 [ saved r13 ] |
151 // -4 [ saved r12 ] |
154 // -4 [ saved r12 ] |
152 // -3 [ saved rdi ] |
155 // -3 [ saved rdi ] |
153 // -2 [ saved rsi ] |
156 // -2 [ saved rsi ] |
167 // We spill c_rarg0-c_rarg3 to this space. |
170 // We spill c_rarg0-c_rarg3 to this space. |
168 |
171 |
169 // Call stub stack layout word offsets from rbp |
172 // Call stub stack layout word offsets from rbp |
170 enum call_stub_layout { |
173 enum call_stub_layout { |
171 #ifdef _WIN64 |
174 #ifdef _WIN64 |
172 rsp_after_call_off = -7, |
175 xmm_save_first = 6, // save from xmm6 |
173 r15_off = rsp_after_call_off, |
176 xmm_save_last = 15, // to xmm15 |
|
177 xmm_save_base = -9, |
|
178 rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27 |
|
179 r15_off = -7, |
174 r14_off = -6, |
180 r14_off = -6, |
175 r13_off = -5, |
181 r13_off = -5, |
176 r12_off = -4, |
182 r12_off = -4, |
177 rdi_off = -3, |
183 rdi_off = -3, |
178 rsi_off = -2, |
184 rsi_off = -2, |
206 parameter_size_off = 2, |
212 parameter_size_off = 2, |
207 thread_off = 3 |
213 thread_off = 3 |
208 #endif |
214 #endif |
209 }; |
215 }; |
210 |
216 |
|
217 #ifdef _WIN64 |
|
218 Address xmm_save(int reg) { |
|
219 assert(reg >= xmm_save_first && reg <= xmm_save_last, "XMM register number out of range"); |
|
220 return Address(rbp, (xmm_save_base - (reg - xmm_save_first) * 2) * wordSize); |
|
221 } |
|
222 #endif |
|
223 |
211 address generate_call_stub(address& return_address) { |
224 address generate_call_stub(address& return_address) { |
212 assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 && |
225 assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 && |
213 (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, |
226 (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, |
214 "adjust this code"); |
227 "adjust this code"); |
215 StubCodeMark mark(this, "StubRoutines", "call_stub"); |
228 StubCodeMark mark(this, "StubRoutines", "call_stub"); |
254 __ movptr(rbx_save, rbx); |
267 __ movptr(rbx_save, rbx); |
255 __ movptr(r12_save, r12); |
268 __ movptr(r12_save, r12); |
256 __ movptr(r13_save, r13); |
269 __ movptr(r13_save, r13); |
257 __ movptr(r14_save, r14); |
270 __ movptr(r14_save, r14); |
258 __ movptr(r15_save, r15); |
271 __ movptr(r15_save, r15); |
259 |
|
260 #ifdef _WIN64 |
272 #ifdef _WIN64 |
|
273 for (int i = 6; i <= 15; i++) { |
|
274 __ movdqu(xmm_save(i), as_XMMRegister(i)); |
|
275 } |
|
276 |
261 const Address rdi_save(rbp, rdi_off * wordSize); |
277 const Address rdi_save(rbp, rdi_off * wordSize); |
262 const Address rsi_save(rbp, rsi_off * wordSize); |
278 const Address rsi_save(rbp, rsi_off * wordSize); |
263 |
279 |
264 __ movptr(rsi_save, rsi); |
280 __ movptr(rsi_save, rsi); |
265 __ movptr(rdi_save, rdi); |
281 __ movptr(rdi_save, rdi); |
358 __ bind(L); |
374 __ bind(L); |
359 } |
375 } |
360 #endif |
376 #endif |
361 |
377 |
362 // restore regs belonging to calling function |
378 // restore regs belonging to calling function |
|
379 #ifdef _WIN64 |
|
380 for (int i = 15; i >= 6; i--) { |
|
381 __ movdqu(as_XMMRegister(i), xmm_save(i)); |
|
382 } |
|
383 #endif |
363 __ movptr(r15, r15_save); |
384 __ movptr(r15, r15_save); |
364 __ movptr(r14, r14_save); |
385 __ movptr(r14, r14_save); |
365 __ movptr(r13, r13_save); |
386 __ movptr(r13, r13_save); |
366 __ movptr(r12, r12_save); |
387 __ movptr(r12, r12_save); |
367 __ movptr(rbx, rbx_save); |
388 __ movptr(rbx, rbx_save); |