Mercurial > hg > graal-compiler
annotate src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 2013:ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
Summary: Implementation of the CAS primitive for x64 compressed oops was incorrect. It kills rscratch2 register (r11), which is allocatable in C1. Also, we don't need to restore cmpval as it's never used after that, so we need only one temporary register, which can be scratch1.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Wed, 08 Dec 2010 02:36:36 -0800 |
parents | 5ddfcf4b079e |
children | 037c727f35fb |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1491
diff
changeset
|
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1491
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1491
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1491
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_Compilation.hpp" | |
27 #include "c1/c1_LIRAssembler.hpp" | |
28 #include "c1/c1_MacroAssembler.hpp" | |
29 #include "c1/c1_Runtime1.hpp" | |
30 #include "c1/c1_ValueStack.hpp" | |
31 #include "ci/ciArrayKlass.hpp" | |
32 #include "ci/ciInstance.hpp" | |
33 #include "gc_interface/collectedHeap.hpp" | |
34 #include "memory/barrierSet.hpp" | |
35 #include "memory/cardTableModRefBS.hpp" | |
36 #include "nativeInst_x86.hpp" | |
37 #include "oops/objArrayKlass.hpp" | |
38 #include "runtime/sharedRuntime.hpp" | |
0 | 39 |
40 | |
41 // These masks are used to provide 128-bit aligned bitmasks to the XMM | |
42 // instructions, to allow sign-masking or sign-bit flipping. They allow | |
43 // fast versions of NegF/NegD and AbsF/AbsD. | |
44 | |
45 // Note: 'double' and 'long long' have 32-bits alignment on x86. | |
46 static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) { | |
47 // Use the expression (adr)&(~0xF) to provide 128-bits aligned address | |
48 // of 128-bits operands for SSE instructions. | |
49 jlong *operand = (jlong*)(((long)adr)&((long)(~0xF))); | |
50 // Store the value to a 128-bits operand. | |
51 operand[0] = lo; | |
52 operand[1] = hi; | |
53 return operand; | |
54 } | |
55 | |
56 // Buffer for 128-bits masks used by SSE instructions. | |
57 static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment) | |
58 | |
59 // Static initialization during VM startup. | |
60 static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF)); | |
61 static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF)); | |
62 static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000)); | |
63 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000)); | |
64 | |
65 | |
66 | |
67 NEEDS_CLEANUP // remove this definitions ? | |
68 const Register IC_Klass = rax; // where the IC klass is cached | |
69 const Register SYNC_header = rax; // synchronization header | |
70 const Register SHIFT_count = rcx; // where count for shift operations must be | |
71 | |
72 #define __ _masm-> | |
73 | |
74 | |
75 static void select_different_registers(Register preserve, | |
76 Register extra, | |
77 Register &tmp1, | |
78 Register &tmp2) { | |
79 if (tmp1 == preserve) { | |
80 assert_different_registers(tmp1, tmp2, extra); | |
81 tmp1 = extra; | |
82 } else if (tmp2 == preserve) { | |
83 assert_different_registers(tmp1, tmp2, extra); | |
84 tmp2 = extra; | |
85 } | |
86 assert_different_registers(preserve, tmp1, tmp2); | |
87 } | |
88 | |
89 | |
90 | |
91 static void select_different_registers(Register preserve, | |
92 Register extra, | |
93 Register &tmp1, | |
94 Register &tmp2, | |
95 Register &tmp3) { | |
96 if (tmp1 == preserve) { | |
97 assert_different_registers(tmp1, tmp2, tmp3, extra); | |
98 tmp1 = extra; | |
99 } else if (tmp2 == preserve) { | |
100 assert_different_registers(tmp1, tmp2, tmp3, extra); | |
101 tmp2 = extra; | |
102 } else if (tmp3 == preserve) { | |
103 assert_different_registers(tmp1, tmp2, tmp3, extra); | |
104 tmp3 = extra; | |
105 } | |
106 assert_different_registers(preserve, tmp1, tmp2, tmp3); | |
107 } | |
108 | |
109 | |
110 | |
111 bool LIR_Assembler::is_small_constant(LIR_Opr opr) { | |
112 if (opr->is_constant()) { | |
113 LIR_Const* constant = opr->as_constant_ptr(); | |
114 switch (constant->type()) { | |
115 case T_INT: { | |
116 return true; | |
117 } | |
118 | |
119 default: | |
120 return false; | |
121 } | |
122 } | |
123 return false; | |
124 } | |
125 | |
126 | |
127 LIR_Opr LIR_Assembler::receiverOpr() { | |
304 | 128 return FrameMap::receiver_opr; |
0 | 129 } |
130 | |
131 LIR_Opr LIR_Assembler::incomingReceiverOpr() { | |
132 return receiverOpr(); | |
133 } | |
134 | |
135 LIR_Opr LIR_Assembler::osrBufferPointer() { | |
304 | 136 return FrameMap::as_pointer_opr(receiverOpr()->as_register()); |
0 | 137 } |
138 | |
139 //--------------fpu register translations----------------------- | |
140 | |
141 | |
142 address LIR_Assembler::float_constant(float f) { | |
143 address const_addr = __ float_constant(f); | |
144 if (const_addr == NULL) { | |
145 bailout("const section overflow"); | |
146 return __ code()->consts()->start(); | |
147 } else { | |
148 return const_addr; | |
149 } | |
150 } | |
151 | |
152 | |
153 address LIR_Assembler::double_constant(double d) { | |
154 address const_addr = __ double_constant(d); | |
155 if (const_addr == NULL) { | |
156 bailout("const section overflow"); | |
157 return __ code()->consts()->start(); | |
158 } else { | |
159 return const_addr; | |
160 } | |
161 } | |
162 | |
163 | |
164 void LIR_Assembler::set_24bit_FPU() { | |
165 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); | |
166 } | |
167 | |
168 void LIR_Assembler::reset_FPU() { | |
169 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); | |
170 } | |
171 | |
172 void LIR_Assembler::fpop() { | |
173 __ fpop(); | |
174 } | |
175 | |
176 void LIR_Assembler::fxch(int i) { | |
177 __ fxch(i); | |
178 } | |
179 | |
180 void LIR_Assembler::fld(int i) { | |
181 __ fld_s(i); | |
182 } | |
183 | |
184 void LIR_Assembler::ffree(int i) { | |
185 __ ffree(i); | |
186 } | |
187 | |
188 void LIR_Assembler::breakpoint() { | |
189 __ int3(); | |
190 } | |
191 | |
192 void LIR_Assembler::push(LIR_Opr opr) { | |
193 if (opr->is_single_cpu()) { | |
194 __ push_reg(opr->as_register()); | |
195 } else if (opr->is_double_cpu()) { | |
304 | 196 NOT_LP64(__ push_reg(opr->as_register_hi())); |
0 | 197 __ push_reg(opr->as_register_lo()); |
198 } else if (opr->is_stack()) { | |
199 __ push_addr(frame_map()->address_for_slot(opr->single_stack_ix())); | |
200 } else if (opr->is_constant()) { | |
201 LIR_Const* const_opr = opr->as_constant_ptr(); | |
202 if (const_opr->type() == T_OBJECT) { | |
203 __ push_oop(const_opr->as_jobject()); | |
204 } else if (const_opr->type() == T_INT) { | |
205 __ push_jint(const_opr->as_jint()); | |
206 } else { | |
207 ShouldNotReachHere(); | |
208 } | |
209 | |
210 } else { | |
211 ShouldNotReachHere(); | |
212 } | |
213 } | |
214 | |
215 void LIR_Assembler::pop(LIR_Opr opr) { | |
216 if (opr->is_single_cpu()) { | |
304 | 217 __ pop_reg(opr->as_register()); |
0 | 218 } else { |
219 ShouldNotReachHere(); | |
220 } | |
221 } | |
222 | |
304 | 223 bool LIR_Assembler::is_literal_address(LIR_Address* addr) { |
224 return addr->base()->is_illegal() && addr->index()->is_illegal(); | |
225 } | |
226 | |
0 | 227 //------------------------------------------- |
304 | 228 |
0 | 229 Address LIR_Assembler::as_Address(LIR_Address* addr) { |
304 | 230 return as_Address(addr, rscratch1); |
231 } | |
232 | |
233 Address LIR_Assembler::as_Address(LIR_Address* addr, Register tmp) { | |
0 | 234 if (addr->base()->is_illegal()) { |
235 assert(addr->index()->is_illegal(), "must be illegal too"); | |
304 | 236 AddressLiteral laddr((address)addr->disp(), relocInfo::none); |
237 if (! __ reachable(laddr)) { | |
238 __ movptr(tmp, laddr.addr()); | |
239 Address res(tmp, 0); | |
240 return res; | |
241 } else { | |
242 return __ as_Address(laddr); | |
243 } | |
0 | 244 } |
245 | |
304 | 246 Register base = addr->base()->as_pointer_register(); |
0 | 247 |
248 if (addr->index()->is_illegal()) { | |
249 return Address( base, addr->disp()); | |
304 | 250 } else if (addr->index()->is_cpu_register()) { |
251 Register index = addr->index()->as_pointer_register(); | |
0 | 252 return Address(base, index, (Address::ScaleFactor) addr->scale(), addr->disp()); |
253 } else if (addr->index()->is_constant()) { | |
304 | 254 intptr_t addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp(); |
255 assert(Assembler::is_simm32(addr_offset), "must be"); | |
0 | 256 |
257 return Address(base, addr_offset); | |
258 } else { | |
259 Unimplemented(); | |
260 return Address(); | |
261 } | |
262 } | |
263 | |
264 | |
265 Address LIR_Assembler::as_Address_hi(LIR_Address* addr) { | |
266 Address base = as_Address(addr); | |
267 return Address(base._base, base._index, base._scale, base._disp + BytesPerWord); | |
268 } | |
269 | |
270 | |
271 Address LIR_Assembler::as_Address_lo(LIR_Address* addr) { | |
272 return as_Address(addr); | |
273 } | |
274 | |
275 | |
276 void LIR_Assembler::osr_entry() { | |
277 offsets()->set_value(CodeOffsets::OSR_Entry, code_offset()); | |
278 BlockBegin* osr_entry = compilation()->hir()->osr_entry(); | |
279 ValueStack* entry_state = osr_entry->state(); | |
280 int number_of_locks = entry_state->locks_size(); | |
281 | |
282 // we jump here if osr happens with the interpreter | |
283 // state set up to continue at the beginning of the | |
284 // loop that triggered osr - in particular, we have | |
285 // the following registers setup: | |
286 // | |
287 // rcx: osr buffer | |
288 // | |
289 | |
290 // build frame | |
291 ciMethod* m = compilation()->method(); | |
292 __ build_frame(initial_frame_size_in_bytes()); | |
293 | |
294 // OSR buffer is | |
295 // | |
296 // locals[nlocals-1..0] | |
297 // monitors[0..number_of_locks] | |
298 // | |
299 // locals is a direct copy of the interpreter frame so in the osr buffer | |
300 // so first slot in the local array is the last local from the interpreter | |
301 // and last slot is local[0] (receiver) from the interpreter | |
302 // | |
303 // Similarly with locks. The first lock slot in the osr buffer is the nth lock | |
304 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock | |
305 // in the interpreter frame (the method lock if a sync method) | |
306 | |
307 // Initialize monitors in the compiled activation. | |
308 // rcx: pointer to osr buffer | |
309 // | |
310 // All other registers are dead at this point and the locals will be | |
311 // copied into place by code emitted in the IR. | |
312 | |
304 | 313 Register OSR_buf = osrBufferPointer()->as_pointer_register(); |
0 | 314 { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below"); |
315 int monitor_offset = BytesPerWord * method()->max_locals() + | |
1060 | 316 (2 * BytesPerWord) * (number_of_locks - 1); |
317 // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in | |
318 // the OSR buffer using 2 word entries: first the lock and then | |
319 // the oop. | |
0 | 320 for (int i = 0; i < number_of_locks; i++) { |
1060 | 321 int slot_offset = monitor_offset - ((i * 2) * BytesPerWord); |
0 | 322 #ifdef ASSERT |
323 // verify the interpreter's monitor has a non-null object | |
324 { | |
325 Label L; | |
1060 | 326 __ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD); |
0 | 327 __ jcc(Assembler::notZero, L); |
328 __ stop("locked object is NULL"); | |
329 __ bind(L); | |
330 } | |
331 #endif | |
1060 | 332 __ movptr(rbx, Address(OSR_buf, slot_offset + 0)); |
304 | 333 __ movptr(frame_map()->address_for_monitor_lock(i), rbx); |
1060 | 334 __ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord)); |
304 | 335 __ movptr(frame_map()->address_for_monitor_object(i), rbx); |
0 | 336 } |
337 } | |
338 } | |
339 | |
340 | |
341 // inline cache check; done before the frame is built. | |
342 int LIR_Assembler::check_icache() { | |
343 Register receiver = FrameMap::receiver_opr->as_register(); | |
344 Register ic_klass = IC_Klass; | |
304 | 345 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); |
2002 | 346 const bool do_post_padding = VerifyOops || UseCompressedOops; |
347 if (!do_post_padding) { | |
0 | 348 // insert some nops so that the verified entry point is aligned on CodeEntryAlignment |
304 | 349 while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { |
0 | 350 __ nop(); |
351 } | |
352 } | |
353 int offset = __ offset(); | |
354 __ inline_cache_check(receiver, IC_Klass); | |
2002 | 355 assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct"); |
356 if (do_post_padding) { | |
0 | 357 // force alignment after the cache check. |
358 // It's been verified to be aligned if !VerifyOops | |
359 __ align(CodeEntryAlignment); | |
360 } | |
361 return offset; | |
362 } | |
363 | |
364 | |
365 void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) { | |
366 jobject o = NULL; | |
367 PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id); | |
368 __ movoop(reg, o); | |
369 patching_epilog(patch, lir_patch_normal, reg, info); | |
370 } | |
371 | |
372 | |
373 void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_hdr, int monitor_no, Register exception) { | |
374 if (exception->is_valid()) { | |
375 // preserve exception | |
376 // note: the monitor_exit runtime call is a leaf routine | |
377 // and cannot block => no GC can happen | |
378 // The slow case (MonitorAccessStub) uses the first two stack slots | |
379 // ([esp+0] and [esp+4]), therefore we store the exception at [esp+8] | |
304 | 380 __ movptr (Address(rsp, 2*wordSize), exception); |
0 | 381 } |
382 | |
383 Register obj_reg = obj_opr->as_register(); | |
384 Register lock_reg = lock_opr->as_register(); | |
385 | |
386 // setup registers (lock_reg must be rax, for lock_object) | |
387 assert(obj_reg != SYNC_header && lock_reg != SYNC_header, "rax, must be available here"); | |
388 Register hdr = lock_reg; | |
389 assert(new_hdr == SYNC_header, "wrong register"); | |
390 lock_reg = new_hdr; | |
391 // compute pointer to BasicLock | |
392 Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no); | |
304 | 393 __ lea(lock_reg, lock_addr); |
0 | 394 // unlock object |
395 MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no); | |
396 // _slow_case_stubs->append(slow_case); | |
397 // temporary fix: must be created after exceptionhandler, therefore as call stub | |
398 _slow_case_stubs->append(slow_case); | |
399 if (UseFastLocking) { | |
400 // try inlined fast unlocking first, revert to slow locking if it fails | |
401 // note: lock_reg points to the displaced header since the displaced header offset is 0! | |
402 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); | |
403 __ unlock_object(hdr, obj_reg, lock_reg, *slow_case->entry()); | |
404 } else { | |
405 // always do slow unlocking | |
406 // note: the slow unlocking code could be inlined here, however if we use | |
407 // slow unlocking, speed doesn't matter anyway and this solution is | |
408 // simpler and requires less duplicated code - additionally, the | |
409 // slow unlocking code is the same in either case which simplifies | |
410 // debugging | |
411 __ jmp(*slow_case->entry()); | |
412 } | |
413 // done | |
414 __ bind(*slow_case->continuation()); | |
415 | |
416 if (exception->is_valid()) { | |
417 // restore exception | |
304 | 418 __ movptr (exception, Address(rsp, 2 * wordSize)); |
0 | 419 } |
420 } | |
421 | |
422 // This specifies the rsp decrement needed to build the frame | |
423 int LIR_Assembler::initial_frame_size_in_bytes() { | |
424 // if rounding, must let FrameMap know! | |
304 | 425 |
426 // The frame_map records size in slots (32bit word) | |
427 | |
428 // subtract two words to account for return address and link | |
429 return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word)) * VMRegImpl::stack_slot_size; | |
0 | 430 } |
431 | |
432 | |
1204 | 433 int LIR_Assembler::emit_exception_handler() { |
0 | 434 // if the last instruction is a call (typically to do a throw which |
435 // is coming at the end after block reordering) the return address | |
436 // must still point into the code area in order to avoid assertion | |
437 // failures when searching for the corresponding bci => add a nop | |
438 // (was bug 5/14/1999 - gri) | |
439 __ nop(); | |
440 | |
441 // generate code for exception handler | |
442 address handler_base = __ start_a_stub(exception_handler_size); | |
443 if (handler_base == NULL) { | |
444 // not enough space left for the handler | |
445 bailout("exception handler overflow"); | |
1204 | 446 return -1; |
0 | 447 } |
1204 | 448 |
0 | 449 int offset = code_offset(); |
450 | |
1295 | 451 // the exception oop and pc are in rax, and rdx |
0 | 452 // no other registers need to be preserved, so invalidate them |
1295 | 453 __ invalidate_registers(false, true, true, false, true, true); |
0 | 454 |
455 // check that there is really an exception | |
456 __ verify_not_null_oop(rax); | |
457 | |
1295 | 458 // search an exception handler (rax: exception oop, rdx: throwing pc) |
459 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); | |
460 | |
461 __ stop("should not reach here"); | |
462 | |
0 | 463 assert(code_offset() - offset <= exception_handler_size, "overflow"); |
464 __ end_a_stub(); | |
1204 | 465 |
466 return offset; | |
0 | 467 } |
468 | |
1204 | 469 |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
470 // Emit the code to remove the frame from the stack in the exception |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
471 // unwind path. |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
472 int LIR_Assembler::emit_unwind_handler() { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
473 #ifndef PRODUCT |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
474 if (CommentedAssembly) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
475 _masm->block_comment("Unwind handler"); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
476 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
477 #endif |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
478 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
479 int offset = code_offset(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
480 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
481 // Fetch the exception from TLS and clear out exception related thread state |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
482 __ get_thread(rsi); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
483 __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
484 __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
485 __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
486 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
487 __ bind(_unwind_handler_entry); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
488 __ verify_not_null_oop(rax); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
489 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
490 __ mov(rsi, rax); // Preserve the exception |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
491 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
492 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
493 // Preform needed unlocking |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
494 MonitorExitStub* stub = NULL; |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
495 if (method()->is_synchronized()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
496 monitor_address(0, FrameMap::rax_opr); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
497 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
498 __ unlock_object(rdi, rbx, rax, *stub->entry()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
499 __ bind(*stub->continuation()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
500 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
501 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
502 if (compilation()->env()->dtrace_method_probes()) { |
1830
a3f7f95b0165
6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents:
1791
diff
changeset
|
503 __ get_thread(rax); |
a3f7f95b0165
6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents:
1791
diff
changeset
|
504 __ movptr(Address(rsp, 0), rax); |
a3f7f95b0165
6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents:
1791
diff
changeset
|
505 __ movoop(Address(rsp, sizeof(void*)), method()->constant_encoding()); |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
506 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
507 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
508 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
509 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
510 __ mov(rax, rsi); // Restore the exception |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
511 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
512 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
513 // remove the activation and dispatch to the unwind handler |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
514 __ remove_frame(initial_frame_size_in_bytes()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
515 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
516 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
517 // Emit the slow path assembly |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
518 if (stub != NULL) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
519 stub->emit_code(this); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
520 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
521 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
522 return offset; |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
523 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
524 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
525 |
1204 | 526 int LIR_Assembler::emit_deopt_handler() { |
0 | 527 // if the last instruction is a call (typically to do a throw which |
528 // is coming at the end after block reordering) the return address | |
529 // must still point into the code area in order to avoid assertion | |
530 // failures when searching for the corresponding bci => add a nop | |
531 // (was bug 5/14/1999 - gri) | |
532 __ nop(); | |
533 | |
534 // generate code for exception handler | |
535 address handler_base = __ start_a_stub(deopt_handler_size); | |
536 if (handler_base == NULL) { | |
537 // not enough space left for the handler | |
538 bailout("deopt handler overflow"); | |
1204 | 539 return -1; |
0 | 540 } |
1204 | 541 |
0 | 542 int offset = code_offset(); |
543 InternalAddress here(__ pc()); | |
1295 | 544 |
0 | 545 __ pushptr(here.addr()); |
546 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); | |
1295 | 547 |
0 | 548 assert(code_offset() - offset <= deopt_handler_size, "overflow"); |
549 __ end_a_stub(); | |
550 | |
1204 | 551 return offset; |
0 | 552 } |
553 | |
554 | |
555 // This is the fast version of java.lang.String.compare; it has not | |
556 // OSR-entry and therefore, we generate a slow version for OSR's | |
557 void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) { | |
304 | 558 __ movptr (rbx, rcx); // receiver is in rcx |
559 __ movptr (rax, arg1->as_register()); | |
0 | 560 |
561 // Get addresses of first characters from both Strings | |
2002 | 562 __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes())); |
563 __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); | |
564 __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); | |
0 | 565 |
566 | |
567 // rbx, may be NULL | |
568 add_debug_info_for_null_check_here(info); | |
2002 | 569 __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); |
570 __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); | |
571 __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); | |
0 | 572 |
573 // compute minimum length (in rax) and difference of lengths (on top of stack) | |
574 if (VM_Version::supports_cmov()) { | |
304 | 575 __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); |
576 __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); | |
577 __ mov (rcx, rbx); | |
578 __ subptr (rbx, rax); // subtract lengths | |
579 __ push (rbx); // result | |
580 __ cmov (Assembler::lessEqual, rax, rcx); | |
0 | 581 } else { |
582 Label L; | |
304 | 583 __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); |
584 __ movl (rcx, Address(rax, java_lang_String::count_offset_in_bytes())); | |
585 __ mov (rax, rbx); | |
586 __ subptr (rbx, rcx); | |
587 __ push (rbx); | |
588 __ jcc (Assembler::lessEqual, L); | |
589 __ mov (rax, rcx); | |
0 | 590 __ bind (L); |
591 } | |
592 // is minimum length 0? | |
593 Label noLoop, haveResult; | |
304 | 594 __ testptr (rax, rax); |
0 | 595 __ jcc (Assembler::zero, noLoop); |
596 | |
597 // compare first characters | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
512
diff
changeset
|
598 __ load_unsigned_short(rcx, Address(rdi, 0)); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
512
diff
changeset
|
599 __ load_unsigned_short(rbx, Address(rsi, 0)); |
0 | 600 __ subl(rcx, rbx); |
601 __ jcc(Assembler::notZero, haveResult); | |
602 // starting loop | |
603 __ decrement(rax); // we already tested index: skip one | |
604 __ jcc(Assembler::zero, noLoop); | |
605 | |
606 // set rsi.edi to the end of the arrays (arrays have same length) | |
607 // negate the index | |
608 | |
304 | 609 __ lea(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); |
610 __ lea(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); | |
611 __ negptr(rax); | |
0 | 612 |
613 // compare the strings in a loop | |
614 | |
615 Label loop; | |
616 __ align(wordSize); | |
617 __ bind(loop); | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
512
diff
changeset
|
618 __ load_unsigned_short(rcx, Address(rdi, rax, Address::times_2, 0)); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
512
diff
changeset
|
619 __ load_unsigned_short(rbx, Address(rsi, rax, Address::times_2, 0)); |
0 | 620 __ subl(rcx, rbx); |
621 __ jcc(Assembler::notZero, haveResult); | |
622 __ increment(rax); | |
623 __ jcc(Assembler::notZero, loop); | |
624 | |
625 // strings are equal up to min length | |
626 | |
627 __ bind(noLoop); | |
304 | 628 __ pop(rax); |
0 | 629 return_op(LIR_OprFact::illegalOpr); |
630 | |
631 __ bind(haveResult); | |
632 // leave instruction is going to discard the TOS value | |
304 | 633 __ mov (rax, rcx); // result of call is in rax, |
0 | 634 } |
635 | |
636 | |
637 void LIR_Assembler::return_op(LIR_Opr result) { | |
638 assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == rax, "word returns are in rax,"); | |
639 if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) { | |
640 assert(result->fpu() == 0, "result must already be on TOS"); | |
641 } | |
642 | |
643 // Pop the stack before the safepoint code | |
1295 | 644 __ remove_frame(initial_frame_size_in_bytes()); |
0 | 645 |
646 bool result_is_oop = result->is_valid() ? result->is_oop() : false; | |
647 | |
648 // Note: we do not need to round double result; float result has the right precision | |
649 // the poll sets the condition code, but no data registers | |
650 AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()), | |
651 relocInfo::poll_return_type); | |
304 | 652 |
653 // NOTE: the requires that the polling page be reachable else the reloc | |
654 // goes to the movq that loads the address and not the faulting instruction | |
655 // which breaks the signal handler code | |
656 | |
0 | 657 __ test32(rax, polling_page); |
658 | |
659 __ ret(0); | |
660 } | |
661 | |
662 | |
663 int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { | |
664 AddressLiteral polling_page(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()), | |
665 relocInfo::poll_type); | |
666 | |
667 if (info != NULL) { | |
668 add_debug_info_for_branch(info); | |
669 } else { | |
670 ShouldNotReachHere(); | |
671 } | |
672 | |
673 int offset = __ offset(); | |
304 | 674 |
675 // NOTE: the requires that the polling page be reachable else the reloc | |
676 // goes to the movq that loads the address and not the faulting instruction | |
677 // which breaks the signal handler code | |
678 | |
0 | 679 __ test32(rax, polling_page); |
680 return offset; | |
681 } | |
682 | |
683 | |
684 void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { | |
304 | 685 if (from_reg != to_reg) __ mov(to_reg, from_reg); |
0 | 686 } |
687 | |
688 void LIR_Assembler::swap_reg(Register a, Register b) { | |
304 | 689 __ xchgptr(a, b); |
0 | 690 } |
691 | |
692 | |
693 void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) { | |
694 assert(src->is_constant(), "should not call otherwise"); | |
695 assert(dest->is_register(), "should not call otherwise"); | |
696 LIR_Const* c = src->as_constant_ptr(); | |
697 | |
698 switch (c->type()) { | |
2002 | 699 case T_INT: { |
700 assert(patch_code == lir_patch_none, "no patching handled here"); | |
701 __ movl(dest->as_register(), c->as_jint()); | |
702 break; | |
703 } | |
704 | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
705 case T_ADDRESS: { |
0 | 706 assert(patch_code == lir_patch_none, "no patching handled here"); |
2002 | 707 __ movptr(dest->as_register(), c->as_jint()); |
0 | 708 break; |
709 } | |
710 | |
711 case T_LONG: { | |
712 assert(patch_code == lir_patch_none, "no patching handled here"); | |
304 | 713 #ifdef _LP64 |
714 __ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong()); | |
715 #else | |
716 __ movptr(dest->as_register_lo(), c->as_jint_lo()); | |
717 __ movptr(dest->as_register_hi(), c->as_jint_hi()); | |
718 #endif // _LP64 | |
0 | 719 break; |
720 } | |
721 | |
722 case T_OBJECT: { | |
723 if (patch_code != lir_patch_none) { | |
724 jobject2reg_with_patching(dest->as_register(), info); | |
725 } else { | |
726 __ movoop(dest->as_register(), c->as_jobject()); | |
727 } | |
728 break; | |
729 } | |
730 | |
731 case T_FLOAT: { | |
732 if (dest->is_single_xmm()) { | |
733 if (c->is_zero_float()) { | |
734 __ xorps(dest->as_xmm_float_reg(), dest->as_xmm_float_reg()); | |
735 } else { | |
736 __ movflt(dest->as_xmm_float_reg(), | |
737 InternalAddress(float_constant(c->as_jfloat()))); | |
738 } | |
739 } else { | |
740 assert(dest->is_single_fpu(), "must be"); | |
741 assert(dest->fpu_regnr() == 0, "dest must be TOS"); | |
742 if (c->is_zero_float()) { | |
743 __ fldz(); | |
744 } else if (c->is_one_float()) { | |
745 __ fld1(); | |
746 } else { | |
747 __ fld_s (InternalAddress(float_constant(c->as_jfloat()))); | |
748 } | |
749 } | |
750 break; | |
751 } | |
752 | |
753 case T_DOUBLE: { | |
754 if (dest->is_double_xmm()) { | |
755 if (c->is_zero_double()) { | |
756 __ xorpd(dest->as_xmm_double_reg(), dest->as_xmm_double_reg()); | |
757 } else { | |
758 __ movdbl(dest->as_xmm_double_reg(), | |
759 InternalAddress(double_constant(c->as_jdouble()))); | |
760 } | |
761 } else { | |
762 assert(dest->is_double_fpu(), "must be"); | |
763 assert(dest->fpu_regnrLo() == 0, "dest must be TOS"); | |
764 if (c->is_zero_double()) { | |
765 __ fldz(); | |
766 } else if (c->is_one_double()) { | |
767 __ fld1(); | |
768 } else { | |
769 __ fld_d (InternalAddress(double_constant(c->as_jdouble()))); | |
770 } | |
771 } | |
772 break; | |
773 } | |
774 | |
775 default: | |
776 ShouldNotReachHere(); | |
777 } | |
778 } | |
779 | |
780 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) { | |
781 assert(src->is_constant(), "should not call otherwise"); | |
782 assert(dest->is_stack(), "should not call otherwise"); | |
783 LIR_Const* c = src->as_constant_ptr(); | |
784 | |
785 switch (c->type()) { | |
786 case T_INT: // fall through | |
787 case T_FLOAT: | |
2002 | 788 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); |
789 break; | |
790 | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
791 case T_ADDRESS: |
2002 | 792 __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); |
0 | 793 break; |
794 | |
795 case T_OBJECT: | |
796 __ movoop(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jobject()); | |
797 break; | |
798 | |
799 case T_LONG: // fall through | |
800 case T_DOUBLE: | |
304 | 801 #ifdef _LP64 |
802 __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), | |
803 lo_word_offset_in_bytes), (intptr_t)c->as_jlong_bits()); | |
804 #else | |
805 __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), | |
806 lo_word_offset_in_bytes), c->as_jint_lo_bits()); | |
807 __ movptr(frame_map()->address_for_slot(dest->double_stack_ix(), | |
808 hi_word_offset_in_bytes), c->as_jint_hi_bits()); | |
809 #endif // _LP64 | |
0 | 810 break; |
811 | |
812 default: | |
813 ShouldNotReachHere(); | |
814 } | |
815 } | |
816 | |
2002 | 817 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { |
0 | 818 assert(src->is_constant(), "should not call otherwise"); |
819 assert(dest->is_address(), "should not call otherwise"); | |
820 LIR_Const* c = src->as_constant_ptr(); | |
821 LIR_Address* addr = dest->as_address_ptr(); | |
822 | |
304 | 823 int null_check_here = code_offset(); |
0 | 824 switch (type) { |
825 case T_INT: // fall through | |
826 case T_FLOAT: | |
2002 | 827 __ movl(as_Address(addr), c->as_jint_bits()); |
828 break; | |
829 | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1295
diff
changeset
|
830 case T_ADDRESS: |
2002 | 831 __ movptr(as_Address(addr), c->as_jint_bits()); |
0 | 832 break; |
833 | |
834 case T_OBJECT: // fall through | |
835 case T_ARRAY: | |
836 if (c->as_jobject() == NULL) { | |
2002 | 837 if (UseCompressedOops && !wide) { |
838 __ movl(as_Address(addr), (int32_t)NULL_WORD); | |
839 } else { | |
840 __ movptr(as_Address(addr), NULL_WORD); | |
841 } | |
0 | 842 } else { |
304 | 843 if (is_literal_address(addr)) { |
844 ShouldNotReachHere(); | |
845 __ movoop(as_Address(addr, noreg), c->as_jobject()); | |
846 } else { | |
1060 | 847 #ifdef _LP64 |
848 __ movoop(rscratch1, c->as_jobject()); | |
2002 | 849 if (UseCompressedOops && !wide) { |
850 __ encode_heap_oop(rscratch1); | |
851 null_check_here = code_offset(); | |
852 __ movl(as_Address_lo(addr), rscratch1); | |
853 } else { | |
854 null_check_here = code_offset(); | |
855 __ movptr(as_Address_lo(addr), rscratch1); | |
856 } | |
1060 | 857 #else |
304 | 858 __ movoop(as_Address(addr), c->as_jobject()); |
1060 | 859 #endif |
304 | 860 } |
0 | 861 } |
862 break; | |
863 | |
864 case T_LONG: // fall through | |
865 case T_DOUBLE: | |
304 | 866 #ifdef _LP64 |
867 if (is_literal_address(addr)) { | |
868 ShouldNotReachHere(); | |
869 __ movptr(as_Address(addr, r15_thread), (intptr_t)c->as_jlong_bits()); | |
870 } else { | |
871 __ movptr(r10, (intptr_t)c->as_jlong_bits()); | |
872 null_check_here = code_offset(); | |
873 __ movptr(as_Address_lo(addr), r10); | |
874 } | |
875 #else | |
876 // Always reachable in 32bit so this doesn't produce useless move literal | |
877 __ movptr(as_Address_hi(addr), c->as_jint_hi_bits()); | |
878 __ movptr(as_Address_lo(addr), c->as_jint_lo_bits()); | |
879 #endif // _LP64 | |
0 | 880 break; |
881 | |
882 case T_BOOLEAN: // fall through | |
883 case T_BYTE: | |
884 __ movb(as_Address(addr), c->as_jint() & 0xFF); | |
885 break; | |
886 | |
887 case T_CHAR: // fall through | |
888 case T_SHORT: | |
889 __ movw(as_Address(addr), c->as_jint() & 0xFFFF); | |
890 break; | |
891 | |
892 default: | |
893 ShouldNotReachHere(); | |
894 }; | |
304 | 895 |
896 if (info != NULL) { | |
897 add_debug_info_for_null_check(null_check_here, info); | |
898 } | |
0 | 899 } |
900 | |
901 | |
902 void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) { | |
903 assert(src->is_register(), "should not call otherwise"); | |
904 assert(dest->is_register(), "should not call otherwise"); | |
905 | |
906 // move between cpu-registers | |
907 if (dest->is_single_cpu()) { | |
304 | 908 #ifdef _LP64 |
909 if (src->type() == T_LONG) { | |
910 // Can do LONG -> OBJECT | |
911 move_regs(src->as_register_lo(), dest->as_register()); | |
912 return; | |
913 } | |
914 #endif | |
0 | 915 assert(src->is_single_cpu(), "must match"); |
916 if (src->type() == T_OBJECT) { | |
917 __ verify_oop(src->as_register()); | |
918 } | |
919 move_regs(src->as_register(), dest->as_register()); | |
920 | |
921 } else if (dest->is_double_cpu()) { | |
304 | 922 #ifdef _LP64 |
923 if (src->type() == T_OBJECT || src->type() == T_ARRAY) { | |
924 // Surprising to me but we can see move of a long to t_object | |
925 __ verify_oop(src->as_register()); | |
926 move_regs(src->as_register(), dest->as_register_lo()); | |
927 return; | |
928 } | |
929 #endif | |
0 | 930 assert(src->is_double_cpu(), "must match"); |
931 Register f_lo = src->as_register_lo(); | |
932 Register f_hi = src->as_register_hi(); | |
933 Register t_lo = dest->as_register_lo(); | |
934 Register t_hi = dest->as_register_hi(); | |
304 | 935 #ifdef _LP64 |
936 assert(f_hi == f_lo, "must be same"); | |
937 assert(t_hi == t_lo, "must be same"); | |
938 move_regs(f_lo, t_lo); | |
939 #else | |
0 | 940 assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation"); |
941 | |
304 | 942 |
0 | 943 if (f_lo == t_hi && f_hi == t_lo) { |
944 swap_reg(f_lo, f_hi); | |
945 } else if (f_hi == t_lo) { | |
946 assert(f_lo != t_hi, "overwriting register"); | |
947 move_regs(f_hi, t_hi); | |
948 move_regs(f_lo, t_lo); | |
949 } else { | |
950 assert(f_hi != t_lo, "overwriting register"); | |
951 move_regs(f_lo, t_lo); | |
952 move_regs(f_hi, t_hi); | |
953 } | |
304 | 954 #endif // LP64 |
0 | 955 |
956 // special moves from fpu-register to xmm-register | |
957 // necessary for method results | |
958 } else if (src->is_single_xmm() && !dest->is_single_xmm()) { | |
959 __ movflt(Address(rsp, 0), src->as_xmm_float_reg()); | |
960 __ fld_s(Address(rsp, 0)); | |
961 } else if (src->is_double_xmm() && !dest->is_double_xmm()) { | |
962 __ movdbl(Address(rsp, 0), src->as_xmm_double_reg()); | |
963 __ fld_d(Address(rsp, 0)); | |
964 } else if (dest->is_single_xmm() && !src->is_single_xmm()) { | |
965 __ fstp_s(Address(rsp, 0)); | |
966 __ movflt(dest->as_xmm_float_reg(), Address(rsp, 0)); | |
967 } else if (dest->is_double_xmm() && !src->is_double_xmm()) { | |
968 __ fstp_d(Address(rsp, 0)); | |
969 __ movdbl(dest->as_xmm_double_reg(), Address(rsp, 0)); | |
970 | |
971 // move between xmm-registers | |
972 } else if (dest->is_single_xmm()) { | |
973 assert(src->is_single_xmm(), "must match"); | |
974 __ movflt(dest->as_xmm_float_reg(), src->as_xmm_float_reg()); | |
975 } else if (dest->is_double_xmm()) { | |
976 assert(src->is_double_xmm(), "must match"); | |
977 __ movdbl(dest->as_xmm_double_reg(), src->as_xmm_double_reg()); | |
978 | |
979 // move between fpu-registers (no instruction necessary because of fpu-stack) | |
980 } else if (dest->is_single_fpu() || dest->is_double_fpu()) { | |
981 assert(src->is_single_fpu() || src->is_double_fpu(), "must match"); | |
982 assert(src->fpu() == dest->fpu(), "currently should be nothing to do"); | |
983 } else { | |
984 ShouldNotReachHere(); | |
985 } | |
986 } | |
987 | |
988 void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) { | |
989 assert(src->is_register(), "should not call otherwise"); | |
990 assert(dest->is_stack(), "should not call otherwise"); | |
991 | |
992 if (src->is_single_cpu()) { | |
993 Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); | |
994 if (type == T_OBJECT || type == T_ARRAY) { | |
995 __ verify_oop(src->as_register()); | |
304 | 996 __ movptr (dst, src->as_register()); |
997 } else { | |
998 __ movl (dst, src->as_register()); | |
0 | 999 } |
1000 | |
1001 } else if (src->is_double_cpu()) { | |
1002 Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes); | |
1003 Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes); | |
304 | 1004 __ movptr (dstLO, src->as_register_lo()); |
1005 NOT_LP64(__ movptr (dstHI, src->as_register_hi())); | |
0 | 1006 |
1007 } else if (src->is_single_xmm()) { | |
1008 Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1009 __ movflt(dst_addr, src->as_xmm_float_reg()); | |
1010 | |
1011 } else if (src->is_double_xmm()) { | |
1012 Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix()); | |
1013 __ movdbl(dst_addr, src->as_xmm_double_reg()); | |
1014 | |
1015 } else if (src->is_single_fpu()) { | |
1016 assert(src->fpu_regnr() == 0, "argument must be on TOS"); | |
1017 Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix()); | |
1018 if (pop_fpu_stack) __ fstp_s (dst_addr); | |
1019 else __ fst_s (dst_addr); | |
1020 | |
1021 } else if (src->is_double_fpu()) { | |
1022 assert(src->fpu_regnrLo() == 0, "argument must be on TOS"); | |
1023 Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix()); | |
1024 if (pop_fpu_stack) __ fstp_d (dst_addr); | |
1025 else __ fst_d (dst_addr); | |
1026 | |
1027 } else { | |
1028 ShouldNotReachHere(); | |
1029 } | |
1030 } | |
1031 | |
1032 | |
2002 | 1033 void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) { |
0 | 1034 LIR_Address* to_addr = dest->as_address_ptr(); |
1035 PatchingStub* patch = NULL; | |
2002 | 1036 Register compressed_src = rscratch1; |
0 | 1037 |
1038 if (type == T_ARRAY || type == T_OBJECT) { | |
1039 __ verify_oop(src->as_register()); | |
2002 | 1040 #ifdef _LP64 |
1041 if (UseCompressedOops && !wide) { | |
1042 __ movptr(compressed_src, src->as_register()); | |
1043 __ encode_heap_oop(compressed_src); | |
1044 } | |
1045 #endif | |
0 | 1046 } |
2002 | 1047 |
0 | 1048 if (patch_code != lir_patch_none) { |
1049 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
304 | 1050 Address toa = as_Address(to_addr); |
1051 assert(toa.disp() != 0, "must have"); | |
0 | 1052 } |
2002 | 1053 |
1054 int null_check_here = code_offset(); | |
0 | 1055 switch (type) { |
1056 case T_FLOAT: { | |
1057 if (src->is_single_xmm()) { | |
1058 __ movflt(as_Address(to_addr), src->as_xmm_float_reg()); | |
1059 } else { | |
1060 assert(src->is_single_fpu(), "must be"); | |
1061 assert(src->fpu_regnr() == 0, "argument must be on TOS"); | |
1062 if (pop_fpu_stack) __ fstp_s(as_Address(to_addr)); | |
1063 else __ fst_s (as_Address(to_addr)); | |
1064 } | |
1065 break; | |
1066 } | |
1067 | |
1068 case T_DOUBLE: { | |
1069 if (src->is_double_xmm()) { | |
1070 __ movdbl(as_Address(to_addr), src->as_xmm_double_reg()); | |
1071 } else { | |
1072 assert(src->is_double_fpu(), "must be"); | |
1073 assert(src->fpu_regnrLo() == 0, "argument must be on TOS"); | |
1074 if (pop_fpu_stack) __ fstp_d(as_Address(to_addr)); | |
1075 else __ fst_d (as_Address(to_addr)); | |
1076 } | |
1077 break; | |
1078 } | |
1079 | |
1080 case T_ARRAY: // fall through | |
1081 case T_OBJECT: // fall through | |
2002 | 1082 if (UseCompressedOops && !wide) { |
1083 __ movl(as_Address(to_addr), compressed_src); | |
1084 } else { | |
1085 __ movptr(as_Address(to_addr), src->as_register()); | |
1086 } | |
1087 break; | |
1088 case T_ADDRESS: | |
304 | 1089 __ movptr(as_Address(to_addr), src->as_register()); |
1090 break; | |
0 | 1091 case T_INT: |
1092 __ movl(as_Address(to_addr), src->as_register()); | |
1093 break; | |
1094 | |
1095 case T_LONG: { | |
1096 Register from_lo = src->as_register_lo(); | |
1097 Register from_hi = src->as_register_hi(); | |
304 | 1098 #ifdef _LP64 |
1099 __ movptr(as_Address_lo(to_addr), from_lo); | |
1100 #else | |
0 | 1101 Register base = to_addr->base()->as_register(); |
1102 Register index = noreg; | |
1103 if (to_addr->index()->is_register()) { | |
1104 index = to_addr->index()->as_register(); | |
1105 } | |
1106 if (base == from_lo || index == from_lo) { | |
1107 assert(base != from_hi, "can't be"); | |
1108 assert(index == noreg || (index != base && index != from_hi), "can't handle this"); | |
1109 __ movl(as_Address_hi(to_addr), from_hi); | |
1110 if (patch != NULL) { | |
1111 patching_epilog(patch, lir_patch_high, base, info); | |
1112 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
1113 patch_code = lir_patch_low; | |
1114 } | |
1115 __ movl(as_Address_lo(to_addr), from_lo); | |
1116 } else { | |
1117 assert(index == noreg || (index != base && index != from_lo), "can't handle this"); | |
1118 __ movl(as_Address_lo(to_addr), from_lo); | |
1119 if (patch != NULL) { | |
1120 patching_epilog(patch, lir_patch_low, base, info); | |
1121 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
1122 patch_code = lir_patch_high; | |
1123 } | |
1124 __ movl(as_Address_hi(to_addr), from_hi); | |
1125 } | |
304 | 1126 #endif // _LP64 |
0 | 1127 break; |
1128 } | |
1129 | |
1130 case T_BYTE: // fall through | |
1131 case T_BOOLEAN: { | |
1132 Register src_reg = src->as_register(); | |
1133 Address dst_addr = as_Address(to_addr); | |
1134 assert(VM_Version::is_P6() || src_reg->has_byte_register(), "must use byte registers if not P6"); | |
1135 __ movb(dst_addr, src_reg); | |
1136 break; | |
1137 } | |
1138 | |
1139 case T_CHAR: // fall through | |
1140 case T_SHORT: | |
1141 __ movw(as_Address(to_addr), src->as_register()); | |
1142 break; | |
1143 | |
1144 default: | |
1145 ShouldNotReachHere(); | |
1146 } | |
2002 | 1147 if (info != NULL) { |
1148 add_debug_info_for_null_check(null_check_here, info); | |
1149 } | |
0 | 1150 |
1151 if (patch_code != lir_patch_none) { | |
1152 patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); | |
1153 } | |
1154 } | |
1155 | |
1156 | |
1157 void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { | |
1158 assert(src->is_stack(), "should not call otherwise"); | |
1159 assert(dest->is_register(), "should not call otherwise"); | |
1160 | |
1161 if (dest->is_single_cpu()) { | |
1162 if (type == T_ARRAY || type == T_OBJECT) { | |
304 | 1163 __ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); |
0 | 1164 __ verify_oop(dest->as_register()); |
304 | 1165 } else { |
1166 __ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix())); | |
0 | 1167 } |
1168 | |
1169 } else if (dest->is_double_cpu()) { | |
1170 Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(), lo_word_offset_in_bytes); | |
1171 Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes); | |
304 | 1172 __ movptr(dest->as_register_lo(), src_addr_LO); |
1173 NOT_LP64(__ movptr(dest->as_register_hi(), src_addr_HI)); | |
0 | 1174 |
1175 } else if (dest->is_single_xmm()) { | |
1176 Address src_addr = frame_map()->address_for_slot(src->single_stack_ix()); | |
1177 __ movflt(dest->as_xmm_float_reg(), src_addr); | |
1178 | |
1179 } else if (dest->is_double_xmm()) { | |
1180 Address src_addr = frame_map()->address_for_slot(src->double_stack_ix()); | |
1181 __ movdbl(dest->as_xmm_double_reg(), src_addr); | |
1182 | |
1183 } else if (dest->is_single_fpu()) { | |
1184 assert(dest->fpu_regnr() == 0, "dest must be TOS"); | |
1185 Address src_addr = frame_map()->address_for_slot(src->single_stack_ix()); | |
1186 __ fld_s(src_addr); | |
1187 | |
1188 } else if (dest->is_double_fpu()) { | |
1189 assert(dest->fpu_regnrLo() == 0, "dest must be TOS"); | |
1190 Address src_addr = frame_map()->address_for_slot(src->double_stack_ix()); | |
1191 __ fld_d(src_addr); | |
1192 | |
1193 } else { | |
1194 ShouldNotReachHere(); | |
1195 } | |
1196 } | |
1197 | |
1198 | |
1199 void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { | |
1200 if (src->is_single_stack()) { | |
304 | 1201 if (type == T_OBJECT || type == T_ARRAY) { |
1202 __ pushptr(frame_map()->address_for_slot(src ->single_stack_ix())); | |
1203 __ popptr (frame_map()->address_for_slot(dest->single_stack_ix())); | |
1204 } else { | |
1060 | 1205 #ifndef _LP64 |
304 | 1206 __ pushl(frame_map()->address_for_slot(src ->single_stack_ix())); |
1207 __ popl (frame_map()->address_for_slot(dest->single_stack_ix())); | |
1060 | 1208 #else |
1209 //no pushl on 64bits | |
1210 __ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix())); | |
1211 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1); | |
1212 #endif | |
304 | 1213 } |
0 | 1214 |
1215 } else if (src->is_double_stack()) { | |
304 | 1216 #ifdef _LP64 |
1217 __ pushptr(frame_map()->address_for_slot(src ->double_stack_ix())); | |
1218 __ popptr (frame_map()->address_for_slot(dest->double_stack_ix())); | |
1219 #else | |
0 | 1220 __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0)); |
304 | 1221 // push and pop the part at src + wordSize, adding wordSize for the previous push |
321
6e7305abe64c
6746320: Hotspot regression test for 6512111 fails in -Xmixed mode
never
parents:
304
diff
changeset
|
1222 __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 2 * wordSize)); |
6e7305abe64c
6746320: Hotspot regression test for 6512111 fails in -Xmixed mode
never
parents:
304
diff
changeset
|
1223 __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 2 * wordSize)); |
0 | 1224 __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0)); |
304 | 1225 #endif // _LP64 |
0 | 1226 |
1227 } else { | |
1228 ShouldNotReachHere(); | |
1229 } | |
1230 } | |
1231 | |
1232 | |
2002 | 1233 void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) { |
0 | 1234 assert(src->is_address(), "should not call otherwise"); |
1235 assert(dest->is_register(), "should not call otherwise"); | |
1236 | |
1237 LIR_Address* addr = src->as_address_ptr(); | |
1238 Address from_addr = as_Address(addr); | |
1239 | |
1240 switch (type) { | |
1241 case T_BOOLEAN: // fall through | |
1242 case T_BYTE: // fall through | |
1243 case T_CHAR: // fall through | |
1244 case T_SHORT: | |
1245 if (!VM_Version::is_P6() && !from_addr.uses(dest->as_register())) { | |
1246 // on pre P6 processors we may get partial register stalls | |
1247 // so blow away the value of to_rinfo before loading a | |
1248 // partial word into it. Do it here so that it precedes | |
1249 // the potential patch point below. | |
304 | 1250 __ xorptr(dest->as_register(), dest->as_register()); |
0 | 1251 } |
1252 break; | |
1253 } | |
1254 | |
1255 PatchingStub* patch = NULL; | |
1256 if (patch_code != lir_patch_none) { | |
1257 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
304 | 1258 assert(from_addr.disp() != 0, "must have"); |
0 | 1259 } |
1260 if (info != NULL) { | |
1261 add_debug_info_for_null_check_here(info); | |
1262 } | |
1263 | |
1264 switch (type) { | |
1265 case T_FLOAT: { | |
1266 if (dest->is_single_xmm()) { | |
1267 __ movflt(dest->as_xmm_float_reg(), from_addr); | |
1268 } else { | |
1269 assert(dest->is_single_fpu(), "must be"); | |
1270 assert(dest->fpu_regnr() == 0, "dest must be TOS"); | |
1271 __ fld_s(from_addr); | |
1272 } | |
1273 break; | |
1274 } | |
1275 | |
1276 case T_DOUBLE: { | |
1277 if (dest->is_double_xmm()) { | |
1278 __ movdbl(dest->as_xmm_double_reg(), from_addr); | |
1279 } else { | |
1280 assert(dest->is_double_fpu(), "must be"); | |
1281 assert(dest->fpu_regnrLo() == 0, "dest must be TOS"); | |
1282 __ fld_d(from_addr); | |
1283 } | |
1284 break; | |
1285 } | |
1286 | |
1287 case T_OBJECT: // fall through | |
1288 case T_ARRAY: // fall through | |
2002 | 1289 if (UseCompressedOops && !wide) { |
1290 __ movl(dest->as_register(), from_addr); | |
1291 } else { | |
1292 __ movptr(dest->as_register(), from_addr); | |
1293 } | |
1294 break; | |
1295 | |
1296 case T_ADDRESS: | |
304 | 1297 __ movptr(dest->as_register(), from_addr); |
1298 break; | |
0 | 1299 case T_INT: |
1398
314e17ca2c23
6946892: c1 shouldn't sign-extend to upper 32bits on x64
iveresov
parents:
1378
diff
changeset
|
1300 __ movl(dest->as_register(), from_addr); |
0 | 1301 break; |
1302 | |
1303 case T_LONG: { | |
1304 Register to_lo = dest->as_register_lo(); | |
1305 Register to_hi = dest->as_register_hi(); | |
304 | 1306 #ifdef _LP64 |
1307 __ movptr(to_lo, as_Address_lo(addr)); | |
1308 #else | |
0 | 1309 Register base = addr->base()->as_register(); |
1310 Register index = noreg; | |
1311 if (addr->index()->is_register()) { | |
1312 index = addr->index()->as_register(); | |
1313 } | |
1314 if ((base == to_lo && index == to_hi) || | |
1315 (base == to_hi && index == to_lo)) { | |
1316 // addresses with 2 registers are only formed as a result of | |
1317 // array access so this code will never have to deal with | |
1318 // patches or null checks. | |
1319 assert(info == NULL && patch == NULL, "must be"); | |
304 | 1320 __ lea(to_hi, as_Address(addr)); |
0 | 1321 __ movl(to_lo, Address(to_hi, 0)); |
1322 __ movl(to_hi, Address(to_hi, BytesPerWord)); | |
1323 } else if (base == to_lo || index == to_lo) { | |
1324 assert(base != to_hi, "can't be"); | |
1325 assert(index == noreg || (index != base && index != to_hi), "can't handle this"); | |
1326 __ movl(to_hi, as_Address_hi(addr)); | |
1327 if (patch != NULL) { | |
1328 patching_epilog(patch, lir_patch_high, base, info); | |
1329 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
1330 patch_code = lir_patch_low; | |
1331 } | |
1332 __ movl(to_lo, as_Address_lo(addr)); | |
1333 } else { | |
1334 assert(index == noreg || (index != base && index != to_lo), "can't handle this"); | |
1335 __ movl(to_lo, as_Address_lo(addr)); | |
1336 if (patch != NULL) { | |
1337 patching_epilog(patch, lir_patch_low, base, info); | |
1338 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | |
1339 patch_code = lir_patch_high; | |
1340 } | |
1341 __ movl(to_hi, as_Address_hi(addr)); | |
1342 } | |
304 | 1343 #endif // _LP64 |
0 | 1344 break; |
1345 } | |
1346 | |
1347 case T_BOOLEAN: // fall through | |
1348 case T_BYTE: { | |
1349 Register dest_reg = dest->as_register(); | |
1350 assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6"); | |
1351 if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { | |
304 | 1352 __ movsbl(dest_reg, from_addr); |
0 | 1353 } else { |
1354 __ movb(dest_reg, from_addr); | |
1355 __ shll(dest_reg, 24); | |
1356 __ sarl(dest_reg, 24); | |
1357 } | |
1358 break; | |
1359 } | |
1360 | |
1361 case T_CHAR: { | |
1362 Register dest_reg = dest->as_register(); | |
1363 assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6"); | |
1364 if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { | |
304 | 1365 __ movzwl(dest_reg, from_addr); |
0 | 1366 } else { |
1367 __ movw(dest_reg, from_addr); | |
1368 } | |
1369 break; | |
1370 } | |
1371 | |
1372 case T_SHORT: { | |
1373 Register dest_reg = dest->as_register(); | |
1374 if (VM_Version::is_P6() || from_addr.uses(dest_reg)) { | |
304 | 1375 __ movswl(dest_reg, from_addr); |
0 | 1376 } else { |
1377 __ movw(dest_reg, from_addr); | |
1378 __ shll(dest_reg, 16); | |
1379 __ sarl(dest_reg, 16); | |
1380 } | |
1381 break; | |
1382 } | |
1383 | |
1384 default: | |
1385 ShouldNotReachHere(); | |
1386 } | |
1387 | |
1388 if (patch != NULL) { | |
1389 patching_epilog(patch, patch_code, addr->base()->as_register(), info); | |
1390 } | |
1391 | |
1392 if (type == T_ARRAY || type == T_OBJECT) { | |
2002 | 1393 #ifdef _LP64 |
1394 if (UseCompressedOops && !wide) { | |
1395 __ decode_heap_oop(dest->as_register()); | |
1396 } | |
1397 #endif | |
0 | 1398 __ verify_oop(dest->as_register()); |
1399 } | |
1400 } | |
1401 | |
1402 | |
1403 void LIR_Assembler::prefetchr(LIR_Opr src) { | |
1404 LIR_Address* addr = src->as_address_ptr(); | |
1405 Address from_addr = as_Address(addr); | |
1406 | |
1407 if (VM_Version::supports_sse()) { | |
1408 switch (ReadPrefetchInstr) { | |
1409 case 0: | |
1410 __ prefetchnta(from_addr); break; | |
1411 case 1: | |
1412 __ prefetcht0(from_addr); break; | |
1413 case 2: | |
1414 __ prefetcht2(from_addr); break; | |
1415 default: | |
1416 ShouldNotReachHere(); break; | |
1417 } | |
1418 } else if (VM_Version::supports_3dnow()) { | |
1419 __ prefetchr(from_addr); | |
1420 } | |
1421 } | |
1422 | |
1423 | |
1424 void LIR_Assembler::prefetchw(LIR_Opr src) { | |
1425 LIR_Address* addr = src->as_address_ptr(); | |
1426 Address from_addr = as_Address(addr); | |
1427 | |
1428 if (VM_Version::supports_sse()) { | |
1429 switch (AllocatePrefetchInstr) { | |
1430 case 0: | |
1431 __ prefetchnta(from_addr); break; | |
1432 case 1: | |
1433 __ prefetcht0(from_addr); break; | |
1434 case 2: | |
1435 __ prefetcht2(from_addr); break; | |
1436 case 3: | |
1437 __ prefetchw(from_addr); break; | |
1438 default: | |
1439 ShouldNotReachHere(); break; | |
1440 } | |
1441 } else if (VM_Version::supports_3dnow()) { | |
1442 __ prefetchw(from_addr); | |
1443 } | |
1444 } | |
1445 | |
1446 | |
1447 NEEDS_CLEANUP; // This could be static? | |
1448 Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const { | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
1449 int elem_size = type2aelembytes(type); |
0 | 1450 switch (elem_size) { |
1451 case 1: return Address::times_1; | |
1452 case 2: return Address::times_2; | |
1453 case 4: return Address::times_4; | |
1454 case 8: return Address::times_8; | |
1455 } | |
1456 ShouldNotReachHere(); | |
1457 return Address::no_scale; | |
1458 } | |
1459 | |
1460 | |
1461 void LIR_Assembler::emit_op3(LIR_Op3* op) { | |
1462 switch (op->code()) { | |
1463 case lir_idiv: | |
1464 case lir_irem: | |
1465 arithmetic_idiv(op->code(), | |
1466 op->in_opr1(), | |
1467 op->in_opr2(), | |
1468 op->in_opr3(), | |
1469 op->result_opr(), | |
1470 op->info()); | |
1471 break; | |
1472 default: ShouldNotReachHere(); break; | |
1473 } | |
1474 } | |
1475 | |
1476 void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) { | |
1477 #ifdef ASSERT | |
1478 assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label"); | |
1479 if (op->block() != NULL) _branch_target_blocks.append(op->block()); | |
1480 if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock()); | |
1481 #endif | |
1482 | |
1483 if (op->cond() == lir_cond_always) { | |
1484 if (op->info() != NULL) add_debug_info_for_branch(op->info()); | |
1485 __ jmp (*(op->label())); | |
1486 } else { | |
1487 Assembler::Condition acond = Assembler::zero; | |
1488 if (op->code() == lir_cond_float_branch) { | |
1489 assert(op->ublock() != NULL, "must have unordered successor"); | |
1490 __ jcc(Assembler::parity, *(op->ublock()->label())); | |
1491 switch(op->cond()) { | |
1492 case lir_cond_equal: acond = Assembler::equal; break; | |
1493 case lir_cond_notEqual: acond = Assembler::notEqual; break; | |
1494 case lir_cond_less: acond = Assembler::below; break; | |
1495 case lir_cond_lessEqual: acond = Assembler::belowEqual; break; | |
1496 case lir_cond_greaterEqual: acond = Assembler::aboveEqual; break; | |
1497 case lir_cond_greater: acond = Assembler::above; break; | |
1498 default: ShouldNotReachHere(); | |
1499 } | |
1500 } else { | |
1501 switch (op->cond()) { | |
1502 case lir_cond_equal: acond = Assembler::equal; break; | |
1503 case lir_cond_notEqual: acond = Assembler::notEqual; break; | |
1504 case lir_cond_less: acond = Assembler::less; break; | |
1505 case lir_cond_lessEqual: acond = Assembler::lessEqual; break; | |
1506 case lir_cond_greaterEqual: acond = Assembler::greaterEqual;break; | |
1507 case lir_cond_greater: acond = Assembler::greater; break; | |
1508 case lir_cond_belowEqual: acond = Assembler::belowEqual; break; | |
1509 case lir_cond_aboveEqual: acond = Assembler::aboveEqual; break; | |
1510 default: ShouldNotReachHere(); | |
1511 } | |
1512 } | |
1513 __ jcc(acond,*(op->label())); | |
1514 } | |
1515 } | |
1516 | |
1517 void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { | |
1518 LIR_Opr src = op->in_opr(); | |
1519 LIR_Opr dest = op->result_opr(); | |
1520 | |
1521 switch (op->bytecode()) { | |
1522 case Bytecodes::_i2l: | |
304 | 1523 #ifdef _LP64 |
1524 __ movl2ptr(dest->as_register_lo(), src->as_register()); | |
1525 #else | |
0 | 1526 move_regs(src->as_register(), dest->as_register_lo()); |
1527 move_regs(src->as_register(), dest->as_register_hi()); | |
1528 __ sarl(dest->as_register_hi(), 31); | |
304 | 1529 #endif // LP64 |
0 | 1530 break; |
1531 | |
1532 case Bytecodes::_l2i: | |
1533 move_regs(src->as_register_lo(), dest->as_register()); | |
1534 break; | |
1535 | |
1536 case Bytecodes::_i2b: | |
1537 move_regs(src->as_register(), dest->as_register()); | |
1538 __ sign_extend_byte(dest->as_register()); | |
1539 break; | |
1540 | |
1541 case Bytecodes::_i2c: | |
1542 move_regs(src->as_register(), dest->as_register()); | |
1543 __ andl(dest->as_register(), 0xFFFF); | |
1544 break; | |
1545 | |
1546 case Bytecodes::_i2s: | |
1547 move_regs(src->as_register(), dest->as_register()); | |
1548 __ sign_extend_short(dest->as_register()); | |
1549 break; | |
1550 | |
1551 | |
1552 case Bytecodes::_f2d: | |
1553 case Bytecodes::_d2f: | |
1554 if (dest->is_single_xmm()) { | |
1555 __ cvtsd2ss(dest->as_xmm_float_reg(), src->as_xmm_double_reg()); | |
1556 } else if (dest->is_double_xmm()) { | |
1557 __ cvtss2sd(dest->as_xmm_double_reg(), src->as_xmm_float_reg()); | |
1558 } else { | |
1559 assert(src->fpu() == dest->fpu(), "register must be equal"); | |
1560 // do nothing (float result is rounded later through spilling) | |
1561 } | |
1562 break; | |
1563 | |
1564 case Bytecodes::_i2f: | |
1565 case Bytecodes::_i2d: | |
1566 if (dest->is_single_xmm()) { | |
304 | 1567 __ cvtsi2ssl(dest->as_xmm_float_reg(), src->as_register()); |
0 | 1568 } else if (dest->is_double_xmm()) { |
304 | 1569 __ cvtsi2sdl(dest->as_xmm_double_reg(), src->as_register()); |
0 | 1570 } else { |
1571 assert(dest->fpu() == 0, "result must be on TOS"); | |
1572 __ movl(Address(rsp, 0), src->as_register()); | |
1573 __ fild_s(Address(rsp, 0)); | |
1574 } | |
1575 break; | |
1576 | |
1577 case Bytecodes::_f2i: | |
1578 case Bytecodes::_d2i: | |
1579 if (src->is_single_xmm()) { | |
304 | 1580 __ cvttss2sil(dest->as_register(), src->as_xmm_float_reg()); |
0 | 1581 } else if (src->is_double_xmm()) { |
304 | 1582 __ cvttsd2sil(dest->as_register(), src->as_xmm_double_reg()); |
0 | 1583 } else { |
1584 assert(src->fpu() == 0, "input must be on TOS"); | |
1585 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc())); | |
1586 __ fist_s(Address(rsp, 0)); | |
1587 __ movl(dest->as_register(), Address(rsp, 0)); | |
1588 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); | |
1589 } | |
1590 | |
1591 // IA32 conversion instructions do not match JLS for overflow, underflow and NaN -> fixup in stub | |
1592 assert(op->stub() != NULL, "stub required"); | |
1593 __ cmpl(dest->as_register(), 0x80000000); | |
1594 __ jcc(Assembler::equal, *op->stub()->entry()); | |
1595 __ bind(*op->stub()->continuation()); | |
1596 break; | |
1597 | |
1598 case Bytecodes::_l2f: | |
1599 case Bytecodes::_l2d: | |
1600 assert(!dest->is_xmm_register(), "result in xmm register not supported (no SSE instruction present)"); | |
1601 assert(dest->fpu() == 0, "result must be on TOS"); | |
1602 | |
304 | 1603 __ movptr(Address(rsp, 0), src->as_register_lo()); |
1604 NOT_LP64(__ movl(Address(rsp, BytesPerWord), src->as_register_hi())); | |
0 | 1605 __ fild_d(Address(rsp, 0)); |
1606 // float result is rounded later through spilling | |
1607 break; | |
1608 | |
1609 case Bytecodes::_f2l: | |
1610 case Bytecodes::_d2l: | |
1611 assert(!src->is_xmm_register(), "input in xmm register not supported (no SSE instruction present)"); | |
1612 assert(src->fpu() == 0, "input must be on TOS"); | |
304 | 1613 assert(dest == FrameMap::long0_opr, "runtime stub places result in these registers"); |
0 | 1614 |
1615 // instruction sequence too long to inline it here | |
1616 { | |
1617 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::fpu2long_stub_id))); | |
1618 } | |
1619 break; | |
1620 | |
1621 default: ShouldNotReachHere(); | |
1622 } | |
1623 } | |
1624 | |
1625 void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { | |
1626 if (op->init_check()) { | |
1627 __ cmpl(Address(op->klass()->as_register(), | |
1628 instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), | |
1629 instanceKlass::fully_initialized); | |
1630 add_debug_info_for_null_check_here(op->stub()->info()); | |
1631 __ jcc(Assembler::notEqual, *op->stub()->entry()); | |
1632 } | |
1633 __ allocate_object(op->obj()->as_register(), | |
1634 op->tmp1()->as_register(), | |
1635 op->tmp2()->as_register(), | |
1636 op->header_size(), | |
1637 op->object_size(), | |
1638 op->klass()->as_register(), | |
1639 *op->stub()->entry()); | |
1640 __ bind(*op->stub()->continuation()); | |
1641 } | |
1642 | |
1643 void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { | |
1644 if (UseSlowPath || | |
1645 (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) || | |
1646 (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) { | |
1647 __ jmp(*op->stub()->entry()); | |
1648 } else { | |
1649 Register len = op->len()->as_register(); | |
1650 Register tmp1 = op->tmp1()->as_register(); | |
1651 Register tmp2 = op->tmp2()->as_register(); | |
1652 Register tmp3 = op->tmp3()->as_register(); | |
1653 if (len == tmp1) { | |
1654 tmp1 = tmp3; | |
1655 } else if (len == tmp2) { | |
1656 tmp2 = tmp3; | |
1657 } else if (len == tmp3) { | |
1658 // everything is ok | |
1659 } else { | |
304 | 1660 __ mov(tmp3, len); |
0 | 1661 } |
1662 __ allocate_array(op->obj()->as_register(), | |
1663 len, | |
1664 tmp1, | |
1665 tmp2, | |
1666 arrayOopDesc::header_size(op->type()), | |
1667 array_element_size(op->type()), | |
1668 op->klass()->as_register(), | |
1669 *op->stub()->entry()); | |
1670 } | |
1671 __ bind(*op->stub()->continuation()); | |
1672 } | |
1673 | |
1783 | 1674 void LIR_Assembler::type_profile_helper(Register mdo, |
1675 ciMethodData *md, ciProfileData *data, | |
1676 Register recv, Label* update_done) { | |
1808
5511edd5d719
6988779: c1_LIRAssembler_x86.cpp crashes VS2010 compiler
iveresov
parents:
1791
diff
changeset
|
1677 for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { |
1783 | 1678 Label next_test; |
1679 // See if the receiver is receiver[n]. | |
1680 __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); | |
1681 __ jccb(Assembler::notEqual, next_test); | |
1682 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); | |
1683 __ addptr(data_addr, DataLayout::counter_increment); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1684 __ jmp(*update_done); |
1783 | 1685 __ bind(next_test); |
1686 } | |
1687 | |
1688 // Didn't find receiver; find next empty slot and fill it in | |
1808
5511edd5d719
6988779: c1_LIRAssembler_x86.cpp crashes VS2010 compiler
iveresov
parents:
1791
diff
changeset
|
1689 for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) { |
1783 | 1690 Label next_test; |
1691 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); | |
1692 __ cmpptr(recv_addr, (intptr_t)NULL_WORD); | |
1693 __ jccb(Assembler::notEqual, next_test); | |
1694 __ movptr(recv_addr, recv); | |
1695 __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1696 __ jmp(*update_done); |
1783 | 1697 __ bind(next_test); |
1698 } | |
1699 } | |
1700 | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1701 void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) { |
1783 | 1702 // we always need a stub for the failure case. |
1703 CodeStub* stub = op->stub(); | |
1704 Register obj = op->object()->as_register(); | |
1705 Register k_RInfo = op->tmp1()->as_register(); | |
1706 Register klass_RInfo = op->tmp2()->as_register(); | |
1707 Register dst = op->result_opr()->as_register(); | |
1708 ciKlass* k = op->klass(); | |
1709 Register Rtmp1 = noreg; | |
1710 | |
1711 // check if it needs to be profiled | |
1712 ciMethodData* md; | |
1713 ciProfileData* data; | |
1714 | |
1715 if (op->should_profile()) { | |
1716 ciMethod* method = op->profiled_method(); | |
1717 assert(method != NULL, "Should have method"); | |
1718 int bci = op->profiled_bci(); | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
1719 md = method->method_data_or_null(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
1720 assert(md != NULL, "Sanity"); |
1783 | 1721 data = md->bci_to_data(bci); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1722 assert(data != NULL, "need data for type check"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1723 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); |
1783 | 1724 } |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1725 Label profile_cast_success, profile_cast_failure; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1726 Label *success_target = op->should_profile() ? &profile_cast_success : success; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1727 Label *failure_target = op->should_profile() ? &profile_cast_failure : failure; |
1783 | 1728 |
1729 if (obj == k_RInfo) { | |
1730 k_RInfo = dst; | |
1731 } else if (obj == klass_RInfo) { | |
1732 klass_RInfo = dst; | |
1733 } | |
2002 | 1734 if (k->is_loaded() && !UseCompressedOops) { |
1783 | 1735 select_different_registers(obj, dst, k_RInfo, klass_RInfo); |
1736 } else { | |
1737 Rtmp1 = op->tmp3()->as_register(); | |
1738 select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); | |
1739 } | |
1740 | |
1741 assert_different_registers(obj, k_RInfo, klass_RInfo); | |
1742 if (!k->is_loaded()) { | |
1743 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); | |
1744 } else { | |
1745 #ifdef _LP64 | |
1746 __ movoop(k_RInfo, k->constant_encoding()); | |
1747 #endif // _LP64 | |
1748 } | |
1749 assert(obj != k_RInfo, "must be different"); | |
1750 | |
1751 __ cmpptr(obj, (int32_t)NULL_WORD); | |
1752 if (op->should_profile()) { | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1753 Label not_null; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1754 __ jccb(Assembler::notEqual, not_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1755 // Object is null; update MDO and exit |
1783 | 1756 Register mdo = klass_RInfo; |
1757 __ movoop(mdo, md->constant_encoding()); | |
1758 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); | |
1759 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); | |
1760 __ orl(data_addr, header_bits); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1761 __ jmp(*obj_is_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1762 __ bind(not_null); |
1783 | 1763 } else { |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1764 __ jcc(Assembler::equal, *obj_is_null); |
1783 | 1765 } |
1766 __ verify_oop(obj); | |
1767 | |
1768 if (op->fast_check()) { | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1769 // get object class |
1783 | 1770 // not a safepoint as obj null check happens earlier |
1771 #ifdef _LP64 | |
2002 | 1772 if (UseCompressedOops) { |
1773 __ load_klass(Rtmp1, obj); | |
1774 __ cmpptr(k_RInfo, Rtmp1); | |
1783 | 1775 } else { |
1776 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1777 } | |
2002 | 1778 #else |
1779 if (k->is_loaded()) { | |
1780 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); | |
1781 } else { | |
1782 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1783 } | |
1784 #endif | |
1783 | 1785 __ jcc(Assembler::notEqual, *failure_target); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1786 // successful cast, fall through to profile or jump |
1783 | 1787 } else { |
1788 // get object class | |
1789 // not a safepoint as obj null check happens earlier | |
2002 | 1790 __ load_klass(klass_RInfo, obj); |
1783 | 1791 if (k->is_loaded()) { |
1792 // See if we get an immediate positive hit | |
1793 #ifdef _LP64 | |
1794 __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); | |
1795 #else | |
1796 __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); | |
1797 #endif // _LP64 | |
1798 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { | |
1799 __ jcc(Assembler::notEqual, *failure_target); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1800 // successful cast, fall through to profile or jump |
1783 | 1801 } else { |
1802 // See if we get an immediate positive hit | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1803 __ jcc(Assembler::equal, *success_target); |
1783 | 1804 // check for self |
1805 #ifdef _LP64 | |
1806 __ cmpptr(klass_RInfo, k_RInfo); | |
1807 #else | |
1808 __ cmpoop(klass_RInfo, k->constant_encoding()); | |
1809 #endif // _LP64 | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1810 __ jcc(Assembler::equal, *success_target); |
1783 | 1811 |
1812 __ push(klass_RInfo); | |
1813 #ifdef _LP64 | |
1814 __ push(k_RInfo); | |
1815 #else | |
1816 __ pushoop(k->constant_encoding()); | |
1817 #endif // _LP64 | |
1818 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1819 __ pop(klass_RInfo); | |
1820 __ pop(klass_RInfo); | |
1821 // result is a boolean | |
1822 __ cmpl(klass_RInfo, 0); | |
1823 __ jcc(Assembler::equal, *failure_target); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1824 // successful cast, fall through to profile or jump |
1783 | 1825 } |
1826 } else { | |
1827 // perform the fast part of the checking logic | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1828 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); |
1783 | 1829 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
1830 __ push(klass_RInfo); | |
1831 __ push(k_RInfo); | |
1832 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); | |
1833 __ pop(klass_RInfo); | |
1834 __ pop(k_RInfo); | |
1835 // result is a boolean | |
1836 __ cmpl(k_RInfo, 0); | |
1837 __ jcc(Assembler::equal, *failure_target); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1838 // successful cast, fall through to profile or jump |
1783 | 1839 } |
1840 } | |
1841 if (op->should_profile()) { | |
1842 Register mdo = klass_RInfo, recv = k_RInfo; | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1843 __ bind(profile_cast_success); |
1783 | 1844 __ movoop(mdo, md->constant_encoding()); |
2002 | 1845 __ load_klass(recv, obj); |
1783 | 1846 Label update_done; |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1847 type_profile_helper(mdo, md, data, recv, success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1848 __ jmp(*success); |
1783 | 1849 |
1850 __ bind(profile_cast_failure); | |
1851 __ movoop(mdo, md->constant_encoding()); | |
1852 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); | |
1853 __ subptr(counter_addr, DataLayout::counter_increment); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1854 __ jmp(*failure); |
1783 | 1855 } |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1856 __ jmp(*success); |
1783 | 1857 } |
0 | 1858 |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1859 |
0 | 1860 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { |
1861 LIR_Code code = op->code(); | |
1862 if (code == lir_store_check) { | |
1863 Register value = op->object()->as_register(); | |
1864 Register array = op->array()->as_register(); | |
1865 Register k_RInfo = op->tmp1()->as_register(); | |
1866 Register klass_RInfo = op->tmp2()->as_register(); | |
1867 Register Rtmp1 = op->tmp3()->as_register(); | |
1868 | |
1869 CodeStub* stub = op->stub(); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1870 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1871 // check if it needs to be profiled |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1872 ciMethodData* md; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1873 ciProfileData* data; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1874 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1875 if (op->should_profile()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1876 ciMethod* method = op->profiled_method(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1877 assert(method != NULL, "Should have method"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1878 int bci = op->profiled_bci(); |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
1879 md = method->method_data_or_null(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
1880 assert(md != NULL, "Sanity"); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1881 data = md->bci_to_data(bci); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1882 assert(data != NULL, "need data for type check"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1883 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check"); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1884 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1885 Label profile_cast_success, profile_cast_failure, done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1886 Label *success_target = op->should_profile() ? &profile_cast_success : &done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1887 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1888 |
304 | 1889 __ cmpptr(value, (int32_t)NULL_WORD); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1890 if (op->should_profile()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1891 Label not_null; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1892 __ jccb(Assembler::notEqual, not_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1893 // Object is null; update MDO and exit |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1894 Register mdo = klass_RInfo; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1895 __ movoop(mdo, md->constant_encoding()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1896 Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1897 int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1898 __ orl(data_addr, header_bits); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1899 __ jmp(done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1900 __ bind(not_null); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1901 } else { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1902 __ jcc(Assembler::equal, done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1903 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1904 |
0 | 1905 add_debug_info_for_null_check_here(op->info_for_exception()); |
2002 | 1906 __ load_klass(k_RInfo, array); |
1907 __ load_klass(klass_RInfo, value); | |
1908 | |
1909 // get instance klass (it's already uncompressed) | |
304 | 1910 __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
622
diff
changeset
|
1911 // perform the fast part of the checking logic |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1912 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
622
diff
changeset
|
1913 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
304 | 1914 __ push(klass_RInfo); |
1915 __ push(k_RInfo); | |
0 | 1916 __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); |
304 | 1917 __ pop(klass_RInfo); |
1918 __ pop(k_RInfo); | |
1919 // result is a boolean | |
0 | 1920 __ cmpl(k_RInfo, 0); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1921 __ jcc(Assembler::equal, *failure_target); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1922 // fall through to the success case |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1923 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1924 if (op->should_profile()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1925 Register mdo = klass_RInfo, recv = k_RInfo; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1926 __ bind(profile_cast_success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1927 __ movoop(mdo, md->constant_encoding()); |
2002 | 1928 __ load_klass(recv, value); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1929 Label update_done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1930 type_profile_helper(mdo, md, data, recv, &done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1931 __ jmpb(done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1932 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1933 __ bind(profile_cast_failure); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1934 __ movoop(mdo, md->constant_encoding()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1935 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1936 __ subptr(counter_addr, DataLayout::counter_increment); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1937 __ jmp(*stub->entry()); |
0 | 1938 } |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1939 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1940 __ bind(done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1941 } else |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1942 if (code == lir_checkcast) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1943 Register obj = op->object()->as_register(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1944 Register dst = op->result_opr()->as_register(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1945 Label success; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1946 emit_typecheck_helper(op, &success, op->stub()->entry(), &success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1947 __ bind(success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1948 if (dst != obj) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1949 __ mov(dst, obj); |
0 | 1950 } |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1951 } else |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1952 if (code == lir_instanceof) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1953 Register obj = op->object()->as_register(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1954 Register dst = op->result_opr()->as_register(); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1955 Label success, failure, done; |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1956 emit_typecheck_helper(op, &success, &failure, &failure); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1957 __ bind(failure); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1958 __ xorptr(dst, dst); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1959 __ jmpb(done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1960 __ bind(success); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1961 __ movptr(dst, 1); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1962 __ bind(done); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1963 } else { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1790
diff
changeset
|
1964 ShouldNotReachHere(); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
622
diff
changeset
|
1965 } |
0 | 1966 |
1967 } | |
1968 | |
1969 | |
1970 void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { | |
304 | 1971 if (LP64_ONLY(false &&) op->code() == lir_cas_long && VM_Version::supports_cx8()) { |
0 | 1972 assert(op->cmp_value()->as_register_lo() == rax, "wrong register"); |
1973 assert(op->cmp_value()->as_register_hi() == rdx, "wrong register"); | |
1974 assert(op->new_value()->as_register_lo() == rbx, "wrong register"); | |
1975 assert(op->new_value()->as_register_hi() == rcx, "wrong register"); | |
1976 Register addr = op->addr()->as_register(); | |
1977 if (os::is_MP()) { | |
1978 __ lock(); | |
1979 } | |
304 | 1980 NOT_LP64(__ cmpxchg8(Address(addr, 0))); |
1981 | |
1982 } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj ) { | |
1983 NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");) | |
1984 Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); | |
0 | 1985 Register newval = op->new_value()->as_register(); |
1986 Register cmpval = op->cmp_value()->as_register(); | |
1987 assert(cmpval == rax, "wrong register"); | |
1988 assert(newval != NULL, "new val must be register"); | |
1989 assert(cmpval != newval, "cmp and new values must be in different registers"); | |
1990 assert(cmpval != addr, "cmp and addr must be in different registers"); | |
1991 assert(newval != addr, "new value and addr must be in different registers"); | |
2002 | 1992 |
304 | 1993 if ( op->code() == lir_cas_obj) { |
2002 | 1994 #ifdef _LP64 |
1995 if (UseCompressedOops) { | |
1996 __ encode_heap_oop(cmpval); | |
2013
ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
iveresov
parents:
2007
diff
changeset
|
1997 __ mov(rscratch1, newval); |
ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
iveresov
parents:
2007
diff
changeset
|
1998 __ encode_heap_oop(rscratch1); |
2002 | 1999 if (os::is_MP()) { |
2000 __ lock(); | |
2001 } | |
2013
ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
iveresov
parents:
2007
diff
changeset
|
2002 // cmpval (rax) is implicitly used by this instruction |
ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
iveresov
parents:
2007
diff
changeset
|
2003 __ cmpxchgl(rscratch1, Address(addr, 0)); |
2002 | 2004 } else |
2005 #endif | |
2006 { | |
2007 if (os::is_MP()) { | |
2008 __ lock(); | |
2009 } | |
2010 __ cmpxchgptr(newval, Address(addr, 0)); | |
2011 } | |
2012 } else { | |
2013 assert(op->code() == lir_cas_int, "lir_cas_int expected"); | |
2014 if (os::is_MP()) { | |
2015 __ lock(); | |
2016 } | |
304 | 2017 __ cmpxchgl(newval, Address(addr, 0)); |
2018 } | |
2019 #ifdef _LP64 | |
2020 } else if (op->code() == lir_cas_long) { | |
2021 Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); | |
2022 Register newval = op->new_value()->as_register_lo(); | |
2023 Register cmpval = op->cmp_value()->as_register_lo(); | |
2024 assert(cmpval == rax, "wrong register"); | |
2025 assert(newval != NULL, "new val must be register"); | |
2026 assert(cmpval != newval, "cmp and new values must be in different registers"); | |
2027 assert(cmpval != addr, "cmp and addr must be in different registers"); | |
2028 assert(newval != addr, "new value and addr must be in different registers"); | |
2029 if (os::is_MP()) { | |
2030 __ lock(); | |
2031 } | |
2032 __ cmpxchgq(newval, Address(addr, 0)); | |
2033 #endif // _LP64 | |
0 | 2034 } else { |
2035 Unimplemented(); | |
2036 } | |
2037 } | |
2038 | |
2039 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { | |
2040 Assembler::Condition acond, ncond; | |
2041 switch (condition) { | |
2042 case lir_cond_equal: acond = Assembler::equal; ncond = Assembler::notEqual; break; | |
2043 case lir_cond_notEqual: acond = Assembler::notEqual; ncond = Assembler::equal; break; | |
2044 case lir_cond_less: acond = Assembler::less; ncond = Assembler::greaterEqual; break; | |
2045 case lir_cond_lessEqual: acond = Assembler::lessEqual; ncond = Assembler::greater; break; | |
2046 case lir_cond_greaterEqual: acond = Assembler::greaterEqual; ncond = Assembler::less; break; | |
2047 case lir_cond_greater: acond = Assembler::greater; ncond = Assembler::lessEqual; break; | |
2048 case lir_cond_belowEqual: acond = Assembler::belowEqual; ncond = Assembler::above; break; | |
2049 case lir_cond_aboveEqual: acond = Assembler::aboveEqual; ncond = Assembler::below; break; | |
2050 default: ShouldNotReachHere(); | |
2051 } | |
2052 | |
2053 if (opr1->is_cpu_register()) { | |
2054 reg2reg(opr1, result); | |
2055 } else if (opr1->is_stack()) { | |
2056 stack2reg(opr1, result, result->type()); | |
2057 } else if (opr1->is_constant()) { | |
2058 const2reg(opr1, result, lir_patch_none, NULL); | |
2059 } else { | |
2060 ShouldNotReachHere(); | |
2061 } | |
2062 | |
2063 if (VM_Version::supports_cmov() && !opr2->is_constant()) { | |
2064 // optimized version that does not require a branch | |
2065 if (opr2->is_single_cpu()) { | |
2066 assert(opr2->cpu_regnr() != result->cpu_regnr(), "opr2 already overwritten by previous move"); | |
304 | 2067 __ cmov(ncond, result->as_register(), opr2->as_register()); |
0 | 2068 } else if (opr2->is_double_cpu()) { |
2069 assert(opr2->cpu_regnrLo() != result->cpu_regnrLo() && opr2->cpu_regnrLo() != result->cpu_regnrHi(), "opr2 already overwritten by previous move"); | |
2070 assert(opr2->cpu_regnrHi() != result->cpu_regnrLo() && opr2->cpu_regnrHi() != result->cpu_regnrHi(), "opr2 already overwritten by previous move"); | |
304 | 2071 __ cmovptr(ncond, result->as_register_lo(), opr2->as_register_lo()); |
2072 NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), opr2->as_register_hi());) | |
0 | 2073 } else if (opr2->is_single_stack()) { |
2074 __ cmovl(ncond, result->as_register(), frame_map()->address_for_slot(opr2->single_stack_ix())); | |
2075 } else if (opr2->is_double_stack()) { | |
304 | 2076 __ cmovptr(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes)); |
2077 NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes));) | |
0 | 2078 } else { |
2079 ShouldNotReachHere(); | |
2080 } | |
2081 | |
2082 } else { | |
2083 Label skip; | |
2084 __ jcc (acond, skip); | |
2085 if (opr2->is_cpu_register()) { | |
2086 reg2reg(opr2, result); | |
2087 } else if (opr2->is_stack()) { | |
2088 stack2reg(opr2, result, result->type()); | |
2089 } else if (opr2->is_constant()) { | |
2090 const2reg(opr2, result, lir_patch_none, NULL); | |
2091 } else { | |
2092 ShouldNotReachHere(); | |
2093 } | |
2094 __ bind(skip); | |
2095 } | |
2096 } | |
2097 | |
2098 | |
2099 void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) { | |
2100 assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method"); | |
2101 | |
2102 if (left->is_single_cpu()) { | |
2103 assert(left == dest, "left and dest must be equal"); | |
2104 Register lreg = left->as_register(); | |
2105 | |
2106 if (right->is_single_cpu()) { | |
2107 // cpu register - cpu register | |
2108 Register rreg = right->as_register(); | |
2109 switch (code) { | |
2110 case lir_add: __ addl (lreg, rreg); break; | |
2111 case lir_sub: __ subl (lreg, rreg); break; | |
2112 case lir_mul: __ imull(lreg, rreg); break; | |
2113 default: ShouldNotReachHere(); | |
2114 } | |
2115 | |
2116 } else if (right->is_stack()) { | |
2117 // cpu register - stack | |
2118 Address raddr = frame_map()->address_for_slot(right->single_stack_ix()); | |
2119 switch (code) { | |
2120 case lir_add: __ addl(lreg, raddr); break; | |
2121 case lir_sub: __ subl(lreg, raddr); break; | |
2122 default: ShouldNotReachHere(); | |
2123 } | |
2124 | |
2125 } else if (right->is_constant()) { | |
2126 // cpu register - constant | |
2127 jint c = right->as_constant_ptr()->as_jint(); | |
2128 switch (code) { | |
2129 case lir_add: { | |
1790
7f9553bedfd5
6984056: C1: incorrect code for integer constant addition on x64
iveresov
parents:
1783
diff
changeset
|
2130 __ incrementl(lreg, c); |
0 | 2131 break; |
2132 } | |
2133 case lir_sub: { | |
1790
7f9553bedfd5
6984056: C1: incorrect code for integer constant addition on x64
iveresov
parents:
1783
diff
changeset
|
2134 __ decrementl(lreg, c); |
0 | 2135 break; |
2136 } | |
2137 default: ShouldNotReachHere(); | |
2138 } | |
2139 | |
2140 } else { | |
2141 ShouldNotReachHere(); | |
2142 } | |
2143 | |
2144 } else if (left->is_double_cpu()) { | |
2145 assert(left == dest, "left and dest must be equal"); | |
2146 Register lreg_lo = left->as_register_lo(); | |
2147 Register lreg_hi = left->as_register_hi(); | |
2148 | |
2149 if (right->is_double_cpu()) { | |
2150 // cpu register - cpu register | |
2151 Register rreg_lo = right->as_register_lo(); | |
2152 Register rreg_hi = right->as_register_hi(); | |
304 | 2153 NOT_LP64(assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi)); |
2154 LP64_ONLY(assert_different_registers(lreg_lo, rreg_lo)); | |
0 | 2155 switch (code) { |
2156 case lir_add: | |
304 | 2157 __ addptr(lreg_lo, rreg_lo); |
2158 NOT_LP64(__ adcl(lreg_hi, rreg_hi)); | |
0 | 2159 break; |
2160 case lir_sub: | |
304 | 2161 __ subptr(lreg_lo, rreg_lo); |
2162 NOT_LP64(__ sbbl(lreg_hi, rreg_hi)); | |
0 | 2163 break; |
2164 case lir_mul: | |
304 | 2165 #ifdef _LP64 |
2166 __ imulq(lreg_lo, rreg_lo); | |
2167 #else | |
0 | 2168 assert(lreg_lo == rax && lreg_hi == rdx, "must be"); |
2169 __ imull(lreg_hi, rreg_lo); | |
2170 __ imull(rreg_hi, lreg_lo); | |
2171 __ addl (rreg_hi, lreg_hi); | |
2172 __ mull (rreg_lo); | |
2173 __ addl (lreg_hi, rreg_hi); | |
304 | 2174 #endif // _LP64 |
0 | 2175 break; |
2176 default: | |
2177 ShouldNotReachHere(); | |
2178 } | |
2179 | |
2180 } else if (right->is_constant()) { | |
2181 // cpu register - constant | |
304 | 2182 #ifdef _LP64 |
2183 jlong c = right->as_constant_ptr()->as_jlong_bits(); | |
2184 __ movptr(r10, (intptr_t) c); | |
2185 switch (code) { | |
2186 case lir_add: | |
2187 __ addptr(lreg_lo, r10); | |
2188 break; | |
2189 case lir_sub: | |
2190 __ subptr(lreg_lo, r10); | |
2191 break; | |
2192 default: | |
2193 ShouldNotReachHere(); | |
2194 } | |
2195 #else | |
0 | 2196 jint c_lo = right->as_constant_ptr()->as_jint_lo(); |
2197 jint c_hi = right->as_constant_ptr()->as_jint_hi(); | |
2198 switch (code) { | |
2199 case lir_add: | |
304 | 2200 __ addptr(lreg_lo, c_lo); |
0 | 2201 __ adcl(lreg_hi, c_hi); |
2202 break; | |
2203 case lir_sub: | |
304 | 2204 __ subptr(lreg_lo, c_lo); |
0 | 2205 __ sbbl(lreg_hi, c_hi); |
2206 break; | |
2207 default: | |
2208 ShouldNotReachHere(); | |
2209 } | |
304 | 2210 #endif // _LP64 |
0 | 2211 |
2212 } else { | |
2213 ShouldNotReachHere(); | |
2214 } | |
2215 | |
2216 } else if (left->is_single_xmm()) { | |
2217 assert(left == dest, "left and dest must be equal"); | |
2218 XMMRegister lreg = left->as_xmm_float_reg(); | |
2219 | |
2220 if (right->is_single_xmm()) { | |
2221 XMMRegister rreg = right->as_xmm_float_reg(); | |
2222 switch (code) { | |
2223 case lir_add: __ addss(lreg, rreg); break; | |
2224 case lir_sub: __ subss(lreg, rreg); break; | |
2225 case lir_mul_strictfp: // fall through | |
2226 case lir_mul: __ mulss(lreg, rreg); break; | |
2227 case lir_div_strictfp: // fall through | |
2228 case lir_div: __ divss(lreg, rreg); break; | |
2229 default: ShouldNotReachHere(); | |
2230 } | |
2231 } else { | |
2232 Address raddr; | |
2233 if (right->is_single_stack()) { | |
2234 raddr = frame_map()->address_for_slot(right->single_stack_ix()); | |
2235 } else if (right->is_constant()) { | |
2236 // hack for now | |
2237 raddr = __ as_Address(InternalAddress(float_constant(right->as_jfloat()))); | |
2238 } else { | |
2239 ShouldNotReachHere(); | |
2240 } | |
2241 switch (code) { | |
2242 case lir_add: __ addss(lreg, raddr); break; | |
2243 case lir_sub: __ subss(lreg, raddr); break; | |
2244 case lir_mul_strictfp: // fall through | |
2245 case lir_mul: __ mulss(lreg, raddr); break; | |
2246 case lir_div_strictfp: // fall through | |
2247 case lir_div: __ divss(lreg, raddr); break; | |
2248 default: ShouldNotReachHere(); | |
2249 } | |
2250 } | |
2251 | |
2252 } else if (left->is_double_xmm()) { | |
2253 assert(left == dest, "left and dest must be equal"); | |
2254 | |
2255 XMMRegister lreg = left->as_xmm_double_reg(); | |
2256 if (right->is_double_xmm()) { | |
2257 XMMRegister rreg = right->as_xmm_double_reg(); | |
2258 switch (code) { | |
2259 case lir_add: __ addsd(lreg, rreg); break; | |
2260 case lir_sub: __ subsd(lreg, rreg); break; | |
2261 case lir_mul_strictfp: // fall through | |
2262 case lir_mul: __ mulsd(lreg, rreg); break; | |
2263 case lir_div_strictfp: // fall through | |
2264 case lir_div: __ divsd(lreg, rreg); break; | |
2265 default: ShouldNotReachHere(); | |
2266 } | |
2267 } else { | |
2268 Address raddr; | |
2269 if (right->is_double_stack()) { | |
2270 raddr = frame_map()->address_for_slot(right->double_stack_ix()); | |
2271 } else if (right->is_constant()) { | |
2272 // hack for now | |
2273 raddr = __ as_Address(InternalAddress(double_constant(right->as_jdouble()))); | |
2274 } else { | |
2275 ShouldNotReachHere(); | |
2276 } | |
2277 switch (code) { | |
2278 case lir_add: __ addsd(lreg, raddr); break; | |
2279 case lir_sub: __ subsd(lreg, raddr); break; | |
2280 case lir_mul_strictfp: // fall through | |
2281 case lir_mul: __ mulsd(lreg, raddr); break; | |
2282 case lir_div_strictfp: // fall through | |
2283 case lir_div: __ divsd(lreg, raddr); break; | |
2284 default: ShouldNotReachHere(); | |
2285 } | |
2286 } | |
2287 | |
2288 } else if (left->is_single_fpu()) { | |
2289 assert(dest->is_single_fpu(), "fpu stack allocation required"); | |
2290 | |
2291 if (right->is_single_fpu()) { | |
2292 arith_fpu_implementation(code, left->fpu_regnr(), right->fpu_regnr(), dest->fpu_regnr(), pop_fpu_stack); | |
2293 | |
2294 } else { | |
2295 assert(left->fpu_regnr() == 0, "left must be on TOS"); | |
2296 assert(dest->fpu_regnr() == 0, "dest must be on TOS"); | |
2297 | |
2298 Address raddr; | |
2299 if (right->is_single_stack()) { | |
2300 raddr = frame_map()->address_for_slot(right->single_stack_ix()); | |
2301 } else if (right->is_constant()) { | |
2302 address const_addr = float_constant(right->as_jfloat()); | |
2303 assert(const_addr != NULL, "incorrect float/double constant maintainance"); | |
2304 // hack for now | |
2305 raddr = __ as_Address(InternalAddress(const_addr)); | |
2306 } else { | |
2307 ShouldNotReachHere(); | |
2308 } | |
2309 | |
2310 switch (code) { | |
2311 case lir_add: __ fadd_s(raddr); break; | |
2312 case lir_sub: __ fsub_s(raddr); break; | |
2313 case lir_mul_strictfp: // fall through | |
2314 case lir_mul: __ fmul_s(raddr); break; | |
2315 case lir_div_strictfp: // fall through | |
2316 case lir_div: __ fdiv_s(raddr); break; | |
2317 default: ShouldNotReachHere(); | |
2318 } | |
2319 } | |
2320 | |
2321 } else if (left->is_double_fpu()) { | |
2322 assert(dest->is_double_fpu(), "fpu stack allocation required"); | |
2323 | |
2324 if (code == lir_mul_strictfp || code == lir_div_strictfp) { | |
2325 // Double values require special handling for strictfp mul/div on x86 | |
2326 __ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias1())); | |
2327 __ fmulp(left->fpu_regnrLo() + 1); | |
2328 } | |
2329 | |
2330 if (right->is_double_fpu()) { | |
2331 arith_fpu_implementation(code, left->fpu_regnrLo(), right->fpu_regnrLo(), dest->fpu_regnrLo(), pop_fpu_stack); | |
2332 | |
2333 } else { | |
2334 assert(left->fpu_regnrLo() == 0, "left must be on TOS"); | |
2335 assert(dest->fpu_regnrLo() == 0, "dest must be on TOS"); | |
2336 | |
2337 Address raddr; | |
2338 if (right->is_double_stack()) { | |
2339 raddr = frame_map()->address_for_slot(right->double_stack_ix()); | |
2340 } else if (right->is_constant()) { | |
2341 // hack for now | |
2342 raddr = __ as_Address(InternalAddress(double_constant(right->as_jdouble()))); | |
2343 } else { | |
2344 ShouldNotReachHere(); | |
2345 } | |
2346 | |
2347 switch (code) { | |
2348 case lir_add: __ fadd_d(raddr); break; | |
2349 case lir_sub: __ fsub_d(raddr); break; | |
2350 case lir_mul_strictfp: // fall through | |
2351 case lir_mul: __ fmul_d(raddr); break; | |
2352 case lir_div_strictfp: // fall through | |
2353 case lir_div: __ fdiv_d(raddr); break; | |
2354 default: ShouldNotReachHere(); | |
2355 } | |
2356 } | |
2357 | |
2358 if (code == lir_mul_strictfp || code == lir_div_strictfp) { | |
2359 // Double values require special handling for strictfp mul/div on x86 | |
2360 __ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias2())); | |
2361 __ fmulp(dest->fpu_regnrLo() + 1); | |
2362 } | |
2363 | |
2364 } else if (left->is_single_stack() || left->is_address()) { | |
2365 assert(left == dest, "left and dest must be equal"); | |
2366 | |
2367 Address laddr; | |
2368 if (left->is_single_stack()) { | |
2369 laddr = frame_map()->address_for_slot(left->single_stack_ix()); | |
2370 } else if (left->is_address()) { | |
2371 laddr = as_Address(left->as_address_ptr()); | |
2372 } else { | |
2373 ShouldNotReachHere(); | |
2374 } | |
2375 | |
2376 if (right->is_single_cpu()) { | |
2377 Register rreg = right->as_register(); | |
2378 switch (code) { | |
2379 case lir_add: __ addl(laddr, rreg); break; | |
2380 case lir_sub: __ subl(laddr, rreg); break; | |
2381 default: ShouldNotReachHere(); | |
2382 } | |
2383 } else if (right->is_constant()) { | |
2384 jint c = right->as_constant_ptr()->as_jint(); | |
2385 switch (code) { | |
2386 case lir_add: { | |
304 | 2387 __ incrementl(laddr, c); |
0 | 2388 break; |
2389 } | |
2390 case lir_sub: { | |
304 | 2391 __ decrementl(laddr, c); |
0 | 2392 break; |
2393 } | |
2394 default: ShouldNotReachHere(); | |
2395 } | |
2396 } else { | |
2397 ShouldNotReachHere(); | |
2398 } | |
2399 | |
2400 } else { | |
2401 ShouldNotReachHere(); | |
2402 } | |
2403 } | |
2404 | |
2405 void LIR_Assembler::arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack) { | |
2406 assert(pop_fpu_stack || (left_index == dest_index || right_index == dest_index), "invalid LIR"); | |
2407 assert(!pop_fpu_stack || (left_index - 1 == dest_index || right_index - 1 == dest_index), "invalid LIR"); | |
2408 assert(left_index == 0 || right_index == 0, "either must be on top of stack"); | |
2409 | |
2410 bool left_is_tos = (left_index == 0); | |
2411 bool dest_is_tos = (dest_index == 0); | |
2412 int non_tos_index = (left_is_tos ? right_index : left_index); | |
2413 | |
2414 switch (code) { | |
2415 case lir_add: | |
2416 if (pop_fpu_stack) __ faddp(non_tos_index); | |
2417 else if (dest_is_tos) __ fadd (non_tos_index); | |
2418 else __ fadda(non_tos_index); | |
2419 break; | |
2420 | |
2421 case lir_sub: | |
2422 if (left_is_tos) { | |
2423 if (pop_fpu_stack) __ fsubrp(non_tos_index); | |
2424 else if (dest_is_tos) __ fsub (non_tos_index); | |
2425 else __ fsubra(non_tos_index); | |
2426 } else { | |
2427 if (pop_fpu_stack) __ fsubp (non_tos_index); | |
2428 else if (dest_is_tos) __ fsubr (non_tos_index); | |
2429 else __ fsuba (non_tos_index); | |
2430 } | |
2431 break; | |
2432 | |
2433 case lir_mul_strictfp: // fall through | |
2434 case lir_mul: | |
2435 if (pop_fpu_stack) __ fmulp(non_tos_index); | |
2436 else if (dest_is_tos) __ fmul (non_tos_index); | |
2437 else __ fmula(non_tos_index); | |
2438 break; | |
2439 | |
2440 case lir_div_strictfp: // fall through | |
2441 case lir_div: | |
2442 if (left_is_tos) { | |
2443 if (pop_fpu_stack) __ fdivrp(non_tos_index); | |
2444 else if (dest_is_tos) __ fdiv (non_tos_index); | |
2445 else __ fdivra(non_tos_index); | |
2446 } else { | |
2447 if (pop_fpu_stack) __ fdivp (non_tos_index); | |
2448 else if (dest_is_tos) __ fdivr (non_tos_index); | |
2449 else __ fdiva (non_tos_index); | |
2450 } | |
2451 break; | |
2452 | |
2453 case lir_rem: | |
2454 assert(left_is_tos && dest_is_tos && right_index == 1, "must be guaranteed by FPU stack allocation"); | |
2455 __ fremr(noreg); | |
2456 break; | |
2457 | |
2458 default: | |
2459 ShouldNotReachHere(); | |
2460 } | |
2461 } | |
2462 | |
2463 | |
2464 void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op) { | |
2465 if (value->is_double_xmm()) { | |
2466 switch(code) { | |
2467 case lir_abs : | |
2468 { | |
2469 if (dest->as_xmm_double_reg() != value->as_xmm_double_reg()) { | |
2470 __ movdbl(dest->as_xmm_double_reg(), value->as_xmm_double_reg()); | |
2471 } | |
2472 __ andpd(dest->as_xmm_double_reg(), | |
2473 ExternalAddress((address)double_signmask_pool)); | |
2474 } | |
2475 break; | |
2476 | |
2477 case lir_sqrt: __ sqrtsd(dest->as_xmm_double_reg(), value->as_xmm_double_reg()); break; | |
2478 // all other intrinsics are not available in the SSE instruction set, so FPU is used | |
2479 default : ShouldNotReachHere(); | |
2480 } | |
2481 | |
2482 } else if (value->is_double_fpu()) { | |
2483 assert(value->fpu_regnrLo() == 0 && dest->fpu_regnrLo() == 0, "both must be on TOS"); | |
2484 switch(code) { | |
2485 case lir_log : __ flog() ; break; | |
2486 case lir_log10 : __ flog10() ; break; | |
2487 case lir_abs : __ fabs() ; break; | |
2488 case lir_sqrt : __ fsqrt(); break; | |
2489 case lir_sin : | |
2490 // Should consider not saving rbx, if not necessary | |
2491 __ trigfunc('s', op->as_Op2()->fpu_stack_size()); | |
2492 break; | |
2493 case lir_cos : | |
2494 // Should consider not saving rbx, if not necessary | |
2495 assert(op->as_Op2()->fpu_stack_size() <= 6, "sin and cos need two free stack slots"); | |
2496 __ trigfunc('c', op->as_Op2()->fpu_stack_size()); | |
2497 break; | |
2498 case lir_tan : | |
2499 // Should consider not saving rbx, if not necessary | |
2500 __ trigfunc('t', op->as_Op2()->fpu_stack_size()); | |
2501 break; | |
2502 default : ShouldNotReachHere(); | |
2503 } | |
2504 } else { | |
2505 Unimplemented(); | |
2506 } | |
2507 } | |
2508 | |
2509 void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) { | |
2510 // assert(left->destroys_register(), "check"); | |
2511 if (left->is_single_cpu()) { | |
2512 Register reg = left->as_register(); | |
2513 if (right->is_constant()) { | |
2514 int val = right->as_constant_ptr()->as_jint(); | |
2515 switch (code) { | |
2516 case lir_logic_and: __ andl (reg, val); break; | |
2517 case lir_logic_or: __ orl (reg, val); break; | |
2518 case lir_logic_xor: __ xorl (reg, val); break; | |
2519 default: ShouldNotReachHere(); | |
2520 } | |
2521 } else if (right->is_stack()) { | |
2522 // added support for stack operands | |
2523 Address raddr = frame_map()->address_for_slot(right->single_stack_ix()); | |
2524 switch (code) { | |
2525 case lir_logic_and: __ andl (reg, raddr); break; | |
2526 case lir_logic_or: __ orl (reg, raddr); break; | |
2527 case lir_logic_xor: __ xorl (reg, raddr); break; | |
2528 default: ShouldNotReachHere(); | |
2529 } | |
2530 } else { | |
2531 Register rright = right->as_register(); | |
2532 switch (code) { | |
304 | 2533 case lir_logic_and: __ andptr (reg, rright); break; |
2534 case lir_logic_or : __ orptr (reg, rright); break; | |
2535 case lir_logic_xor: __ xorptr (reg, rright); break; | |
0 | 2536 default: ShouldNotReachHere(); |
2537 } | |
2538 } | |
2539 move_regs(reg, dst->as_register()); | |
2540 } else { | |
2541 Register l_lo = left->as_register_lo(); | |
2542 Register l_hi = left->as_register_hi(); | |
2543 if (right->is_constant()) { | |
304 | 2544 #ifdef _LP64 |
2545 __ mov64(rscratch1, right->as_constant_ptr()->as_jlong()); | |
2546 switch (code) { | |
2547 case lir_logic_and: | |
2548 __ andq(l_lo, rscratch1); | |
2549 break; | |
2550 case lir_logic_or: | |
2551 __ orq(l_lo, rscratch1); | |
2552 break; | |
2553 case lir_logic_xor: | |
2554 __ xorq(l_lo, rscratch1); | |
2555 break; | |
2556 default: ShouldNotReachHere(); | |
2557 } | |
2558 #else | |
0 | 2559 int r_lo = right->as_constant_ptr()->as_jint_lo(); |
2560 int r_hi = right->as_constant_ptr()->as_jint_hi(); | |
2561 switch (code) { | |
2562 case lir_logic_and: | |
2563 __ andl(l_lo, r_lo); | |
2564 __ andl(l_hi, r_hi); | |
2565 break; | |
2566 case lir_logic_or: | |
2567 __ orl(l_lo, r_lo); | |
2568 __ orl(l_hi, r_hi); | |
2569 break; | |
2570 case lir_logic_xor: | |
2571 __ xorl(l_lo, r_lo); | |
2572 __ xorl(l_hi, r_hi); | |
2573 break; | |
2574 default: ShouldNotReachHere(); | |
2575 } | |
304 | 2576 #endif // _LP64 |
0 | 2577 } else { |
1572 | 2578 #ifdef _LP64 |
2579 Register r_lo; | |
2580 if (right->type() == T_OBJECT || right->type() == T_ARRAY) { | |
2581 r_lo = right->as_register(); | |
2582 } else { | |
2583 r_lo = right->as_register_lo(); | |
2584 } | |
2585 #else | |
0 | 2586 Register r_lo = right->as_register_lo(); |
2587 Register r_hi = right->as_register_hi(); | |
2588 assert(l_lo != r_hi, "overwriting registers"); | |
1572 | 2589 #endif |
0 | 2590 switch (code) { |
2591 case lir_logic_and: | |
304 | 2592 __ andptr(l_lo, r_lo); |
2593 NOT_LP64(__ andptr(l_hi, r_hi);) | |
0 | 2594 break; |
2595 case lir_logic_or: | |
304 | 2596 __ orptr(l_lo, r_lo); |
2597 NOT_LP64(__ orptr(l_hi, r_hi);) | |
0 | 2598 break; |
2599 case lir_logic_xor: | |
304 | 2600 __ xorptr(l_lo, r_lo); |
2601 NOT_LP64(__ xorptr(l_hi, r_hi);) | |
0 | 2602 break; |
2603 default: ShouldNotReachHere(); | |
2604 } | |
2605 } | |
2606 | |
2607 Register dst_lo = dst->as_register_lo(); | |
2608 Register dst_hi = dst->as_register_hi(); | |
2609 | |
304 | 2610 #ifdef _LP64 |
2611 move_regs(l_lo, dst_lo); | |
2612 #else | |
0 | 2613 if (dst_lo == l_hi) { |
2614 assert(dst_hi != l_lo, "overwriting registers"); | |
2615 move_regs(l_hi, dst_hi); | |
2616 move_regs(l_lo, dst_lo); | |
2617 } else { | |
2618 assert(dst_lo != l_hi, "overwriting registers"); | |
2619 move_regs(l_lo, dst_lo); | |
2620 move_regs(l_hi, dst_hi); | |
2621 } | |
304 | 2622 #endif // _LP64 |
0 | 2623 } |
2624 } | |
2625 | |
2626 | |
2627 // we assume that rax, and rdx can be overwritten | |
2628 void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) { | |
2629 | |
2630 assert(left->is_single_cpu(), "left must be register"); | |
2631 assert(right->is_single_cpu() || right->is_constant(), "right must be register or constant"); | |
2632 assert(result->is_single_cpu(), "result must be register"); | |
2633 | |
2634 // assert(left->destroys_register(), "check"); | |
2635 // assert(right->destroys_register(), "check"); | |
2636 | |
2637 Register lreg = left->as_register(); | |
2638 Register dreg = result->as_register(); | |
2639 | |
2640 if (right->is_constant()) { | |
2641 int divisor = right->as_constant_ptr()->as_jint(); | |
2642 assert(divisor > 0 && is_power_of_2(divisor), "must be"); | |
2643 if (code == lir_idiv) { | |
2644 assert(lreg == rax, "must be rax,"); | |
2645 assert(temp->as_register() == rdx, "tmp register must be rdx"); | |
2646 __ cdql(); // sign extend into rdx:rax | |
2647 if (divisor == 2) { | |
2648 __ subl(lreg, rdx); | |
2649 } else { | |
2650 __ andl(rdx, divisor - 1); | |
2651 __ addl(lreg, rdx); | |
2652 } | |
2653 __ sarl(lreg, log2_intptr(divisor)); | |
2654 move_regs(lreg, dreg); | |
2655 } else if (code == lir_irem) { | |
2656 Label done; | |
304 | 2657 __ mov(dreg, lreg); |
0 | 2658 __ andl(dreg, 0x80000000 | (divisor - 1)); |
2659 __ jcc(Assembler::positive, done); | |
2660 __ decrement(dreg); | |
2661 __ orl(dreg, ~(divisor - 1)); | |
2662 __ increment(dreg); | |
2663 __ bind(done); | |
2664 } else { | |
2665 ShouldNotReachHere(); | |
2666 } | |
2667 } else { | |
2668 Register rreg = right->as_register(); | |
2669 assert(lreg == rax, "left register must be rax,"); | |
2670 assert(rreg != rdx, "right register must not be rdx"); | |
2671 assert(temp->as_register() == rdx, "tmp register must be rdx"); | |
2672 | |
2673 move_regs(lreg, rax); | |
2674 | |
2675 int idivl_offset = __ corrected_idivl(rreg); | |
2676 add_debug_info_for_div0(idivl_offset, info); | |
2677 if (code == lir_irem) { | |
2678 move_regs(rdx, dreg); // result is in rdx | |
2679 } else { | |
2680 move_regs(rax, dreg); | |
2681 } | |
2682 } | |
2683 } | |
2684 | |
2685 | |
2686 void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) { | |
2687 if (opr1->is_single_cpu()) { | |
2688 Register reg1 = opr1->as_register(); | |
2689 if (opr2->is_single_cpu()) { | |
2690 // cpu register - cpu register | |
304 | 2691 if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { |
2692 __ cmpptr(reg1, opr2->as_register()); | |
2693 } else { | |
2694 assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?"); | |
2695 __ cmpl(reg1, opr2->as_register()); | |
2696 } | |
0 | 2697 } else if (opr2->is_stack()) { |
2698 // cpu register - stack | |
304 | 2699 if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) { |
2700 __ cmpptr(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); | |
2701 } else { | |
2702 __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); | |
2703 } | |
0 | 2704 } else if (opr2->is_constant()) { |
2705 // cpu register - constant | |
2706 LIR_Const* c = opr2->as_constant_ptr(); | |
2707 if (c->type() == T_INT) { | |
2708 __ cmpl(reg1, c->as_jint()); | |
304 | 2709 } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) { |
2710 // In 64bit oops are single register | |
0 | 2711 jobject o = c->as_jobject(); |
2712 if (o == NULL) { | |
304 | 2713 __ cmpptr(reg1, (int32_t)NULL_WORD); |
0 | 2714 } else { |
304 | 2715 #ifdef _LP64 |
2716 __ movoop(rscratch1, o); | |
2717 __ cmpptr(reg1, rscratch1); | |
2718 #else | |
0 | 2719 __ cmpoop(reg1, c->as_jobject()); |
304 | 2720 #endif // _LP64 |
0 | 2721 } |
2722 } else { | |
2723 ShouldNotReachHere(); | |
2724 } | |
2725 // cpu register - address | |
2726 } else if (opr2->is_address()) { | |
2727 if (op->info() != NULL) { | |
2728 add_debug_info_for_null_check_here(op->info()); | |
2729 } | |
2730 __ cmpl(reg1, as_Address(opr2->as_address_ptr())); | |
2731 } else { | |
2732 ShouldNotReachHere(); | |
2733 } | |
2734 | |
2735 } else if(opr1->is_double_cpu()) { | |
2736 Register xlo = opr1->as_register_lo(); | |
2737 Register xhi = opr1->as_register_hi(); | |
2738 if (opr2->is_double_cpu()) { | |
304 | 2739 #ifdef _LP64 |
2740 __ cmpptr(xlo, opr2->as_register_lo()); | |
2741 #else | |
0 | 2742 // cpu register - cpu register |
2743 Register ylo = opr2->as_register_lo(); | |
2744 Register yhi = opr2->as_register_hi(); | |
2745 __ subl(xlo, ylo); | |
2746 __ sbbl(xhi, yhi); | |
2747 if (condition == lir_cond_equal || condition == lir_cond_notEqual) { | |
2748 __ orl(xhi, xlo); | |
2749 } | |
304 | 2750 #endif // _LP64 |
0 | 2751 } else if (opr2->is_constant()) { |
2752 // cpu register - constant 0 | |
2753 assert(opr2->as_jlong() == (jlong)0, "only handles zero"); | |
304 | 2754 #ifdef _LP64 |
2755 __ cmpptr(xlo, (int32_t)opr2->as_jlong()); | |
2756 #else | |
0 | 2757 assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles equals case"); |
2758 __ orl(xhi, xlo); | |
304 | 2759 #endif // _LP64 |
0 | 2760 } else { |
2761 ShouldNotReachHere(); | |
2762 } | |
2763 | |
2764 } else if (opr1->is_single_xmm()) { | |
2765 XMMRegister reg1 = opr1->as_xmm_float_reg(); | |
2766 if (opr2->is_single_xmm()) { | |
2767 // xmm register - xmm register | |
2768 __ ucomiss(reg1, opr2->as_xmm_float_reg()); | |
2769 } else if (opr2->is_stack()) { | |
2770 // xmm register - stack | |
2771 __ ucomiss(reg1, frame_map()->address_for_slot(opr2->single_stack_ix())); | |
2772 } else if (opr2->is_constant()) { | |
2773 // xmm register - constant | |
2774 __ ucomiss(reg1, InternalAddress(float_constant(opr2->as_jfloat()))); | |
2775 } else if (opr2->is_address()) { | |
2776 // xmm register - address | |
2777 if (op->info() != NULL) { | |
2778 add_debug_info_for_null_check_here(op->info()); | |
2779 } | |
2780 __ ucomiss(reg1, as_Address(opr2->as_address_ptr())); | |
2781 } else { | |
2782 ShouldNotReachHere(); | |
2783 } | |
2784 | |
2785 } else if (opr1->is_double_xmm()) { | |
2786 XMMRegister reg1 = opr1->as_xmm_double_reg(); | |
2787 if (opr2->is_double_xmm()) { | |
2788 // xmm register - xmm register | |
2789 __ ucomisd(reg1, opr2->as_xmm_double_reg()); | |
2790 } else if (opr2->is_stack()) { | |
2791 // xmm register - stack | |
2792 __ ucomisd(reg1, frame_map()->address_for_slot(opr2->double_stack_ix())); | |
2793 } else if (opr2->is_constant()) { | |
2794 // xmm register - constant | |
2795 __ ucomisd(reg1, InternalAddress(double_constant(opr2->as_jdouble()))); | |
2796 } else if (opr2->is_address()) { | |
2797 // xmm register - address | |
2798 if (op->info() != NULL) { | |
2799 add_debug_info_for_null_check_here(op->info()); | |
2800 } | |
2801 __ ucomisd(reg1, as_Address(opr2->pointer()->as_address())); | |
2802 } else { | |
2803 ShouldNotReachHere(); | |
2804 } | |
2805 | |
2806 } else if(opr1->is_single_fpu() || opr1->is_double_fpu()) { | |
2807 assert(opr1->is_fpu_register() && opr1->fpu() == 0, "currently left-hand side must be on TOS (relax this restriction)"); | |
2808 assert(opr2->is_fpu_register(), "both must be registers"); | |
2809 __ fcmp(noreg, opr2->fpu(), op->fpu_pop_count() > 0, op->fpu_pop_count() > 1); | |
2810 | |
2811 } else if (opr1->is_address() && opr2->is_constant()) { | |
304 | 2812 LIR_Const* c = opr2->as_constant_ptr(); |
2813 #ifdef _LP64 | |
2814 if (c->type() == T_OBJECT || c->type() == T_ARRAY) { | |
2815 assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "need to reverse"); | |
2816 __ movoop(rscratch1, c->as_jobject()); | |
2817 } | |
2818 #endif // LP64 | |
0 | 2819 if (op->info() != NULL) { |
2820 add_debug_info_for_null_check_here(op->info()); | |
2821 } | |
2822 // special case: address - constant | |
2823 LIR_Address* addr = opr1->as_address_ptr(); | |
2824 if (c->type() == T_INT) { | |
2825 __ cmpl(as_Address(addr), c->as_jint()); | |
304 | 2826 } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) { |
2827 #ifdef _LP64 | |
2828 // %%% Make this explode if addr isn't reachable until we figure out a | |
2829 // better strategy by giving noreg as the temp for as_Address | |
2830 __ cmpptr(rscratch1, as_Address(addr, noreg)); | |
2831 #else | |
0 | 2832 __ cmpoop(as_Address(addr), c->as_jobject()); |
304 | 2833 #endif // _LP64 |
0 | 2834 } else { |
2835 ShouldNotReachHere(); | |
2836 } | |
2837 | |
2838 } else { | |
2839 ShouldNotReachHere(); | |
2840 } | |
2841 } | |
2842 | |
2843 void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op) { | |
2844 if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) { | |
2845 if (left->is_single_xmm()) { | |
2846 assert(right->is_single_xmm(), "must match"); | |
2847 __ cmpss2int(left->as_xmm_float_reg(), right->as_xmm_float_reg(), dst->as_register(), code == lir_ucmp_fd2i); | |
2848 } else if (left->is_double_xmm()) { | |
2849 assert(right->is_double_xmm(), "must match"); | |
2850 __ cmpsd2int(left->as_xmm_double_reg(), right->as_xmm_double_reg(), dst->as_register(), code == lir_ucmp_fd2i); | |
2851 | |
2852 } else { | |
2853 assert(left->is_single_fpu() || left->is_double_fpu(), "must be"); | |
2854 assert(right->is_single_fpu() || right->is_double_fpu(), "must match"); | |
2855 | |
2856 assert(left->fpu() == 0, "left must be on TOS"); | |
2857 __ fcmp2int(dst->as_register(), code == lir_ucmp_fd2i, right->fpu(), | |
2858 op->fpu_pop_count() > 0, op->fpu_pop_count() > 1); | |
2859 } | |
2860 } else { | |
2861 assert(code == lir_cmp_l2i, "check"); | |
304 | 2862 #ifdef _LP64 |
1369 | 2863 Label done; |
2864 Register dest = dst->as_register(); | |
2865 __ cmpptr(left->as_register_lo(), right->as_register_lo()); | |
2866 __ movl(dest, -1); | |
2867 __ jccb(Assembler::less, done); | |
2868 __ set_byte_if_not_zero(dest); | |
2869 __ movzbl(dest, dest); | |
2870 __ bind(done); | |
304 | 2871 #else |
0 | 2872 __ lcmp2int(left->as_register_hi(), |
2873 left->as_register_lo(), | |
2874 right->as_register_hi(), | |
2875 right->as_register_lo()); | |
2876 move_regs(left->as_register_hi(), dst->as_register()); | |
304 | 2877 #endif // _LP64 |
0 | 2878 } |
2879 } | |
2880 | |
2881 | |
2882 void LIR_Assembler::align_call(LIR_Code code) { | |
2883 if (os::is_MP()) { | |
2884 // make sure that the displacement word of the call ends up word aligned | |
2885 int offset = __ offset(); | |
2886 switch (code) { | |
2887 case lir_static_call: | |
2888 case lir_optvirtual_call: | |
1295 | 2889 case lir_dynamic_call: |
0 | 2890 offset += NativeCall::displacement_offset; |
2891 break; | |
2892 case lir_icvirtual_call: | |
2893 offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size; | |
2894 break; | |
2895 case lir_virtual_call: // currently, sparc-specific for niagara | |
2896 default: ShouldNotReachHere(); | |
2897 } | |
2898 while (offset++ % BytesPerWord != 0) { | |
2899 __ nop(); | |
2900 } | |
2901 } | |
2902 } | |
2903 | |
2904 | |
1295 | 2905 void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) { |
0 | 2906 assert(!os::is_MP() || (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, |
2907 "must be aligned"); | |
1295 | 2908 __ call(AddressLiteral(op->addr(), rtype)); |
1564 | 2909 add_call_info(code_offset(), op->info()); |
0 | 2910 } |
2911 | |
2912 | |
1295 | 2913 void LIR_Assembler::ic_call(LIR_OpJavaCall* op) { |
0 | 2914 RelocationHolder rh = virtual_call_Relocation::spec(pc()); |
2915 __ movoop(IC_Klass, (jobject)Universe::non_oop_word()); | |
2916 assert(!os::is_MP() || | |
2917 (__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0, | |
2918 "must be aligned"); | |
1295 | 2919 __ call(AddressLiteral(op->addr(), rh)); |
1564 | 2920 add_call_info(code_offset(), op->info()); |
0 | 2921 } |
2922 | |
2923 | |
2924 /* Currently, vtable-dispatch is only enabled for sparc platforms */ | |
1295 | 2925 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) { |
0 | 2926 ShouldNotReachHere(); |
2927 } | |
2928 | |
1295 | 2929 |
0 | 2930 void LIR_Assembler::emit_static_call_stub() { |
2931 address call_pc = __ pc(); | |
2932 address stub = __ start_a_stub(call_stub_size); | |
2933 if (stub == NULL) { | |
2934 bailout("static call stub overflow"); | |
2935 return; | |
2936 } | |
2937 | |
2938 int start = __ offset(); | |
2939 if (os::is_MP()) { | |
2940 // make sure that the displacement word of the call ends up word aligned | |
2941 int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset; | |
2942 while (offset++ % BytesPerWord != 0) { | |
2943 __ nop(); | |
2944 } | |
2945 } | |
2946 __ relocate(static_stub_Relocation::spec(call_pc)); | |
2947 __ movoop(rbx, (jobject)NULL); | |
2948 // must be set to -1 at code generation time | |
2949 assert(!os::is_MP() || ((__ offset() + 1) % BytesPerWord) == 0, "must be aligned on MP"); | |
304 | 2950 // On 64bit this will die since it will take a movq & jmp, must be only a jmp |
2951 __ jump(RuntimeAddress(__ pc())); | |
0 | 2952 |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1378
diff
changeset
|
2953 assert(__ offset() - start <= call_stub_size, "stub too big"); |
0 | 2954 __ end_a_stub(); |
2955 } | |
2956 | |
2957 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2958 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { |
0 | 2959 assert(exceptionOop->as_register() == rax, "must match"); |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2960 assert(exceptionPC->as_register() == rdx, "must match"); |
0 | 2961 |
2962 // exception object is not added to oop map by LinearScan | |
2963 // (LinearScan assumes that no oops are in fixed registers) | |
2964 info->add_register_oop(exceptionOop); | |
2965 Runtime1::StubID unwind_id; | |
2966 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2967 // get current pc information |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2968 // pc is only needed if the method has an exception handler, the unwind code does not need it. |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2969 int pc_for_athrow_offset = __ offset(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2970 InternalAddress pc_for_athrow(__ pc()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2971 __ lea(exceptionPC->as_register(), pc_for_athrow); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2972 add_call_info(pc_for_athrow_offset, info); // for exception handler |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2973 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2974 __ verify_not_null_oop(rax); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2975 // search an exception handler (rax: exception oop, rdx: throwing pc) |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2976 if (compilation()->has_fpu_code()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2977 unwind_id = Runtime1::handle_exception_id; |
0 | 2978 } else { |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2979 unwind_id = Runtime1::handle_exception_nofpu_id; |
0 | 2980 } |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2981 __ call(RuntimeAddress(Runtime1::entry_for(unwind_id))); |
0 | 2982 |
2983 // enough room for two byte trap | |
2984 __ nop(); | |
2985 } | |
2986 | |
2987 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2988 void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2989 assert(exceptionOop->as_register() == rax, "must match"); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2990 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2991 __ jmp(_unwind_handler_entry); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2992 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2993 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1369
diff
changeset
|
2994 |
0 | 2995 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) { |
2996 | |
2997 // optimized version for linear scan: | |
2998 // * count must be already in ECX (guaranteed by LinearScan) | |
2999 // * left and dest must be equal | |
3000 // * tmp must be unused | |
3001 assert(count->as_register() == SHIFT_count, "count must be in ECX"); | |
3002 assert(left == dest, "left and dest must be equal"); | |
3003 assert(tmp->is_illegal(), "wasting a register if tmp is allocated"); | |
3004 | |
3005 if (left->is_single_cpu()) { | |
3006 Register value = left->as_register(); | |
3007 assert(value != SHIFT_count, "left cannot be ECX"); | |
3008 | |
3009 switch (code) { | |
3010 case lir_shl: __ shll(value); break; | |
3011 case lir_shr: __ sarl(value); break; | |
3012 case lir_ushr: __ shrl(value); break; | |
3013 default: ShouldNotReachHere(); | |
3014 } | |
3015 } else if (left->is_double_cpu()) { | |
3016 Register lo = left->as_register_lo(); | |
3017 Register hi = left->as_register_hi(); | |
3018 assert(lo != SHIFT_count && hi != SHIFT_count, "left cannot be ECX"); | |
304 | 3019 #ifdef _LP64 |
3020 switch (code) { | |
3021 case lir_shl: __ shlptr(lo); break; | |
3022 case lir_shr: __ sarptr(lo); break; | |
3023 case lir_ushr: __ shrptr(lo); break; | |
3024 default: ShouldNotReachHere(); | |
3025 } | |
3026 #else | |
0 | 3027 |
3028 switch (code) { | |
3029 case lir_shl: __ lshl(hi, lo); break; | |
3030 case lir_shr: __ lshr(hi, lo, true); break; | |
3031 case lir_ushr: __ lshr(hi, lo, false); break; | |
3032 default: ShouldNotReachHere(); | |
3033 } | |
304 | 3034 #endif // LP64 |
0 | 3035 } else { |
3036 ShouldNotReachHere(); | |
3037 } | |
3038 } | |
3039 | |
3040 | |
3041 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) { | |
3042 if (dest->is_single_cpu()) { | |
3043 // first move left into dest so that left is not destroyed by the shift | |
3044 Register value = dest->as_register(); | |
3045 count = count & 0x1F; // Java spec | |
3046 | |
3047 move_regs(left->as_register(), value); | |
3048 switch (code) { | |
3049 case lir_shl: __ shll(value, count); break; | |
3050 case lir_shr: __ sarl(value, count); break; | |
3051 case lir_ushr: __ shrl(value, count); break; | |
3052 default: ShouldNotReachHere(); | |
3053 } | |
3054 } else if (dest->is_double_cpu()) { | |
304 | 3055 #ifndef _LP64 |
0 | 3056 Unimplemented(); |
304 | 3057 #else |
3058 // first move left into dest so that left is not destroyed by the shift | |
3059 Register value = dest->as_register_lo(); | |
3060 count = count & 0x1F; // Java spec | |
3061 | |
3062 move_regs(left->as_register_lo(), value); | |
3063 switch (code) { | |
3064 case lir_shl: __ shlptr(value, count); break; | |
3065 case lir_shr: __ sarptr(value, count); break; | |
3066 case lir_ushr: __ shrptr(value, count); break; | |
3067 default: ShouldNotReachHere(); | |
3068 } | |
3069 #endif // _LP64 | |
0 | 3070 } else { |
3071 ShouldNotReachHere(); | |
3072 } | |
3073 } | |
3074 | |
3075 | |
3076 void LIR_Assembler::store_parameter(Register r, int offset_from_rsp_in_words) { | |
3077 assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); | |
3078 int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; | |
3079 assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); | |
304 | 3080 __ movptr (Address(rsp, offset_from_rsp_in_bytes), r); |
0 | 3081 } |
3082 | |
3083 | |
3084 void LIR_Assembler::store_parameter(jint c, int offset_from_rsp_in_words) { | |
3085 assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); | |
3086 int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; | |
3087 assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); | |
304 | 3088 __ movptr (Address(rsp, offset_from_rsp_in_bytes), c); |
0 | 3089 } |
3090 | |
3091 | |
3092 void LIR_Assembler::store_parameter(jobject o, int offset_from_rsp_in_words) { | |
3093 assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp"); | |
3094 int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord; | |
3095 assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset"); | |
3096 __ movoop (Address(rsp, offset_from_rsp_in_bytes), o); | |
3097 } | |
3098 | |
3099 | |
3100 // This code replaces a call to arraycopy; no exception may | |
3101 // be thrown in this code, they must be thrown in the System.arraycopy | |
3102 // activation frame; we could save some checks if this would not be the case | |
3103 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { | |
3104 ciArrayKlass* default_type = op->expected_type(); | |
3105 Register src = op->src()->as_register(); | |
3106 Register dst = op->dst()->as_register(); | |
3107 Register src_pos = op->src_pos()->as_register(); | |
3108 Register dst_pos = op->dst_pos()->as_register(); | |
3109 Register length = op->length()->as_register(); | |
3110 Register tmp = op->tmp()->as_register(); | |
3111 | |
3112 CodeStub* stub = op->stub(); | |
3113 int flags = op->flags(); | |
3114 BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL; | |
3115 if (basic_type == T_ARRAY) basic_type = T_OBJECT; | |
3116 | |
3117 // if we don't know anything or it's an object array, just go through the generic arraycopy | |
3118 if (default_type == NULL) { | |
3119 Label done; | |
3120 // save outgoing arguments on stack in case call to System.arraycopy is needed | |
3121 // HACK ALERT. This code used to push the parameters in a hardwired fashion | |
3122 // for interpreter calling conventions. Now we have to do it in new style conventions. | |
3123 // For the moment until C1 gets the new register allocator I just force all the | |
3124 // args to the right place (except the register args) and then on the back side | |
3125 // reload the register args properly if we go slow path. Yuck | |
3126 | |
3127 // These are proper for the calling convention | |
3128 | |
3129 store_parameter(length, 2); | |
3130 store_parameter(dst_pos, 1); | |
3131 store_parameter(dst, 0); | |
3132 | |
3133 // these are just temporary placements until we need to reload | |
3134 store_parameter(src_pos, 3); | |
3135 store_parameter(src, 4); | |
304 | 3136 NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");) |
3137 | |
3138 address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); | |
0 | 3139 |
3140 // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint | |
304 | 3141 #ifdef _LP64 |
3142 // The arguments are in java calling convention so we can trivially shift them to C | |
3143 // convention | |
3144 assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); | |
3145 __ mov(c_rarg0, j_rarg0); | |
3146 assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4); | |
3147 __ mov(c_rarg1, j_rarg1); | |
3148 assert_different_registers(c_rarg2, j_rarg3, j_rarg4); | |
3149 __ mov(c_rarg2, j_rarg2); | |
3150 assert_different_registers(c_rarg3, j_rarg4); | |
3151 __ mov(c_rarg3, j_rarg3); | |
3152 #ifdef _WIN64 | |
3153 // Allocate abi space for args but be sure to keep stack aligned | |
3154 __ subptr(rsp, 6*wordSize); | |
3155 store_parameter(j_rarg4, 4); | |
3156 __ call(RuntimeAddress(entry)); | |
3157 __ addptr(rsp, 6*wordSize); | |
3158 #else | |
3159 __ mov(c_rarg4, j_rarg4); | |
3160 __ call(RuntimeAddress(entry)); | |
3161 #endif // _WIN64 | |
3162 #else | |
3163 __ push(length); | |
3164 __ push(dst_pos); | |
3165 __ push(dst); | |
3166 __ push(src_pos); | |
3167 __ push(src); | |
0 | 3168 __ call_VM_leaf(entry, 5); // removes pushed parameter from the stack |
3169 | |
304 | 3170 #endif // _LP64 |
3171 | |
0 | 3172 __ cmpl(rax, 0); |
3173 __ jcc(Assembler::equal, *stub->continuation()); | |
3174 | |
3175 // Reload values from the stack so they are where the stub | |
3176 // expects them. | |
304 | 3177 __ movptr (dst, Address(rsp, 0*BytesPerWord)); |
3178 __ movptr (dst_pos, Address(rsp, 1*BytesPerWord)); | |
3179 __ movptr (length, Address(rsp, 2*BytesPerWord)); | |
3180 __ movptr (src_pos, Address(rsp, 3*BytesPerWord)); | |
3181 __ movptr (src, Address(rsp, 4*BytesPerWord)); | |
0 | 3182 __ jmp(*stub->entry()); |
3183 | |
3184 __ bind(*stub->continuation()); | |
3185 return; | |
3186 } | |
3187 | |
3188 assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point"); | |
3189 | |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
0
diff
changeset
|
3190 int elem_size = type2aelembytes(basic_type); |
0 | 3191 int shift_amount; |
3192 Address::ScaleFactor scale; | |
3193 | |
3194 switch (elem_size) { | |
3195 case 1 : | |
3196 shift_amount = 0; | |
3197 scale = Address::times_1; | |
3198 break; | |
3199 case 2 : | |
3200 shift_amount = 1; | |
3201 scale = Address::times_2; | |
3202 break; | |
3203 case 4 : | |
3204 shift_amount = 2; | |
3205 scale = Address::times_4; | |
3206 break; | |
3207 case 8 : | |
3208 shift_amount = 3; | |
3209 scale = Address::times_8; | |
3210 break; | |
3211 default: | |
3212 ShouldNotReachHere(); | |
3213 } | |
3214 | |
3215 Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes()); | |
3216 Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes()); | |
3217 Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes()); | |
3218 Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes()); | |
3219 | |
304 | 3220 // length and pos's are all sign extended at this point on 64bit |
3221 | |
0 | 3222 // test for NULL |
3223 if (flags & LIR_OpArrayCopy::src_null_check) { | |
304 | 3224 __ testptr(src, src); |
0 | 3225 __ jcc(Assembler::zero, *stub->entry()); |
3226 } | |
3227 if (flags & LIR_OpArrayCopy::dst_null_check) { | |
304 | 3228 __ testptr(dst, dst); |
0 | 3229 __ jcc(Assembler::zero, *stub->entry()); |
3230 } | |
3231 | |
3232 // check if negative | |
3233 if (flags & LIR_OpArrayCopy::src_pos_positive_check) { | |
3234 __ testl(src_pos, src_pos); | |
3235 __ jcc(Assembler::less, *stub->entry()); | |
3236 } | |
3237 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) { | |
3238 __ testl(dst_pos, dst_pos); | |
3239 __ jcc(Assembler::less, *stub->entry()); | |
3240 } | |
3241 if (flags & LIR_OpArrayCopy::length_positive_check) { | |
3242 __ testl(length, length); | |
3243 __ jcc(Assembler::less, *stub->entry()); | |
3244 } | |
3245 | |
3246 if (flags & LIR_OpArrayCopy::src_range_check) { | |
304 | 3247 __ lea(tmp, Address(src_pos, length, Address::times_1, 0)); |
0 | 3248 __ cmpl(tmp, src_length_addr); |
3249 __ jcc(Assembler::above, *stub->entry()); | |
3250 } | |
3251 if (flags & LIR_OpArrayCopy::dst_range_check) { | |
304 | 3252 __ lea(tmp, Address(dst_pos, length, Address::times_1, 0)); |
0 | 3253 __ cmpl(tmp, dst_length_addr); |
3254 __ jcc(Assembler::above, *stub->entry()); | |
3255 } | |
3256 | |
3257 if (flags & LIR_OpArrayCopy::type_check) { | |
2002 | 3258 if (UseCompressedOops) { |
3259 __ movl(tmp, src_klass_addr); | |
3260 __ cmpl(tmp, dst_klass_addr); | |
3261 } else { | |
3262 __ movptr(tmp, src_klass_addr); | |
3263 __ cmpptr(tmp, dst_klass_addr); | |
3264 } | |
0 | 3265 __ jcc(Assembler::notEqual, *stub->entry()); |
3266 } | |
3267 | |
3268 #ifdef ASSERT | |
3269 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { | |
3270 // Sanity check the known type with the incoming class. For the | |
3271 // primitive case the types must match exactly with src.klass and | |
3272 // dst.klass each exactly matching the default type. For the | |
3273 // object array case, if no type check is needed then either the | |
3274 // dst type is exactly the expected type and the src type is a | |
3275 // subtype which we can't check or src is the same array as dst | |
3276 // but not necessarily exactly of type default_type. | |
3277 Label known_ok, halt; | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
780
diff
changeset
|
3278 __ movoop(tmp, default_type->constant_encoding()); |
2002 | 3279 #ifdef _LP64 |
3280 if (UseCompressedOops) { | |
3281 __ encode_heap_oop(tmp); | |
3282 } | |
3283 #endif | |
3284 | |
0 | 3285 if (basic_type != T_OBJECT) { |
2002 | 3286 |
3287 if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); | |
3288 else __ cmpptr(tmp, dst_klass_addr); | |
0 | 3289 __ jcc(Assembler::notEqual, halt); |
2002 | 3290 if (UseCompressedOops) __ cmpl(tmp, src_klass_addr); |
3291 else __ cmpptr(tmp, src_klass_addr); | |
0 | 3292 __ jcc(Assembler::equal, known_ok); |
3293 } else { | |
2002 | 3294 if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); |
3295 else __ cmpptr(tmp, dst_klass_addr); | |
0 | 3296 __ jcc(Assembler::equal, known_ok); |
304 | 3297 __ cmpptr(src, dst); |
0 | 3298 __ jcc(Assembler::equal, known_ok); |
3299 } | |
3300 __ bind(halt); | |
3301 __ stop("incorrect type information in arraycopy"); | |
3302 __ bind(known_ok); | |
3303 } | |
3304 #endif | |
3305 | |
304 | 3306 if (shift_amount > 0 && basic_type != T_OBJECT) { |
3307 __ shlptr(length, shift_amount); | |
3308 } | |
3309 | |
3310 #ifdef _LP64 | |
3311 assert_different_registers(c_rarg0, dst, dst_pos, length); | |
1060 | 3312 __ movl2ptr(src_pos, src_pos); //higher 32bits must be null |
304 | 3313 __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3314 assert_different_registers(c_rarg1, length); | |
1060 | 3315 __ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null |
304 | 3316 __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3317 __ mov(c_rarg2, length); | |
3318 | |
3319 #else | |
3320 __ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); | |
0 | 3321 store_parameter(tmp, 0); |
304 | 3322 __ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
0 | 3323 store_parameter(tmp, 1); |
3324 store_parameter(length, 2); | |
304 | 3325 #endif // _LP64 |
0 | 3326 if (basic_type == T_OBJECT) { |
3327 __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy), 0); | |
3328 } else { | |
3329 __ call_VM_leaf(CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy), 0); | |
3330 } | |
3331 | |
3332 __ bind(*stub->continuation()); | |
3333 } | |
3334 | |
3335 | |
3336 void LIR_Assembler::emit_lock(LIR_OpLock* op) { | |
3337 Register obj = op->obj_opr()->as_register(); // may not be an oop | |
3338 Register hdr = op->hdr_opr()->as_register(); | |
3339 Register lock = op->lock_opr()->as_register(); | |
3340 if (!UseFastLocking) { | |
3341 __ jmp(*op->stub()->entry()); | |
3342 } else if (op->code() == lir_lock) { | |
3343 Register scratch = noreg; | |
3344 if (UseBiasedLocking) { | |
3345 scratch = op->scratch_opr()->as_register(); | |
3346 } | |
3347 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); | |
3348 // add debug info for NullPointerException only if one is possible | |
3349 int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry()); | |
3350 if (op->info() != NULL) { | |
3351 add_debug_info_for_null_check(null_check_offset, op->info()); | |
3352 } | |
3353 // done | |
3354 } else if (op->code() == lir_unlock) { | |
3355 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); | |
3356 __ unlock_object(hdr, obj, lock, *op->stub()->entry()); | |
3357 } else { | |
3358 Unimplemented(); | |
3359 } | |
3360 __ bind(*op->stub()->continuation()); | |
3361 } | |
3362 | |
3363 | |
3364 void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { | |
3365 ciMethod* method = op->profiled_method(); | |
3366 int bci = op->profiled_bci(); | |
3367 | |
3368 // Update counter for all call types | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
3369 ciMethodData* md = method->method_data_or_null(); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
3370 assert(md != NULL, "Sanity"); |
0 | 3371 ciProfileData* data = md->bci_to_data(bci); |
3372 assert(data->is_CounterData(), "need CounterData for calls"); | |
3373 assert(op->mdo()->is_single_cpu(), "mdo must be allocated"); | |
3374 Register mdo = op->mdo()->as_register(); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
780
diff
changeset
|
3375 __ movoop(mdo, md->constant_encoding()); |
0 | 3376 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); |
3377 Bytecodes::Code bc = method->java_code_at_bci(bci); | |
3378 // Perform additional virtual call profiling for invokevirtual and | |
3379 // invokeinterface bytecodes | |
3380 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && | |
1783 | 3381 C1ProfileVirtualCalls) { |
0 | 3382 assert(op->recv()->is_single_cpu(), "recv must be allocated"); |
3383 Register recv = op->recv()->as_register(); | |
3384 assert_different_registers(mdo, recv); | |
3385 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); | |
3386 ciKlass* known_klass = op->known_holder(); | |
1783 | 3387 if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { |
0 | 3388 // We know the type that will be seen at this call site; we can |
3389 // statically update the methodDataOop rather than needing to do | |
3390 // dynamic tests on the receiver type | |
3391 | |
3392 // NOTE: we should probably put a lock around this search to | |
3393 // avoid collisions by concurrent compilations | |
3394 ciVirtualCallData* vc_data = (ciVirtualCallData*) data; | |
3395 uint i; | |
3396 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
3397 ciKlass* receiver = vc_data->receiver(i); | |
3398 if (known_klass->equals(receiver)) { | |
3399 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); | |
1783 | 3400 __ addptr(data_addr, DataLayout::counter_increment); |
0 | 3401 return; |
3402 } | |
3403 } | |
3404 | |
3405 // Receiver type not found in profile data; select an empty slot | |
3406 | |
3407 // Note that this is less efficient than it should be because it | |
3408 // always does a write to the receiver part of the | |
3409 // VirtualCallData rather than just the first time | |
3410 for (i = 0; i < VirtualCallData::row_limit(); i++) { | |
3411 ciKlass* receiver = vc_data->receiver(i); | |
3412 if (receiver == NULL) { | |
3413 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
780
diff
changeset
|
3414 __ movoop(recv_addr, known_klass->constant_encoding()); |
0 | 3415 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); |
1783 | 3416 __ addptr(data_addr, DataLayout::counter_increment); |
0 | 3417 return; |
3418 } | |
3419 } | |
3420 } else { | |
2002 | 3421 __ load_klass(recv, recv); |
0 | 3422 Label update_done; |
1783 | 3423 type_profile_helper(mdo, md, data, recv, &update_done); |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
3424 // Receiver did not match any saved receiver and there is no empty row for it. |
1251
576e77447e3c
6923002: assert(false,"this call site should not be polymorphic")
kvn
parents:
1206
diff
changeset
|
3425 // Increment total counter to indicate polymorphic case. |
1783 | 3426 __ addptr(counter_addr, DataLayout::counter_increment); |
0 | 3427 |
3428 __ bind(update_done); | |
3429 } | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
3430 } else { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
3431 // Static call |
1783 | 3432 __ addptr(counter_addr, DataLayout::counter_increment); |
0 | 3433 } |
3434 } | |
3435 | |
3436 void LIR_Assembler::emit_delay(LIR_OpDelay*) { | |
3437 Unimplemented(); | |
3438 } | |
3439 | |
3440 | |
3441 void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) { | |
304 | 3442 __ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no)); |
0 | 3443 } |
3444 | |
3445 | |
3446 void LIR_Assembler::align_backward_branch_target() { | |
3447 __ align(BytesPerWord); | |
3448 } | |
3449 | |
3450 | |
3451 void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) { | |
3452 if (left->is_single_cpu()) { | |
3453 __ negl(left->as_register()); | |
3454 move_regs(left->as_register(), dest->as_register()); | |
3455 | |
3456 } else if (left->is_double_cpu()) { | |
3457 Register lo = left->as_register_lo(); | |
304 | 3458 #ifdef _LP64 |
3459 Register dst = dest->as_register_lo(); | |
3460 __ movptr(dst, lo); | |
3461 __ negptr(dst); | |
3462 #else | |
0 | 3463 Register hi = left->as_register_hi(); |
3464 __ lneg(hi, lo); | |
3465 if (dest->as_register_lo() == hi) { | |
3466 assert(dest->as_register_hi() != lo, "destroying register"); | |
3467 move_regs(hi, dest->as_register_hi()); | |
3468 move_regs(lo, dest->as_register_lo()); | |
3469 } else { | |
3470 move_regs(lo, dest->as_register_lo()); | |
3471 move_regs(hi, dest->as_register_hi()); | |
3472 } | |
304 | 3473 #endif // _LP64 |
0 | 3474 |
3475 } else if (dest->is_single_xmm()) { | |
3476 if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) { | |
3477 __ movflt(dest->as_xmm_float_reg(), left->as_xmm_float_reg()); | |
3478 } | |
3479 __ xorps(dest->as_xmm_float_reg(), | |
3480 ExternalAddress((address)float_signflip_pool)); | |
3481 | |
3482 } else if (dest->is_double_xmm()) { | |
3483 if (left->as_xmm_double_reg() != dest->as_xmm_double_reg()) { | |
3484 __ movdbl(dest->as_xmm_double_reg(), left->as_xmm_double_reg()); | |
3485 } | |
3486 __ xorpd(dest->as_xmm_double_reg(), | |
3487 ExternalAddress((address)double_signflip_pool)); | |
3488 | |
3489 } else if (left->is_single_fpu() || left->is_double_fpu()) { | |
3490 assert(left->fpu() == 0, "arg must be on TOS"); | |
3491 assert(dest->fpu() == 0, "dest must be TOS"); | |
3492 __ fchs(); | |
3493 | |
3494 } else { | |
3495 ShouldNotReachHere(); | |
3496 } | |
3497 } | |
3498 | |
3499 | |
3500 void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) { | |
3501 assert(addr->is_address() && dest->is_register(), "check"); | |
304 | 3502 Register reg; |
3503 reg = dest->as_pointer_register(); | |
3504 __ lea(reg, as_Address(addr->as_address_ptr())); | |
0 | 3505 } |
3506 | |
3507 | |
3508 | |
3509 void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) { | |
3510 assert(!tmp->is_valid(), "don't need temporary"); | |
3511 __ call(RuntimeAddress(dest)); | |
3512 if (info != NULL) { | |
3513 add_call_info_here(info); | |
3514 } | |
3515 } | |
3516 | |
3517 | |
3518 void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) { | |
3519 assert(type == T_LONG, "only for volatile long fields"); | |
3520 | |
3521 if (info != NULL) { | |
3522 add_debug_info_for_null_check_here(info); | |
3523 } | |
3524 | |
3525 if (src->is_double_xmm()) { | |
3526 if (dest->is_double_cpu()) { | |
304 | 3527 #ifdef _LP64 |
3528 __ movdq(dest->as_register_lo(), src->as_xmm_double_reg()); | |
3529 #else | |
3530 __ movdl(dest->as_register_lo(), src->as_xmm_double_reg()); | |
0 | 3531 __ psrlq(src->as_xmm_double_reg(), 32); |
304 | 3532 __ movdl(dest->as_register_hi(), src->as_xmm_double_reg()); |
3533 #endif // _LP64 | |
0 | 3534 } else if (dest->is_double_stack()) { |
3535 __ movdbl(frame_map()->address_for_slot(dest->double_stack_ix()), src->as_xmm_double_reg()); | |
3536 } else if (dest->is_address()) { | |
3537 __ movdbl(as_Address(dest->as_address_ptr()), src->as_xmm_double_reg()); | |
3538 } else { | |
3539 ShouldNotReachHere(); | |
3540 } | |
3541 | |
3542 } else if (dest->is_double_xmm()) { | |
3543 if (src->is_double_stack()) { | |
3544 __ movdbl(dest->as_xmm_double_reg(), frame_map()->address_for_slot(src->double_stack_ix())); | |
3545 } else if (src->is_address()) { | |
3546 __ movdbl(dest->as_xmm_double_reg(), as_Address(src->as_address_ptr())); | |
3547 } else { | |
3548 ShouldNotReachHere(); | |
3549 } | |
3550 | |
3551 } else if (src->is_double_fpu()) { | |
3552 assert(src->fpu_regnrLo() == 0, "must be TOS"); | |
3553 if (dest->is_double_stack()) { | |
3554 __ fistp_d(frame_map()->address_for_slot(dest->double_stack_ix())); | |
3555 } else if (dest->is_address()) { | |
3556 __ fistp_d(as_Address(dest->as_address_ptr())); | |
3557 } else { | |
3558 ShouldNotReachHere(); | |
3559 } | |
3560 | |
3561 } else if (dest->is_double_fpu()) { | |
3562 assert(dest->fpu_regnrLo() == 0, "must be TOS"); | |
3563 if (src->is_double_stack()) { | |
3564 __ fild_d(frame_map()->address_for_slot(src->double_stack_ix())); | |
3565 } else if (src->is_address()) { | |
3566 __ fild_d(as_Address(src->as_address_ptr())); | |
3567 } else { | |
3568 ShouldNotReachHere(); | |
3569 } | |
3570 } else { | |
3571 ShouldNotReachHere(); | |
3572 } | |
3573 } | |
3574 | |
3575 | |
3576 void LIR_Assembler::membar() { | |
304 | 3577 // QQQ sparc TSO uses this, |
3578 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad)); | |
0 | 3579 } |
3580 | |
3581 void LIR_Assembler::membar_acquire() { | |
3582 // No x86 machines currently require load fences | |
3583 // __ load_fence(); | |
3584 } | |
3585 | |
3586 void LIR_Assembler::membar_release() { | |
3587 // No x86 machines currently require store fences | |
3588 // __ store_fence(); | |
3589 } | |
3590 | |
3591 void LIR_Assembler::get_thread(LIR_Opr result_reg) { | |
3592 assert(result_reg->is_register(), "check"); | |
304 | 3593 #ifdef _LP64 |
3594 // __ get_thread(result_reg->as_register_lo()); | |
3595 __ mov(result_reg->as_register(), r15_thread); | |
3596 #else | |
0 | 3597 __ get_thread(result_reg->as_register()); |
304 | 3598 #endif // _LP64 |
0 | 3599 } |
3600 | |
3601 | |
3602 void LIR_Assembler::peephole(LIR_List*) { | |
3603 // do nothing for now | |
3604 } | |
3605 | |
3606 | |
3607 #undef __ |