69 #define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off
70 enum layout {
71 fpu_state_off = frame::arg_reg_save_area_bytes/BytesPerInt, // fxsave save area
72 xmm_off = fpu_state_off + 160/BytesPerInt, // offset in fxsave save area
73 DEF_XMM_OFFS(0),
74 DEF_XMM_OFFS(1),
75 DEF_XMM_OFFS(2),
76 DEF_XMM_OFFS(3),
77 DEF_XMM_OFFS(4),
78 DEF_XMM_OFFS(5),
79 DEF_XMM_OFFS(6),
80 DEF_XMM_OFFS(7),
81 DEF_XMM_OFFS(8),
82 DEF_XMM_OFFS(9),
83 DEF_XMM_OFFS(10),
84 DEF_XMM_OFFS(11),
85 DEF_XMM_OFFS(12),
86 DEF_XMM_OFFS(13),
87 DEF_XMM_OFFS(14),
88 DEF_XMM_OFFS(15),
89 fpu_state_end = fpu_state_off + ((FPUStateSizeInWords-1)*wordSize / BytesPerInt),
90 fpu_stateH_end,
91 r15_off, r15H_off,
92 r14_off, r14H_off,
93 r13_off, r13H_off,
94 r12_off, r12H_off,
95 r11_off, r11H_off,
96 r10_off, r10H_off,
97 r9_off, r9H_off,
98 r8_off, r8H_off,
99 rdi_off, rdiH_off,
100 rsi_off, rsiH_off,
101 ignore_off, ignoreH_off, // extra copy of rbp
102 rsp_off, rspH_off,
103 rbx_off, rbxH_off,
104 rdx_off, rdxH_off,
105 rcx_off, rcxH_off,
106 rax_off, raxH_off,
107 // 16-byte stack alignment fill word: see MacroAssembler::push/pop_IU_state
108 align_off, alignH_off,
109 flags_off, flagsH_off,
119 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors = false);
120 static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
121
122 // Offsets into the register save area
123 // Used by deoptimization when it is managing result register
124 // values on its own
125
126 static int rax_offset_in_bytes(void) { return BytesPerInt * rax_off; }
127 static int rdx_offset_in_bytes(void) { return BytesPerInt * rdx_off; }
128 static int rbx_offset_in_bytes(void) { return BytesPerInt * rbx_off; }
129 static int xmm0_offset_in_bytes(void) { return BytesPerInt * xmm0_off; }
130 static int return_offset_in_bytes(void) { return BytesPerInt * return_off; }
131
132 // During deoptimization only the result registers need to be restored,
133 // all the other values have already been extracted.
134 static void restore_result_registers(MacroAssembler* masm);
135 };
136
137 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
138 int vect_words = 0;
139 #ifdef COMPILER2
140 if (save_vectors) {
141 assert(UseAVX > 0, "256bit vectors are supported only with AVX");
142 assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
143 // Save upper half of YMM registes
144 vect_words = 16 * 16 / wordSize;
145 additional_frame_words += vect_words;
146 }
147 #else
148 assert(!save_vectors, "vectors are generated only by C2");
149 #endif
150
151 // Always make the frame size 16-byte aligned
152 int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
153 reg_save_size*BytesPerInt, 16);
154 // OopMap frame size is in compiler stack slots (jint's) not bytes or words
155 int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
156 // The caller will allocate additional_frame_words
157 int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt;
158 // CodeBlob frame size is in words.
159 int frame_size_in_words = frame_size_in_bytes / wordSize;
160 *total_frame_words = frame_size_in_words;
161
162 // Save registers, fpu state, and flags.
163 // We assume caller has already pushed the return address onto the
164 // stack, so rsp is 8-byte aligned here.
165 // We push rpb twice in this sequence because we want the real rbp
166 // to be under the return like a normal enter.
167
168 __ enter(); // rsp becomes 16-byte aligned here
169 __ push_CPU_state(); // Push a multiple of 16 bytes
170
171 if (vect_words > 0) {
172 assert(vect_words*wordSize == 256, "");
173 __ subptr(rsp, 256); // Save upper half of YMM registes
174 __ vextractf128h(Address(rsp, 0),xmm0);
175 __ vextractf128h(Address(rsp, 16),xmm1);
176 __ vextractf128h(Address(rsp, 32),xmm2);
177 __ vextractf128h(Address(rsp, 48),xmm3);
178 __ vextractf128h(Address(rsp, 64),xmm4);
179 __ vextractf128h(Address(rsp, 80),xmm5);
180 __ vextractf128h(Address(rsp, 96),xmm6);
181 __ vextractf128h(Address(rsp,112),xmm7);
182 __ vextractf128h(Address(rsp,128),xmm8);
183 __ vextractf128h(Address(rsp,144),xmm9);
184 __ vextractf128h(Address(rsp,160),xmm10);
185 __ vextractf128h(Address(rsp,176),xmm11);
186 __ vextractf128h(Address(rsp,192),xmm12);
187 __ vextractf128h(Address(rsp,208),xmm13);
188 __ vextractf128h(Address(rsp,224),xmm14);
189 __ vextractf128h(Address(rsp,240),xmm15);
190 }
191 if (frame::arg_reg_save_area_bytes != 0) {
192 // Allocate argument register save area
193 __ subptr(rsp, frame::arg_reg_save_area_bytes);
194 }
195
196 // Set an oopmap for the call site. This oopmap will map all
197 // oop-registers and debug-info registers as callee-saved. This
198 // will allow deoptimization at this safepoint to find all possible
199 // debug-info recordings, as well as let GC find all oops.
200
201 OopMapSet *oop_maps = new OopMapSet();
202 OopMap* map = new OopMap(frame_size_in_slots, 0);
203
204 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots)
205
206 map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg());
207 map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg());
208 map->set_callee_saved(STACK_OFFSET( rdx_off ), rdx->as_VMReg());
209 map->set_callee_saved(STACK_OFFSET( rbx_off ), rbx->as_VMReg());
218 map->set_callee_saved(STACK_OFFSET( r12_off ), r12->as_VMReg());
219 map->set_callee_saved(STACK_OFFSET( r13_off ), r13->as_VMReg());
220 map->set_callee_saved(STACK_OFFSET( r14_off ), r14->as_VMReg());
221 map->set_callee_saved(STACK_OFFSET( r15_off ), r15->as_VMReg());
222 map->set_callee_saved(STACK_OFFSET(xmm0_off ), xmm0->as_VMReg());
223 map->set_callee_saved(STACK_OFFSET(xmm1_off ), xmm1->as_VMReg());
224 map->set_callee_saved(STACK_OFFSET(xmm2_off ), xmm2->as_VMReg());
225 map->set_callee_saved(STACK_OFFSET(xmm3_off ), xmm3->as_VMReg());
226 map->set_callee_saved(STACK_OFFSET(xmm4_off ), xmm4->as_VMReg());
227 map->set_callee_saved(STACK_OFFSET(xmm5_off ), xmm5->as_VMReg());
228 map->set_callee_saved(STACK_OFFSET(xmm6_off ), xmm6->as_VMReg());
229 map->set_callee_saved(STACK_OFFSET(xmm7_off ), xmm7->as_VMReg());
230 map->set_callee_saved(STACK_OFFSET(xmm8_off ), xmm8->as_VMReg());
231 map->set_callee_saved(STACK_OFFSET(xmm9_off ), xmm9->as_VMReg());
232 map->set_callee_saved(STACK_OFFSET(xmm10_off), xmm10->as_VMReg());
233 map->set_callee_saved(STACK_OFFSET(xmm11_off), xmm11->as_VMReg());
234 map->set_callee_saved(STACK_OFFSET(xmm12_off), xmm12->as_VMReg());
235 map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg());
236 map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg());
237 map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg());
238
239 // %%% These should all be a waste but we'll keep things as they were for now
240 if (true) {
241 map->set_callee_saved(STACK_OFFSET( raxH_off ), rax->as_VMReg()->next());
242 map->set_callee_saved(STACK_OFFSET( rcxH_off ), rcx->as_VMReg()->next());
243 map->set_callee_saved(STACK_OFFSET( rdxH_off ), rdx->as_VMReg()->next());
244 map->set_callee_saved(STACK_OFFSET( rbxH_off ), rbx->as_VMReg()->next());
245 // rbp location is known implicitly by the frame sender code, needs no oopmap
246 map->set_callee_saved(STACK_OFFSET( rsiH_off ), rsi->as_VMReg()->next());
247 map->set_callee_saved(STACK_OFFSET( rdiH_off ), rdi->as_VMReg()->next());
248 map->set_callee_saved(STACK_OFFSET( r8H_off ), r8->as_VMReg()->next());
249 map->set_callee_saved(STACK_OFFSET( r9H_off ), r9->as_VMReg()->next());
250 map->set_callee_saved(STACK_OFFSET( r10H_off ), r10->as_VMReg()->next());
251 map->set_callee_saved(STACK_OFFSET( r11H_off ), r11->as_VMReg()->next());
252 map->set_callee_saved(STACK_OFFSET( r12H_off ), r12->as_VMReg()->next());
253 map->set_callee_saved(STACK_OFFSET( r13H_off ), r13->as_VMReg()->next());
254 map->set_callee_saved(STACK_OFFSET( r14H_off ), r14->as_VMReg()->next());
255 map->set_callee_saved(STACK_OFFSET( r15H_off ), r15->as_VMReg()->next());
256 map->set_callee_saved(STACK_OFFSET(xmm0H_off ), xmm0->as_VMReg()->next());
257 map->set_callee_saved(STACK_OFFSET(xmm1H_off ), xmm1->as_VMReg()->next());
258 map->set_callee_saved(STACK_OFFSET(xmm2H_off ), xmm2->as_VMReg()->next());
259 map->set_callee_saved(STACK_OFFSET(xmm3H_off ), xmm3->as_VMReg()->next());
260 map->set_callee_saved(STACK_OFFSET(xmm4H_off ), xmm4->as_VMReg()->next());
261 map->set_callee_saved(STACK_OFFSET(xmm5H_off ), xmm5->as_VMReg()->next());
262 map->set_callee_saved(STACK_OFFSET(xmm6H_off ), xmm6->as_VMReg()->next());
263 map->set_callee_saved(STACK_OFFSET(xmm7H_off ), xmm7->as_VMReg()->next());
264 map->set_callee_saved(STACK_OFFSET(xmm8H_off ), xmm8->as_VMReg()->next());
265 map->set_callee_saved(STACK_OFFSET(xmm9H_off ), xmm9->as_VMReg()->next());
266 map->set_callee_saved(STACK_OFFSET(xmm10H_off), xmm10->as_VMReg()->next());
267 map->set_callee_saved(STACK_OFFSET(xmm11H_off), xmm11->as_VMReg()->next());
268 map->set_callee_saved(STACK_OFFSET(xmm12H_off), xmm12->as_VMReg()->next());
269 map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next());
270 map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next());
271 map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next());
272 }
273
274 return map;
275 }
276
277 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
278 if (frame::arg_reg_save_area_bytes != 0) {
279 // Pop arg register save area
280 __ addptr(rsp, frame::arg_reg_save_area_bytes);
281 }
282 #ifdef COMPILER2
283 if (restore_vectors) {
284 // Restore upper half of YMM registes.
285 assert(UseAVX > 0, "256bit vectors are supported only with AVX");
286 assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
287 __ vinsertf128h(xmm0, Address(rsp, 0));
288 __ vinsertf128h(xmm1, Address(rsp, 16));
289 __ vinsertf128h(xmm2, Address(rsp, 32));
290 __ vinsertf128h(xmm3, Address(rsp, 48));
291 __ vinsertf128h(xmm4, Address(rsp, 64));
292 __ vinsertf128h(xmm5, Address(rsp, 80));
293 __ vinsertf128h(xmm6, Address(rsp, 96));
294 __ vinsertf128h(xmm7, Address(rsp,112));
295 __ vinsertf128h(xmm8, Address(rsp,128));
296 __ vinsertf128h(xmm9, Address(rsp,144));
297 __ vinsertf128h(xmm10, Address(rsp,160));
298 __ vinsertf128h(xmm11, Address(rsp,176));
299 __ vinsertf128h(xmm12, Address(rsp,192));
300 __ vinsertf128h(xmm13, Address(rsp,208));
301 __ vinsertf128h(xmm14, Address(rsp,224));
302 __ vinsertf128h(xmm15, Address(rsp,240));
303 __ addptr(rsp, 256);
304 }
305 #else
306 assert(!restore_vectors, "vectors are generated only by C2");
307 #endif
308 // Recover CPU state
309 __ pop_CPU_state();
310 // Get the rbp described implicitly by the calling convention (no oopMap)
311 __ pop(rbp);
312 }
313
314 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
315
316 // Just restore result register. Only used by deoptimization. By
317 // now any callee save register that needs to be restored to a c2
318 // caller of the deoptee has been extracted into the vframeArray
319 // and will be stuffed into the c2i adapter we create for later
320 // restoration so only result registers need to be restored here.
321
322 // Restore fp result register
323 __ movdbl(xmm0, Address(rsp, xmm0_offset_in_bytes()));
|
69 #define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off
70 enum layout {
71 fpu_state_off = frame::arg_reg_save_area_bytes/BytesPerInt, // fxsave save area
72 xmm_off = fpu_state_off + 160/BytesPerInt, // offset in fxsave save area
73 DEF_XMM_OFFS(0),
74 DEF_XMM_OFFS(1),
75 DEF_XMM_OFFS(2),
76 DEF_XMM_OFFS(3),
77 DEF_XMM_OFFS(4),
78 DEF_XMM_OFFS(5),
79 DEF_XMM_OFFS(6),
80 DEF_XMM_OFFS(7),
81 DEF_XMM_OFFS(8),
82 DEF_XMM_OFFS(9),
83 DEF_XMM_OFFS(10),
84 DEF_XMM_OFFS(11),
85 DEF_XMM_OFFS(12),
86 DEF_XMM_OFFS(13),
87 DEF_XMM_OFFS(14),
88 DEF_XMM_OFFS(15),
89 DEF_XMM_OFFS(16),
90 DEF_XMM_OFFS(17),
91 DEF_XMM_OFFS(18),
92 DEF_XMM_OFFS(19),
93 DEF_XMM_OFFS(20),
94 DEF_XMM_OFFS(21),
95 DEF_XMM_OFFS(22),
96 DEF_XMM_OFFS(23),
97 DEF_XMM_OFFS(24),
98 DEF_XMM_OFFS(25),
99 DEF_XMM_OFFS(26),
100 DEF_XMM_OFFS(27),
101 DEF_XMM_OFFS(28),
102 DEF_XMM_OFFS(29),
103 DEF_XMM_OFFS(30),
104 DEF_XMM_OFFS(31),
105 fpu_state_end = fpu_state_off + ((FPUStateSizeInWords - 1)*wordSize / BytesPerInt),
106 fpu_stateH_end,
107 r15_off, r15H_off,
108 r14_off, r14H_off,
109 r13_off, r13H_off,
110 r12_off, r12H_off,
111 r11_off, r11H_off,
112 r10_off, r10H_off,
113 r9_off, r9H_off,
114 r8_off, r8H_off,
115 rdi_off, rdiH_off,
116 rsi_off, rsiH_off,
117 ignore_off, ignoreH_off, // extra copy of rbp
118 rsp_off, rspH_off,
119 rbx_off, rbxH_off,
120 rdx_off, rdxH_off,
121 rcx_off, rcxH_off,
122 rax_off, raxH_off,
123 // 16-byte stack alignment fill word: see MacroAssembler::push/pop_IU_state
124 align_off, alignH_off,
125 flags_off, flagsH_off,
135 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors = false);
136 static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
137
138 // Offsets into the register save area
139 // Used by deoptimization when it is managing result register
140 // values on its own
141
142 static int rax_offset_in_bytes(void) { return BytesPerInt * rax_off; }
143 static int rdx_offset_in_bytes(void) { return BytesPerInt * rdx_off; }
144 static int rbx_offset_in_bytes(void) { return BytesPerInt * rbx_off; }
145 static int xmm0_offset_in_bytes(void) { return BytesPerInt * xmm0_off; }
146 static int return_offset_in_bytes(void) { return BytesPerInt * return_off; }
147
148 // During deoptimization only the result registers need to be restored,
149 // all the other values have already been extracted.
150 static void restore_result_registers(MacroAssembler* masm);
151 };
152
153 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
154 int vect_words = 0;
155 int num_xmm_regs = 16;
156 if (UseAVX > 2) {
157 num_xmm_regs = 32;
158 }
159 #ifdef COMPILER2
160 if (save_vectors) {
161 assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
162 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
163 // Save upper half of YMM registers
164 vect_words = 16 * num_xmm_regs / wordSize;
165 additional_frame_words += vect_words;
166 if (UseAVX > 2) {
167 // Save upper half of ZMM registers as well
168 additional_frame_words += vect_words;
169 }
170 }
171 #else
172 assert(!save_vectors, "vectors are generated only by C2");
173 #endif
174
175 // Always make the frame size 16-byte aligned
176 int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
177 reg_save_size*BytesPerInt, num_xmm_regs);
178 // OopMap frame size is in compiler stack slots (jint's) not bytes or words
179 int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
180 // The caller will allocate additional_frame_words
181 int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt;
182 // CodeBlob frame size is in words.
183 int frame_size_in_words = frame_size_in_bytes / wordSize;
184 *total_frame_words = frame_size_in_words;
185
186 // Save registers, fpu state, and flags.
187 // We assume caller has already pushed the return address onto the
188 // stack, so rsp is 8-byte aligned here.
189 // We push rpb twice in this sequence because we want the real rbp
190 // to be under the return like a normal enter.
191
192 __ enter(); // rsp becomes 16-byte aligned here
193 __ push_CPU_state(); // Push a multiple of 16 bytes
194
195 if (vect_words > 0) {
196 assert(vect_words*wordSize >= 256, "");
197 __ subptr(rsp, 256); // Save upper half of YMM registes(0..15)
198 __ vextractf128h(Address(rsp, 0), xmm0);
199 __ vextractf128h(Address(rsp, 16), xmm1);
200 __ vextractf128h(Address(rsp, 32), xmm2);
201 __ vextractf128h(Address(rsp, 48), xmm3);
202 __ vextractf128h(Address(rsp, 64), xmm4);
203 __ vextractf128h(Address(rsp, 80), xmm5);
204 __ vextractf128h(Address(rsp, 96), xmm6);
205 __ vextractf128h(Address(rsp, 112), xmm7);
206 __ vextractf128h(Address(rsp, 128), xmm8);
207 __ vextractf128h(Address(rsp, 144), xmm9);
208 __ vextractf128h(Address(rsp, 160), xmm10);
209 __ vextractf128h(Address(rsp, 176), xmm11);
210 __ vextractf128h(Address(rsp, 192), xmm12);
211 __ vextractf128h(Address(rsp, 208), xmm13);
212 __ vextractf128h(Address(rsp, 224), xmm14);
213 __ vextractf128h(Address(rsp, 240), xmm15);
214 if (UseAVX > 2) {
215 __ subptr(rsp, 256); // Save upper half of YMM registes(16..31)
216 __ vextractf128h(Address(rsp, 0), xmm16);
217 __ vextractf128h(Address(rsp, 16), xmm17);
218 __ vextractf128h(Address(rsp, 32), xmm18);
219 __ vextractf128h(Address(rsp, 48), xmm19);
220 __ vextractf128h(Address(rsp, 64), xmm20);
221 __ vextractf128h(Address(rsp, 80), xmm21);
222 __ vextractf128h(Address(rsp, 96), xmm22);
223 __ vextractf128h(Address(rsp, 112), xmm23);
224 __ vextractf128h(Address(rsp, 128), xmm24);
225 __ vextractf128h(Address(rsp, 144), xmm25);
226 __ vextractf128h(Address(rsp, 160), xmm26);
227 __ vextractf128h(Address(rsp, 176), xmm27);
228 __ vextractf128h(Address(rsp, 192), xmm28);
229 __ vextractf128h(Address(rsp, 208), xmm29);
230 __ vextractf128h(Address(rsp, 224), xmm30);
231 __ vextractf128h(Address(rsp, 240), xmm31);
232 // Now handle the ZMM registers (0..31)
233 __ subptr(rsp, 1024); // Save upper half of ZMM registes
234 __ vextractf64x4h(Address(rsp, 0), xmm0);
235 __ vextractf64x4h(Address(rsp, 32), xmm1);
236 __ vextractf64x4h(Address(rsp, 64), xmm2);
237 __ vextractf64x4h(Address(rsp, 96), xmm3);
238 __ vextractf64x4h(Address(rsp, 128), xmm4);
239 __ vextractf64x4h(Address(rsp, 160), xmm5);
240 __ vextractf64x4h(Address(rsp, 192), xmm6);
241 __ vextractf64x4h(Address(rsp, 224), xmm7);
242 __ vextractf64x4h(Address(rsp, 256), xmm8);
243 __ vextractf64x4h(Address(rsp, 288), xmm9);
244 __ vextractf64x4h(Address(rsp, 320), xmm10);
245 __ vextractf64x4h(Address(rsp, 352), xmm11);
246 __ vextractf64x4h(Address(rsp, 384), xmm12);
247 __ vextractf64x4h(Address(rsp, 416), xmm13);
248 __ vextractf64x4h(Address(rsp, 448), xmm14);
249 __ vextractf64x4h(Address(rsp, 480), xmm15);
250 __ vextractf64x4h(Address(rsp, 512), xmm16);
251 __ vextractf64x4h(Address(rsp, 544), xmm17);
252 __ vextractf64x4h(Address(rsp, 576), xmm18);
253 __ vextractf64x4h(Address(rsp, 608), xmm19);
254 __ vextractf64x4h(Address(rsp, 640), xmm20);
255 __ vextractf64x4h(Address(rsp, 672), xmm21);
256 __ vextractf64x4h(Address(rsp, 704), xmm22);
257 __ vextractf64x4h(Address(rsp, 736), xmm23);
258 __ vextractf64x4h(Address(rsp, 768), xmm24);
259 __ vextractf64x4h(Address(rsp, 800), xmm25);
260 __ vextractf64x4h(Address(rsp, 832), xmm26);
261 __ vextractf64x4h(Address(rsp, 864), xmm27);
262 __ vextractf64x4h(Address(rsp, 896), xmm28);
263 __ vextractf64x4h(Address(rsp, 928), xmm29);
264 __ vextractf64x4h(Address(rsp, 960), xmm30);
265 __ vextractf64x4h(Address(rsp, 992), xmm31);
266 }
267 }
268 if (frame::arg_reg_save_area_bytes != 0) {
269 // Allocate argument register save area
270 __ subptr(rsp, frame::arg_reg_save_area_bytes);
271 }
272
273 // Set an oopmap for the call site. This oopmap will map all
274 // oop-registers and debug-info registers as callee-saved. This
275 // will allow deoptimization at this safepoint to find all possible
276 // debug-info recordings, as well as let GC find all oops.
277
278 OopMapSet *oop_maps = new OopMapSet();
279 OopMap* map = new OopMap(frame_size_in_slots, 0);
280
281 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots)
282
283 map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg());
284 map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg());
285 map->set_callee_saved(STACK_OFFSET( rdx_off ), rdx->as_VMReg());
286 map->set_callee_saved(STACK_OFFSET( rbx_off ), rbx->as_VMReg());
295 map->set_callee_saved(STACK_OFFSET( r12_off ), r12->as_VMReg());
296 map->set_callee_saved(STACK_OFFSET( r13_off ), r13->as_VMReg());
297 map->set_callee_saved(STACK_OFFSET( r14_off ), r14->as_VMReg());
298 map->set_callee_saved(STACK_OFFSET( r15_off ), r15->as_VMReg());
299 map->set_callee_saved(STACK_OFFSET(xmm0_off ), xmm0->as_VMReg());
300 map->set_callee_saved(STACK_OFFSET(xmm1_off ), xmm1->as_VMReg());
301 map->set_callee_saved(STACK_OFFSET(xmm2_off ), xmm2->as_VMReg());
302 map->set_callee_saved(STACK_OFFSET(xmm3_off ), xmm3->as_VMReg());
303 map->set_callee_saved(STACK_OFFSET(xmm4_off ), xmm4->as_VMReg());
304 map->set_callee_saved(STACK_OFFSET(xmm5_off ), xmm5->as_VMReg());
305 map->set_callee_saved(STACK_OFFSET(xmm6_off ), xmm6->as_VMReg());
306 map->set_callee_saved(STACK_OFFSET(xmm7_off ), xmm7->as_VMReg());
307 map->set_callee_saved(STACK_OFFSET(xmm8_off ), xmm8->as_VMReg());
308 map->set_callee_saved(STACK_OFFSET(xmm9_off ), xmm9->as_VMReg());
309 map->set_callee_saved(STACK_OFFSET(xmm10_off), xmm10->as_VMReg());
310 map->set_callee_saved(STACK_OFFSET(xmm11_off), xmm11->as_VMReg());
311 map->set_callee_saved(STACK_OFFSET(xmm12_off), xmm12->as_VMReg());
312 map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg());
313 map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg());
314 map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg());
315 if (UseAVX > 2) {
316 map->set_callee_saved(STACK_OFFSET(xmm16_off), xmm16->as_VMReg());
317 map->set_callee_saved(STACK_OFFSET(xmm17_off), xmm17->as_VMReg());
318 map->set_callee_saved(STACK_OFFSET(xmm18_off), xmm18->as_VMReg());
319 map->set_callee_saved(STACK_OFFSET(xmm19_off), xmm19->as_VMReg());
320 map->set_callee_saved(STACK_OFFSET(xmm20_off), xmm20->as_VMReg());
321 map->set_callee_saved(STACK_OFFSET(xmm21_off), xmm21->as_VMReg());
322 map->set_callee_saved(STACK_OFFSET(xmm22_off), xmm22->as_VMReg());
323 map->set_callee_saved(STACK_OFFSET(xmm23_off), xmm23->as_VMReg());
324 map->set_callee_saved(STACK_OFFSET(xmm24_off), xmm24->as_VMReg());
325 map->set_callee_saved(STACK_OFFSET(xmm25_off), xmm25->as_VMReg());
326 map->set_callee_saved(STACK_OFFSET(xmm26_off), xmm26->as_VMReg());
327 map->set_callee_saved(STACK_OFFSET(xmm27_off), xmm27->as_VMReg());
328 map->set_callee_saved(STACK_OFFSET(xmm28_off), xmm28->as_VMReg());
329 map->set_callee_saved(STACK_OFFSET(xmm29_off), xmm29->as_VMReg());
330 map->set_callee_saved(STACK_OFFSET(xmm30_off), xmm30->as_VMReg());
331 map->set_callee_saved(STACK_OFFSET(xmm31_off), xmm31->as_VMReg());
332 }
333
334 // %%% These should all be a waste but we'll keep things as they were for now
335 if (true) {
336 map->set_callee_saved(STACK_OFFSET( raxH_off ), rax->as_VMReg()->next());
337 map->set_callee_saved(STACK_OFFSET( rcxH_off ), rcx->as_VMReg()->next());
338 map->set_callee_saved(STACK_OFFSET( rdxH_off ), rdx->as_VMReg()->next());
339 map->set_callee_saved(STACK_OFFSET( rbxH_off ), rbx->as_VMReg()->next());
340 // rbp location is known implicitly by the frame sender code, needs no oopmap
341 map->set_callee_saved(STACK_OFFSET( rsiH_off ), rsi->as_VMReg()->next());
342 map->set_callee_saved(STACK_OFFSET( rdiH_off ), rdi->as_VMReg()->next());
343 map->set_callee_saved(STACK_OFFSET( r8H_off ), r8->as_VMReg()->next());
344 map->set_callee_saved(STACK_OFFSET( r9H_off ), r9->as_VMReg()->next());
345 map->set_callee_saved(STACK_OFFSET( r10H_off ), r10->as_VMReg()->next());
346 map->set_callee_saved(STACK_OFFSET( r11H_off ), r11->as_VMReg()->next());
347 map->set_callee_saved(STACK_OFFSET( r12H_off ), r12->as_VMReg()->next());
348 map->set_callee_saved(STACK_OFFSET( r13H_off ), r13->as_VMReg()->next());
349 map->set_callee_saved(STACK_OFFSET( r14H_off ), r14->as_VMReg()->next());
350 map->set_callee_saved(STACK_OFFSET( r15H_off ), r15->as_VMReg()->next());
351 map->set_callee_saved(STACK_OFFSET(xmm0H_off ), xmm0->as_VMReg()->next());
352 map->set_callee_saved(STACK_OFFSET(xmm1H_off ), xmm1->as_VMReg()->next());
353 map->set_callee_saved(STACK_OFFSET(xmm2H_off ), xmm2->as_VMReg()->next());
354 map->set_callee_saved(STACK_OFFSET(xmm3H_off ), xmm3->as_VMReg()->next());
355 map->set_callee_saved(STACK_OFFSET(xmm4H_off ), xmm4->as_VMReg()->next());
356 map->set_callee_saved(STACK_OFFSET(xmm5H_off ), xmm5->as_VMReg()->next());
357 map->set_callee_saved(STACK_OFFSET(xmm6H_off ), xmm6->as_VMReg()->next());
358 map->set_callee_saved(STACK_OFFSET(xmm7H_off ), xmm7->as_VMReg()->next());
359 map->set_callee_saved(STACK_OFFSET(xmm8H_off ), xmm8->as_VMReg()->next());
360 map->set_callee_saved(STACK_OFFSET(xmm9H_off ), xmm9->as_VMReg()->next());
361 map->set_callee_saved(STACK_OFFSET(xmm10H_off), xmm10->as_VMReg()->next());
362 map->set_callee_saved(STACK_OFFSET(xmm11H_off), xmm11->as_VMReg()->next());
363 map->set_callee_saved(STACK_OFFSET(xmm12H_off), xmm12->as_VMReg()->next());
364 map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next());
365 map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next());
366 map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next());
367 if (UseAVX > 2) {
368 map->set_callee_saved(STACK_OFFSET(xmm16H_off), xmm16->as_VMReg());
369 map->set_callee_saved(STACK_OFFSET(xmm17H_off), xmm17->as_VMReg());
370 map->set_callee_saved(STACK_OFFSET(xmm18H_off), xmm18->as_VMReg());
371 map->set_callee_saved(STACK_OFFSET(xmm19H_off), xmm19->as_VMReg());
372 map->set_callee_saved(STACK_OFFSET(xmm20H_off), xmm20->as_VMReg());
373 map->set_callee_saved(STACK_OFFSET(xmm21H_off), xmm21->as_VMReg());
374 map->set_callee_saved(STACK_OFFSET(xmm22H_off), xmm22->as_VMReg());
375 map->set_callee_saved(STACK_OFFSET(xmm23H_off), xmm23->as_VMReg());
376 map->set_callee_saved(STACK_OFFSET(xmm24H_off), xmm24->as_VMReg());
377 map->set_callee_saved(STACK_OFFSET(xmm25H_off), xmm25->as_VMReg());
378 map->set_callee_saved(STACK_OFFSET(xmm26H_off), xmm26->as_VMReg());
379 map->set_callee_saved(STACK_OFFSET(xmm27H_off), xmm27->as_VMReg());
380 map->set_callee_saved(STACK_OFFSET(xmm28H_off), xmm28->as_VMReg());
381 map->set_callee_saved(STACK_OFFSET(xmm29H_off), xmm29->as_VMReg());
382 map->set_callee_saved(STACK_OFFSET(xmm30H_off), xmm30->as_VMReg());
383 map->set_callee_saved(STACK_OFFSET(xmm31H_off), xmm31->as_VMReg());
384 }
385 }
386
387 return map;
388 }
389
390 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
391 if (frame::arg_reg_save_area_bytes != 0) {
392 // Pop arg register save area
393 __ addptr(rsp, frame::arg_reg_save_area_bytes);
394 }
395 #ifdef COMPILER2
396 if (restore_vectors) {
397 // Restore upper half of YMM registes (0..15)
398 assert(UseAVX > 0, "512bit vectors are supported only with AVX");
399 assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
400 __ vinsertf128h(xmm0, Address(rsp, 0));
401 __ vinsertf128h(xmm1, Address(rsp, 16));
402 __ vinsertf128h(xmm2, Address(rsp, 32));
403 __ vinsertf128h(xmm3, Address(rsp, 48));
404 __ vinsertf128h(xmm4, Address(rsp, 64));
405 __ vinsertf128h(xmm5, Address(rsp, 80));
406 __ vinsertf128h(xmm6, Address(rsp, 96));
407 __ vinsertf128h(xmm7, Address(rsp,112));
408 __ vinsertf128h(xmm8, Address(rsp,128));
409 __ vinsertf128h(xmm9, Address(rsp,144));
410 __ vinsertf128h(xmm10, Address(rsp,160));
411 __ vinsertf128h(xmm11, Address(rsp,176));
412 __ vinsertf128h(xmm12, Address(rsp,192));
413 __ vinsertf128h(xmm13, Address(rsp,208));
414 __ vinsertf128h(xmm14, Address(rsp,224));
415 __ vinsertf128h(xmm15, Address(rsp,240));
416 __ addptr(rsp, 256);
417 if (UseAVX > 2) {
418 // Restore upper half of YMM registes (16..31)
419 __ vinsertf128h(xmm16, Address(rsp, 0));
420 __ vinsertf128h(xmm17, Address(rsp, 16));
421 __ vinsertf128h(xmm18, Address(rsp, 32));
422 __ vinsertf128h(xmm19, Address(rsp, 48));
423 __ vinsertf128h(xmm20, Address(rsp, 64));
424 __ vinsertf128h(xmm21, Address(rsp, 80));
425 __ vinsertf128h(xmm22, Address(rsp, 96));
426 __ vinsertf128h(xmm23, Address(rsp,112));
427 __ vinsertf128h(xmm24, Address(rsp,128));
428 __ vinsertf128h(xmm25, Address(rsp,144));
429 __ vinsertf128h(xmm26, Address(rsp,160));
430 __ vinsertf128h(xmm27, Address(rsp,176));
431 __ vinsertf128h(xmm28, Address(rsp,192));
432 __ vinsertf128h(xmm29, Address(rsp,208));
433 __ vinsertf128h(xmm30, Address(rsp,224));
434 __ vinsertf128h(xmm31, Address(rsp,240));
435 __ addptr(rsp, 256);
436 // Restore upper half of ZMM registes.
437 __ vinsertf64x4h(xmm0, Address(rsp, 0));
438 __ vinsertf64x4h(xmm1, Address(rsp, 32));
439 __ vinsertf64x4h(xmm2, Address(rsp, 64));
440 __ vinsertf64x4h(xmm3, Address(rsp, 96));
441 __ vinsertf64x4h(xmm4, Address(rsp, 128));
442 __ vinsertf64x4h(xmm5, Address(rsp, 160));
443 __ vinsertf64x4h(xmm6, Address(rsp, 192));
444 __ vinsertf64x4h(xmm7, Address(rsp, 224));
445 __ vinsertf64x4h(xmm8, Address(rsp, 256));
446 __ vinsertf64x4h(xmm9, Address(rsp, 288));
447 __ vinsertf64x4h(xmm10, Address(rsp, 320));
448 __ vinsertf64x4h(xmm11, Address(rsp, 352));
449 __ vinsertf64x4h(xmm12, Address(rsp, 384));
450 __ vinsertf64x4h(xmm13, Address(rsp, 416));
451 __ vinsertf64x4h(xmm14, Address(rsp, 448));
452 __ vinsertf64x4h(xmm15, Address(rsp, 480));
453 __ vinsertf64x4h(xmm16, Address(rsp, 512));
454 __ vinsertf64x4h(xmm17, Address(rsp, 544));
455 __ vinsertf64x4h(xmm18, Address(rsp, 576));
456 __ vinsertf64x4h(xmm19, Address(rsp, 608));
457 __ vinsertf64x4h(xmm20, Address(rsp, 640));
458 __ vinsertf64x4h(xmm21, Address(rsp, 672));
459 __ vinsertf64x4h(xmm22, Address(rsp, 704));
460 __ vinsertf64x4h(xmm23, Address(rsp, 736));
461 __ vinsertf64x4h(xmm24, Address(rsp, 768));
462 __ vinsertf64x4h(xmm25, Address(rsp, 800));
463 __ vinsertf64x4h(xmm26, Address(rsp, 832));
464 __ vinsertf64x4h(xmm27, Address(rsp, 864));
465 __ vinsertf64x4h(xmm28, Address(rsp, 896));
466 __ vinsertf64x4h(xmm29, Address(rsp, 928));
467 __ vinsertf64x4h(xmm30, Address(rsp, 960));
468 __ vinsertf64x4h(xmm31, Address(rsp, 992));
469 __ subptr(rsp, 1024);
470 }
471 }
472 #else
473 assert(!restore_vectors, "vectors are generated only by C2");
474 #endif
475 // Recover CPU state
476 __ pop_CPU_state();
477 // Get the rbp described implicitly by the calling convention (no oopMap)
478 __ pop(rbp);
479 }
480
481 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
482
483 // Just restore result register. Only used by deoptimization. By
484 // now any callee save register that needs to be restored to a c2
485 // caller of the deoptee has been extracted into the vframeArray
486 // and will be stuffed into the c2i adapter we create for later
487 // restoration so only result registers need to be restored here.
488
489 // Restore fp result register
490 __ movdbl(xmm0, Address(rsp, xmm0_offset_in_bytes()));
|