112 |
112 |
113 }; |
113 }; |
114 |
114 |
115 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, |
115 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, |
116 int* total_frame_words, bool verify_fpu, bool save_vectors) { |
116 int* total_frame_words, bool verify_fpu, bool save_vectors) { |
117 int vect_words = 0; |
|
118 int num_xmm_regs = XMMRegisterImpl::number_of_registers; |
117 int num_xmm_regs = XMMRegisterImpl::number_of_registers; |
|
118 int ymm_bytes = num_xmm_regs * 16; |
|
119 int zmm_bytes = num_xmm_regs * 32; |
119 #ifdef COMPILER2 |
120 #ifdef COMPILER2 |
120 if (save_vectors) { |
121 if (save_vectors) { |
121 assert(UseAVX > 0, "512bit vectors are supported only with EVEX"); |
122 assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX"); |
122 assert(MaxVectorSize == 64, "only 512bit vectors are supported now"); |
123 assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now"); |
123 // Save upper half of ZMM/YMM registers : |
124 // Save upper half of YMM registers |
124 vect_words = 8 * 16 / wordSize; |
125 int vect_bytes = ymm_bytes; |
125 additional_frame_words += vect_words; |
126 if (UseAVX > 2) { |
|
127 // Save upper half of ZMM registers as well |
|
128 vect_bytes += zmm_bytes; |
|
129 } |
|
130 additional_frame_words += vect_bytes / wordSize; |
126 } |
131 } |
127 #else |
132 #else |
128 assert(!save_vectors, "vectors are generated only by C2"); |
133 assert(!save_vectors, "vectors are generated only by C2"); |
129 #endif |
134 #endif |
130 int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize; |
135 int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize; |
183 off += delta; |
188 off += delta; |
184 } |
189 } |
185 |
190 |
186 off = xmm0_off; |
191 off = xmm0_off; |
187 delta = xmm1_off - off; |
192 delta = xmm1_off - off; |
188 if(UseSSE == 1) { // Save the XMM state |
193 if(UseSSE == 1) { |
|
194 // Save the XMM state |
189 for (int n = 0; n < num_xmm_regs; n++) { |
195 for (int n = 0; n < num_xmm_regs; n++) { |
190 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n)); |
196 __ movflt(Address(rsp, off*wordSize), as_XMMRegister(n)); |
191 off += delta; |
197 off += delta; |
192 } |
198 } |
193 } else if(UseSSE >= 2) { |
199 } else if(UseSSE >= 2) { |
194 // Save whole 128bit (16 bytes) XMM regiters |
200 // Save whole 128bit (16 bytes) XMM registers |
195 for (int n = 0; n < num_xmm_regs; n++) { |
201 for (int n = 0; n < num_xmm_regs; n++) { |
196 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n)); |
202 __ movdqu(Address(rsp, off*wordSize), as_XMMRegister(n)); |
197 off += delta; |
203 off += delta; |
198 } |
204 } |
199 } |
205 } |
200 |
206 |
201 if (save_vectors) { |
207 if (save_vectors) { |
202 assert(vect_words*wordSize == 128, ""); |
208 __ subptr(rsp, ymm_bytes); |
203 __ subptr(rsp, 128); // Save upper half of YMM registes |
209 // Save upper half of YMM registers |
204 for (int n = 0; n < num_xmm_regs; n++) { |
210 for (int n = 0; n < num_xmm_regs; n++) { |
205 __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n)); |
211 __ vextractf128h(Address(rsp, n*16), as_XMMRegister(n)); |
206 } |
212 } |
207 if (UseAVX > 2) { |
213 if (UseAVX > 2) { |
208 __ subptr(rsp, 256); // Save upper half of ZMM registes |
214 __ subptr(rsp, zmm_bytes); |
|
215 // Save upper half of ZMM registers |
209 for (int n = 0; n < num_xmm_regs; n++) { |
216 for (int n = 0; n < num_xmm_regs; n++) { |
210 __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1); |
217 __ vextractf64x4h(Address(rsp, n*32), as_XMMRegister(n), 1); |
211 } |
218 } |
212 } |
219 } |
213 } |
220 } |
253 return map; |
260 return map; |
254 } |
261 } |
255 |
262 |
256 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) { |
263 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) { |
257 int num_xmm_regs = XMMRegisterImpl::number_of_registers; |
264 int num_xmm_regs = XMMRegisterImpl::number_of_registers; |
|
265 int ymm_bytes = num_xmm_regs * 16; |
|
266 int zmm_bytes = num_xmm_regs * 32; |
258 // Recover XMM & FPU state |
267 // Recover XMM & FPU state |
259 int additional_frame_bytes = 0; |
268 int additional_frame_bytes = 0; |
260 #ifdef COMPILER2 |
269 #ifdef COMPILER2 |
261 if (restore_vectors) { |
270 if (restore_vectors) { |
262 assert(UseAVX > 0, "512bit vectors are supported only with EVEX"); |
271 assert(UseAVX > 0, "up to 512bit vectors are supported with EVEX"); |
263 assert(MaxVectorSize == 64, "only 512bit vectors are supported now"); |
272 assert(MaxVectorSize <= 64, "up to 512bit vectors are supported now"); |
264 additional_frame_bytes = 128; |
273 // Save upper half of YMM registers |
|
274 additional_frame_bytes = ymm_bytes; |
|
275 if (UseAVX > 2) { |
|
276 // Save upper half of ZMM registers as well |
|
277 additional_frame_bytes += zmm_bytes; |
|
278 } |
265 } |
279 } |
266 #else |
280 #else |
267 assert(!restore_vectors, "vectors are generated only by C2"); |
281 assert(!restore_vectors, "vectors are generated only by C2"); |
268 #endif |
282 #endif |
269 |
283 |
|
284 int off = xmm0_off; |
|
285 int delta = xmm1_off - off; |
|
286 |
|
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 |
270 if (restore_vectors) { |
303 if (restore_vectors) { |
271 assert(additional_frame_bytes == 128, ""); |
|
272 if (UseAVX > 2) { |
304 if (UseAVX > 2) { |
273 // Restore upper half of ZMM registers. |
305 // Restore upper half of ZMM registers. |
274 for (int n = 0; n < num_xmm_regs; n++) { |
306 for (int n = 0; n < num_xmm_regs; n++) { |
275 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1); |
307 __ vinsertf64x4h(as_XMMRegister(n), Address(rsp, n*32), 1); |
276 } |
308 } |
277 __ addptr(rsp, additional_frame_bytes*2); // Save upper half of ZMM registes |
309 __ addptr(rsp, zmm_bytes); |
278 } |
310 } |
279 // Restore upper half of YMM registes. |
311 // Restore upper half of YMM registers. |
280 for (int n = 0; n < num_xmm_regs; n++) { |
312 for (int n = 0; n < num_xmm_regs; n++) { |
281 __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16)); |
313 __ vinsertf128h(as_XMMRegister(n), Address(rsp, n*16)); |
282 } |
314 } |
283 __ addptr(rsp, additional_frame_bytes); // Save upper half of YMM registes |
315 __ addptr(rsp, ymm_bytes); |
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 } |
316 } |
301 |
317 |
302 __ pop_FPU_state(); |
318 __ pop_FPU_state(); |
303 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers |
319 __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers |
304 |
320 |
305 __ popf(); |
321 __ popf(); |
306 __ popa(); |
322 __ popa(); |
307 // Get the rbp, described implicitly by the frame sender code (no oopMap) |
323 // Get the rbp, described implicitly by the frame sender code (no oopMap) |
308 __ pop(rbp); |
324 __ pop(rbp); |
309 |
|
310 } |
325 } |
311 |
326 |
312 void RegisterSaver::restore_result_registers(MacroAssembler* masm) { |
327 void RegisterSaver::restore_result_registers(MacroAssembler* masm) { |
313 |
328 |
314 // Just restore result register. Only used by deoptimization. By |
329 // Just restore result register. Only used by deoptimization. By |