191 off = xmm0_off;
192 delta = xmm1_off - off;
193 if(UseSSE == 1) {
194 // Save the XMM state
195 for (int n = 0; n < num_xmm_regs; n++) {
196 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
197 off += delta;
198 }
199 } else if(UseSSE >= 2) {
200 // Save whole 128bit (16 bytes) XMM registers
201 for (int n = 0; n < num_xmm_regs; n++) {
202 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
203 off += delta;
204 }
205 }
206
207 if (save_vectors) {
208 __ subptr(rsp, ymm_bytes);
209 // Save upper half of YMM registers
210 for (int n = 0; n < num_xmm_regs; n++) {
211 __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n));
212 }
213 if (UseAVX > 2) {
214 __ subptr(rsp, zmm_bytes);
215 // Save upper half of ZMM registers
216 for (int n = 0; n < num_xmm_regs; n++) {
217 __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1);
218 }
219 }
220 }
221
222 // Set an oopmap for the call site. This oopmap will map all
223 // oop-registers and debug-info registers as callee-saved. This
224 // will allow deoptimization at this safepoint to find all possible
225 // debug-info recordings, as well as let GC find all oops.
226
227 OopMapSet *oop_maps = new OopMapSet();
228 OopMap* map = new OopMap( frame_words, 0 );
229
230 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
231 #define NEXTREG(x) (x)->as_VMReg()->next()
232
233 map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
234 map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
235 map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());
236 map->set_callee_saved(STACK_OFFSET(rbx_off), rbx->as_VMReg());
237 // rbp, location is known implicitly, no oopMap
287 if (UseSSE == 1) {
288 // Restore XMM registers
289 assert(additional_frame_bytes == 0, "");
290 for (int n = 0; n < num_xmm_regs; n++) {
291 __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
292 off += delta;
293 }
294 } else if (UseSSE >= 2) {
295 // Restore whole 128bit (16 bytes) XMM registers. Do this before restoring YMM and
296 // ZMM because the movdqu instruction zeros the upper part of the XMM register.
297 for (int n = 0; n < num_xmm_regs; n++) {
298 __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
299 off += delta;
300 }
301 }
302
303 if (restore_vectors) {
304 if (UseAVX > 2) {
305 // Restore upper half of ZMM registers.
306 for (int n = 0; n < num_xmm_regs; n++) {
307 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
308 }
309 __ addptr(rsp, zmm_bytes);
310 }
311 // Restore upper half of YMM registers.
312 for (int n = 0; n < num_xmm_regs; n++) {
313 __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
314 }
315 __ addptr(rsp, ymm_bytes);
316 }
317
318 __ pop_FPU_state();
319 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
320
321 __ popf();
322 __ popa();
323 // Get the rbp, described implicitly by the frame sender code (no oopMap)
324 __ pop(rbp);
325 }
326
327 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
328
329 // Just restore result register. Only used by deoptimization. By
330 // now any callee save register that needs to be restore to a c2
331 // caller of the deoptee has been extracted into the vframeArray
332 // and will be stuffed into the c2i adapter we create for later
333 // restoration so only result registers need to be restored here.
|
191 off = xmm0_off;
192 delta = xmm1_off - off;
193 if(UseSSE == 1) {
194 // Save the XMM state
195 for (int n = 0; n < num_xmm_regs; n++) {
196 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
197 off += delta;
198 }
199 } else if(UseSSE >= 2) {
200 // Save whole 128bit (16 bytes) XMM registers
201 for (int n = 0; n < num_xmm_regs; n++) {
202 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
203 off += delta;
204 }
205 }
206
207 if (save_vectors) {
208 __ subptr(rsp, ymm_bytes);
209 // Save upper half of YMM registers
210 for (int n = 0; n < num_xmm_regs; n++) {
211 __ vextractf128_high(Address(rsp, n*16), as_XMMRegister(n));
212 }
213 if (UseAVX > 2) {
214 __ subptr(rsp, zmm_bytes);
215 // Save upper half of ZMM registers
216 for (int n = 0; n < num_xmm_regs; n++) {
217 __ vextractf64x4_high(Address(rsp, n*32), as_XMMRegister(n));
218 }
219 }
220 }
221
222 // Set an oopmap for the call site. This oopmap will map all
223 // oop-registers and debug-info registers as callee-saved. This
224 // will allow deoptimization at this safepoint to find all possible
225 // debug-info recordings, as well as let GC find all oops.
226
227 OopMapSet *oop_maps = new OopMapSet();
228 OopMap* map = new OopMap( frame_words, 0 );
229
230 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
231 #define NEXTREG(x) (x)->as_VMReg()->next()
232
233 map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
234 map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
235 map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());
236 map->set_callee_saved(STACK_OFFSET(rbx_off), rbx->as_VMReg());
237 // rbp, location is known implicitly, no oopMap
287 if (UseSSE == 1) {
288 // Restore XMM registers
289 assert(additional_frame_bytes == 0, "");
290 for (int n = 0; n < num_xmm_regs; n++) {
291 __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
292 off += delta;
293 }
294 } else if (UseSSE >= 2) {
295 // Restore whole 128bit (16 bytes) XMM registers. Do this before restoring YMM and
296 // ZMM because the movdqu instruction zeros the upper part of the XMM register.
297 for (int n = 0; n < num_xmm_regs; n++) {
298 __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
299 off += delta;
300 }
301 }
302
303 if (restore_vectors) {
304 if (UseAVX > 2) {
305 // Restore upper half of ZMM registers.
306 for (int n = 0; n < num_xmm_regs; n++) {
307 __ vinsertf64x4_high(as_XMMRegister(n), Address(rsp, n*32));
308 }
309 __ addptr(rsp, zmm_bytes);
310 }
311 // Restore upper half of YMM registers.
312 for (int n = 0; n < num_xmm_regs; n++) {
313 __ vinsertf128_high(as_XMMRegister(n), Address(rsp, n*16));
314 }
315 __ addptr(rsp, ymm_bytes);
316 }
317
318 __ pop_FPU_state();
319 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
320
321 __ popf();
322 __ popa();
323 // Get the rbp, described implicitly by the frame sender code (no oopMap)
324 __ pop(rbp);
325 }
326
327 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
328
329 // Just restore result register. Only used by deoptimization. By
330 // now any callee save register that needs to be restore to a c2
331 // caller of the deoptee has been extracted into the vframeArray
332 // and will be stuffed into the c2i adapter we create for later
333 // restoration so only result registers need to be restored here.
|