1 /*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
97 // Offsets into the register save area
98 // Used by deoptimization when it is managing result register
99 // values on its own
100
101 static int raxOffset(void) { return rax_off; }
102 static int rdxOffset(void) { return rdx_off; }
103 static int rbxOffset(void) { return rbx_off; }
104 static int xmm0Offset(void) { return xmm0_off; }
105 // This really returns a slot in the fp save area, which one is not important
106 static int fpResultOffset(void) { return st0_off; }
107
108 // During deoptimization only the result register need to be restored
109 // all the other values have already been extracted.
110
111 static void restore_result_registers(MacroAssembler* masm);
112
113 };
114
115 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
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;
119 #ifdef COMPILER2
120 if (save_vectors) {
121 assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
122 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
123 // Save upper half of ZMM/YMM registers :
124 vect_words = 8 * 16 / wordSize;
125 additional_frame_words += vect_words;
126 }
127 #else
128 assert(!save_vectors, "vectors are generated only by C2");
129 #endif
130 int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize;
131 int frame_words = frame_size_in_bytes / wordSize;
132 *total_frame_words = frame_words;
133
134 assert(FPUStateSizeInWords == 27, "update stack layout");
135
136 // save registers, fpu state, and flags
137 // We assume caller has already has return address slot on the stack
138 // We push epb twice in this sequence because we want the real rbp,
139 // to be under the return like a normal enter and we want to use pusha
140 // We push by hand instead of pusing push
141 __ enter();
142 __ pusha();
143 __ pushf();
144 __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space
145 __ push_FPU_state(); // Save FPU state & init
168 }
169
170 __ frstor(Address(rsp, 0));
171 if (!verify_fpu) {
172 // Set the control word so that exceptions are masked for the
173 // following code.
174 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
175 }
176
177 int off = st0_off;
178 int delta = st1_off - off;
179
180 // Save the FPU registers in de-opt-able form
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 );
222
223 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
224 #define NEXTREG(x) (x)->as_VMReg()->next()
225
226 map->set_callee_saved(STACK_OFFSET(rax_off), rax->as_VMReg());
227 map->set_callee_saved(STACK_OFFSET(rcx_off), rcx->as_VMReg());
228 map->set_callee_saved(STACK_OFFSET(rdx_off), rdx->as_VMReg());
238 map->set_callee_saved(STACK_OFFSET(off), freg_name->as_VMReg());
239 map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(freg_name));
240 off += delta;
241 }
242 off = xmm0_off;
243 delta = xmm1_off - off;
244 for (int n = 0; n < num_xmm_regs; n++) {
245 XMMRegister xmm_name = as_XMMRegister(n);
246 map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
247 map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(xmm_name));
248 off += delta;
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
322
323 // Recover XMM & FPU state
324 if( UseSSE == 1 ) {
325 __ movflt(xmm0, Address(rsp, xmm0_off*wordSize));
326 } else if( UseSSE >= 2 ) {
327 __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize));
328 }
329 __ movptr(rax, Address(rsp, rax_off*wordSize));
|
1 /*
2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
97 // Offsets into the register save area
98 // Used by deoptimization when it is managing result register
99 // values on its own
100
101 static int raxOffset(void) { return rax_off; }
102 static int rdxOffset(void) { return rdx_off; }
103 static int rbxOffset(void) { return rbx_off; }
104 static int xmm0Offset(void) { return xmm0_off; }
105 // This really returns a slot in the fp save area, which one is not important
106 static int fpResultOffset(void) { return st0_off; }
107
108 // During deoptimization only the result register need to be restored
109 // all the other values have already been extracted.
110
111 static void restore_result_registers(MacroAssembler* masm);
112
113 };
114
115 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
116 int* total_frame_words, bool verify_fpu, bool save_vectors) {
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;
120 #ifdef COMPILER2
121 if (save_vectors) {
122 assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
123 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
124 // Save upper half of YMM registers
125 int vect_bytes = ymm_bytes;
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;
131 }
132 #else
133 assert(!save_vectors, "vectors are generated only by C2");
134 #endif
135 int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize;
136 int frame_words = frame_size_in_bytes / wordSize;
137 *total_frame_words = frame_words;
138
139 assert(FPUStateSizeInWords == 27, "update stack layout");
140
141 // save registers, fpu state, and flags
142 // We assume caller has already has return address slot on the stack
143 // We push epb twice in this sequence because we want the real rbp,
144 // to be under the return like a normal enter and we want to use pusha
145 // We push by hand instead of pusing push
146 __ enter();
147 __ pusha();
148 __ pushf();
149 __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space
150 __ push_FPU_state(); // Save FPU state & init
173 }
174
175 __ frstor(Address(rsp, 0));
176 if (!verify_fpu) {
177 // Set the control word so that exceptions are masked for the
178 // following code.
179 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
180 }
181
182 int off = st0_off;
183 int delta = st1_off - off;
184
185 // Save the FPU registers in de-opt-able form
186 for (int n = 0; n < FloatRegisterImpl::number_of_registers; n++) {
187 __ fstp_d(Address(rsp, off*wordSize));
188 off += delta;
189 }
190
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());
245 map->set_callee_saved(STACK_OFFSET(off), freg_name->as_VMReg());
246 map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(freg_name));
247 off += delta;
248 }
249 off = xmm0_off;
250 delta = xmm1_off - off;
251 for (int n = 0; n < num_xmm_regs; n++) {
252 XMMRegister xmm_name = as_XMMRegister(n);
253 map->set_callee_saved(STACK_OFFSET(off), xmm_name->as_VMReg());
254 map->set_callee_saved(STACK_OFFSET(off+1), NEXTREG(xmm_name));
255 off += delta;
256 }
257 #undef NEXTREG
258 #undef STACK_OFFSET
259
260 return map;
261 }
262
263 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
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;
267 // Recover XMM & FPU state
268 int additional_frame_bytes = 0;
269 #ifdef COMPILER2
270 if (restore_vectors) {
271 assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
272 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
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 }
279 }
280 #else
281 assert(!restore_vectors, "vectors are generated only by C2");
282 #endif
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
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.
334 //
335
336 __ frstor(Address(rsp, 0)); // Restore fpu state
337
338 // Recover XMM & FPU state
339 if( UseSSE == 1 ) {
340 __ movflt(xmm0, Address(rsp, xmm0_off*wordSize));
341 } else if( UseSSE >= 2 ) {
342 __ movdbl(xmm0, Address(rsp, xmm0_off*wordSize));
343 }
344 __ movptr(rax, Address(rsp, rax_off*wordSize));
|