181 for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
182 __ fstp_d(Address(rsp, off*wordSize));
183 off += delta;
184 }
185
186 off = xmm0_off;
187 delta = xmm1_off - off;
188 if(UseSSE == 1) { // Save the XMM state
189 for (int n = 0; n < num_xmm_regs; n++) {
190 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
191 off += delta;
192 }
193 } else if(UseSSE >= 2) {
194 // Save whole 128bit (16 bytes) XMM regiters
195 for (int n = 0; n < num_xmm_regs; n++) {
196 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
197 off += delta;
198 }
199 }
200
201 if (vect_words > 0) {
202 assert(vect_words*wordSize == 128, "");
203 __ subptr(rsp, 128); // Save upper half of YMM registes
204 for (int n = 0; n < num_xmm_regs; n++) {
205 __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n));
206 }
207 if (UseAVX > 2) {
208 __ subptr(rsp, 256); // Save upper half of ZMM registes
209 for (int n = 0; n < num_xmm_regs; n++) {
210 __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1);
211 }
212 }
213 }
214
215 // Set an oopmap for the call site. This oopmap will map all
216 // oop-registers and debug-info registers as callee-saved. This
217 // will allow deoptimization at this safepoint to find all possible
218 // debug-info recordings, as well as let GC find all oops.
219
220 OopMapSet *oop_maps = new OopMapSet();
221 OopMap* map = new OopMap( frame_words, 0 );
249 }
250 #undef NEXTREG
251 #undef STACK_OFFSET
252
253 return map;
254 }
255
256 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
257 int num_xmm_regs = XMMRegisterImpl::number_of_registers;
258 // Recover XMM & FPU state
259 int additional_frame_bytes = 0;
260 #ifdef COMPILER2
261 if (restore_vectors) {
262 assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
263 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
264 additional_frame_bytes = 128;
265 }
266 #else
267 assert(!restore_vectors, "vectors are generated only by C2");
268 #endif
269 int off = xmm0_off;
270 int delta = xmm1_off - off;
271
272 if (UseSSE == 1) {
273 assert(additional_frame_bytes == 0, "");
274 for (int n = 0; n < num_xmm_regs; n++) {
275 __ movflt(as_XMMRegister(n), Address(rsp, off*wordSize));
276 off += delta;
277 }
278 } else if (UseSSE >= 2) {
279 for (int n = 0; n < num_xmm_regs; n++) {
280 __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
281 off += delta;
282 }
283 }
284 if (restore_vectors) {
285 assert(additional_frame_bytes == 128, "");
286 if (UseAVX > 2) {
287 // Restore upper half of ZMM registers.
288 for (int n = 0; n < num_xmm_regs; n++) {
289 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
290 }
291 __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes
292 }
293 // Restore upper half of YMM registes.
294 for (int n = 0; n < num_xmm_regs; n++) {
295 __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
296 }
297 __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes
298 }
299 __ pop_FPU_state();
300 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
301
302 __ popf();
303 __ popa();
304 // Get the rbp, described implicitly by the frame sender code (no oopMap)
305 __ pop(rbp);
306
307 }
308
309 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
310
311 // Just restore result register. Only used by deoptimization. By
312 // now any callee save register that needs to be restore to a c2
313 // caller of the deoptee has been extracted into the vframeArray
314 // and will be stuffed into the c2i adapter we create for later
315 // restoration so only result registers need to be restored here.
316 //
317
318 __ frstor(Address(rsp, 0)); // Restore fpu state
|
181 for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
182 __ fstp_d(Address(rsp, off*wordSize));
183 off += delta;
184 }
185
186 off = xmm0_off;
187 delta = xmm1_off - off;
188 if(UseSSE == 1) { // Save the XMM state
189 for (int n = 0; n < num_xmm_regs; n++) {
190 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n));
191 off += delta;
192 }
193 } else if(UseSSE >= 2) {
194 // Save whole 128bit (16 bytes) XMM regiters
195 for (int n = 0; n < num_xmm_regs; n++) {
196 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n));
197 off += delta;
198 }
199 }
200
201 if (save_vectors) {
202 assert(vect_words*wordSize == 128, "");
203 __ subptr(rsp, 128); // Save upper half of YMM registes
204 for (int n = 0; n < num_xmm_regs; n++) {
205 __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n));
206 }
207 if (UseAVX > 2) {
208 __ subptr(rsp, 256); // Save upper half of ZMM registes
209 for (int n = 0; n < num_xmm_regs; n++) {
210 __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1);
211 }
212 }
213 }
214
215 // Set an oopmap for the call site. This oopmap will map all
216 // oop-registers and debug-info registers as callee-saved. This
217 // will allow deoptimization at this safepoint to find all possible
218 // debug-info recordings, as well as let GC find all oops.
219
220 OopMapSet *oop_maps = new OopMapSet();
221 OopMap* map = new OopMap( frame_words, 0 );
249 }
250 #undef NEXTREG
251 #undef STACK_OFFSET
252
253 return map;
254 }
255
256 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
257 int num_xmm_regs = XMMRegisterImpl::number_of_registers;
258 // Recover XMM & FPU state
259 int additional_frame_bytes = 0;
260 #ifdef COMPILER2
261 if (restore_vectors) {
262 assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
263 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
264 additional_frame_bytes = 128;
265 }
266 #else
267 assert(!restore_vectors, "vectors are generated only by C2");
268 #endif
269
270 if (restore_vectors) {
271 assert(additional_frame_bytes == 128, "");
272 if (UseAVX > 2) {
273 // Restore upper half of ZMM registers.
274 for (int n = 0; n < num_xmm_regs; n++) {
275 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1);
276 }
277 __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes
278 }
279 // Restore upper half of YMM registes.
280 for (int n = 0; n < num_xmm_regs; n++) {
281 __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16));
282 }
283 __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes
284 }
285
286 int off = xmm0_off;
287 int delta = xmm1_off - off;
288
289 if (UseSSE == 1) {
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 // additional_frame_bytes only populated for the restore_vector case, else it is 0
296 for (int n = 0; n < num_xmm_regs; n++) {
297 __ movdqu(as_XMMRegister(n), Address(rsp, off*wordSize+additional_frame_bytes));
298 off += delta;
299 }
300 }
301
302 __ pop_FPU_state();
303 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
304
305 __ popf();
306 __ popa();
307 // Get the rbp, described implicitly by the frame sender code (no oopMap)
308 __ pop(rbp);
309
310 }
311
312 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
313
314 // Just restore result register. Only used by deoptimization. By
315 // now any callee save register that needs to be restore to a c2
316 // caller of the deoptee has been extracted into the vframeArray
317 // and will be stuffed into the c2i adapter we create for later
318 // restoration so only result registers need to be restored here.
319 //
320
321 __ frstor(Address(rsp, 0)); // Restore fpu state
|