441 // Singleton class for RCX long register |
438 // Singleton class for RCX long register |
442 reg_class long_rcx_reg(RCX, RCX_H); |
439 reg_class long_rcx_reg(RCX, RCX_H); |
443 |
440 |
444 // Singleton class for RDX long register |
441 // Singleton class for RDX long register |
445 reg_class long_rdx_reg(RDX, RDX_H); |
442 reg_class long_rdx_reg(RDX, RDX_H); |
446 |
|
447 // Singleton class for R12 long register |
|
448 reg_class long_r12_reg(R12, R12_H); |
|
449 |
443 |
450 // Class for all int registers (except RSP) |
444 // Class for all int registers (except RSP) |
451 reg_class int_reg(RAX, |
445 reg_class int_reg(RAX, |
452 RDX, |
446 RDX, |
453 RBP, |
447 RBP, |
1840 #ifndef PRODUCT |
1834 #ifndef PRODUCT |
1841 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
1835 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
1842 { |
1836 { |
1843 if (UseCompressedOops) { |
1837 if (UseCompressedOops) { |
1844 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes()); |
1838 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes()); |
1845 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]"); |
1839 if (Universe::narrow_oop_shift() != 0) { |
|
1840 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]"); |
|
1841 } |
1846 st->print_cr("cmpq rax, rscratch1\t # Inline cache check"); |
1842 st->print_cr("cmpq rax, rscratch1\t # Inline cache check"); |
1847 } else { |
1843 } else { |
1848 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" |
1844 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" |
1849 "# Inline cache check", oopDesc::klass_offset_in_bytes()); |
1845 "# Inline cache check", oopDesc::klass_offset_in_bytes()); |
1850 } |
1846 } |
2573 %{ |
2573 %{ |
2574 Register Rrdi = as_Register(RDI_enc); // result register |
2574 Register Rrdi = as_Register(RDI_enc); // result register |
2575 Register Rrax = as_Register(RAX_enc); // super class |
2575 Register Rrax = as_Register(RAX_enc); // super class |
2576 Register Rrcx = as_Register(RCX_enc); // killed |
2576 Register Rrcx = as_Register(RCX_enc); // killed |
2577 Register Rrsi = as_Register(RSI_enc); // sub class |
2577 Register Rrsi = as_Register(RSI_enc); // sub class |
2578 Label hit, miss, cmiss; |
2578 Label miss; |
|
2579 const bool set_cond_codes = true; |
2579 |
2580 |
2580 MacroAssembler _masm(&cbuf); |
2581 MacroAssembler _masm(&cbuf); |
2581 // Compare super with sub directly, since super is not in its own SSA. |
2582 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, |
2582 // The compiler used to emit this test, but we fold it in here, |
2583 NULL, &miss, |
2583 // to allow platform-specific tweaking on sparc. |
2584 /*set_cond_codes:*/ true); |
2584 __ cmpptr(Rrax, Rrsi); |
|
2585 __ jcc(Assembler::equal, hit); |
|
2586 #ifndef PRODUCT |
|
2587 __ lea(Rrcx, ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); |
|
2588 __ incrementl(Address(Rrcx, 0)); |
|
2589 #endif //PRODUCT |
|
2590 __ movptr(Rrdi, Address(Rrsi, |
|
2591 sizeof(oopDesc) + |
|
2592 Klass::secondary_supers_offset_in_bytes())); |
|
2593 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); |
|
2594 __ addptr(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
|
2595 if (UseCompressedOops) { |
|
2596 __ encode_heap_oop(Rrax); |
|
2597 __ repne_scanl(); |
|
2598 __ jcc(Assembler::notEqual, cmiss); |
|
2599 __ decode_heap_oop(Rrax); |
|
2600 __ movptr(Address(Rrsi, |
|
2601 sizeof(oopDesc) + |
|
2602 Klass::secondary_super_cache_offset_in_bytes()), |
|
2603 Rrax); |
|
2604 __ jmp(hit); |
|
2605 __ bind(cmiss); |
|
2606 __ decode_heap_oop(Rrax); |
|
2607 __ jmp(miss); |
|
2608 } else { |
|
2609 __ repne_scan(); |
|
2610 __ jcc(Assembler::notEqual, miss); |
|
2611 __ movptr(Address(Rrsi, |
|
2612 sizeof(oopDesc) + |
|
2613 Klass::secondary_super_cache_offset_in_bytes()), |
|
2614 Rrax); |
|
2615 } |
|
2616 __ bind(hit); |
|
2617 if ($primary) { |
2585 if ($primary) { |
2618 __ xorptr(Rrdi, Rrdi); |
2586 __ xorptr(Rrdi, Rrdi); |
2619 } |
2587 } |
2620 __ bind(miss); |
2588 __ bind(miss); |
2621 %} |
2589 %} |
5287 scale($scale); |
5246 scale($scale); |
5288 disp($off); |
5247 disp($off); |
5289 %} |
5248 %} |
5290 %} |
5249 %} |
5291 |
5250 |
5292 // Indirect Narrow Oop Plus Offset Operand |
|
5293 operand indNarrowOopOffset(rRegN src, immL32 off) %{ |
|
5294 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5295 match(AddP (DecodeN src) off); |
|
5296 |
|
5297 op_cost(10); |
|
5298 format %{"[R12 + $src << 3 + $off] (compressed oop addressing)" %} |
|
5299 interface(MEMORY_INTER) %{ |
|
5300 base(0xc); // R12 |
|
5301 index($src); |
|
5302 scale(0x3); |
|
5303 disp($off); |
|
5304 %} |
|
5305 %} |
|
5306 |
|
5307 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand |
5251 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand |
5308 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) |
5252 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) |
5309 %{ |
5253 %{ |
5310 constraint(ALLOC_IN_RC(ptr_reg)); |
5254 constraint(ALLOC_IN_RC(ptr_reg)); |
5311 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); |
5255 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); |
5318 index($idx); |
5262 index($idx); |
5319 scale($scale); |
5263 scale($scale); |
5320 disp($off); |
5264 disp($off); |
5321 %} |
5265 %} |
5322 %} |
5266 %} |
|
5267 |
|
5268 // Indirect Narrow Oop Plus Offset Operand |
|
5269 // Note: x86 architecture doesn't support "scale * index + offset" without a base |
|
5270 // we can't free r12 even with Universe::narrow_oop_base() == NULL. |
|
5271 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ |
|
5272 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); |
|
5273 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5274 match(AddP (DecodeN reg) off); |
|
5275 |
|
5276 op_cost(10); |
|
5277 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} |
|
5278 interface(MEMORY_INTER) %{ |
|
5279 base(0xc); // R12 |
|
5280 index($reg); |
|
5281 scale(0x3); |
|
5282 disp($off); |
|
5283 %} |
|
5284 %} |
|
5285 |
|
5286 // Indirect Memory Operand |
|
5287 operand indirectNarrow(rRegN reg) |
|
5288 %{ |
|
5289 predicate(Universe::narrow_oop_shift() == 0); |
|
5290 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5291 match(DecodeN reg); |
|
5292 |
|
5293 format %{ "[$reg]" %} |
|
5294 interface(MEMORY_INTER) %{ |
|
5295 base($reg); |
|
5296 index(0x4); |
|
5297 scale(0x0); |
|
5298 disp(0x0); |
|
5299 %} |
|
5300 %} |
|
5301 |
|
5302 // Indirect Memory Plus Short Offset Operand |
|
5303 operand indOffset8Narrow(rRegN reg, immL8 off) |
|
5304 %{ |
|
5305 predicate(Universe::narrow_oop_shift() == 0); |
|
5306 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5307 match(AddP (DecodeN reg) off); |
|
5308 |
|
5309 format %{ "[$reg + $off (8-bit)]" %} |
|
5310 interface(MEMORY_INTER) %{ |
|
5311 base($reg); |
|
5312 index(0x4); |
|
5313 scale(0x0); |
|
5314 disp($off); |
|
5315 %} |
|
5316 %} |
|
5317 |
|
5318 // Indirect Memory Plus Long Offset Operand |
|
5319 operand indOffset32Narrow(rRegN reg, immL32 off) |
|
5320 %{ |
|
5321 predicate(Universe::narrow_oop_shift() == 0); |
|
5322 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5323 match(AddP (DecodeN reg) off); |
|
5324 |
|
5325 format %{ "[$reg + $off (32-bit)]" %} |
|
5326 interface(MEMORY_INTER) %{ |
|
5327 base($reg); |
|
5328 index(0x4); |
|
5329 scale(0x0); |
|
5330 disp($off); |
|
5331 %} |
|
5332 %} |
|
5333 |
|
5334 // Indirect Memory Plus Index Register Plus Offset Operand |
|
5335 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) |
|
5336 %{ |
|
5337 predicate(Universe::narrow_oop_shift() == 0); |
|
5338 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5339 match(AddP (AddP (DecodeN reg) lreg) off); |
|
5340 |
|
5341 op_cost(10); |
|
5342 format %{"[$reg + $off + $lreg]" %} |
|
5343 interface(MEMORY_INTER) %{ |
|
5344 base($reg); |
|
5345 index($lreg); |
|
5346 scale(0x0); |
|
5347 disp($off); |
|
5348 %} |
|
5349 %} |
|
5350 |
|
5351 // Indirect Memory Plus Index Register Plus Offset Operand |
|
5352 operand indIndexNarrow(rRegN reg, rRegL lreg) |
|
5353 %{ |
|
5354 predicate(Universe::narrow_oop_shift() == 0); |
|
5355 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5356 match(AddP (DecodeN reg) lreg); |
|
5357 |
|
5358 op_cost(10); |
|
5359 format %{"[$reg + $lreg]" %} |
|
5360 interface(MEMORY_INTER) %{ |
|
5361 base($reg); |
|
5362 index($lreg); |
|
5363 scale(0x0); |
|
5364 disp(0x0); |
|
5365 %} |
|
5366 %} |
|
5367 |
|
5368 // Indirect Memory Times Scale Plus Index Register |
|
5369 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) |
|
5370 %{ |
|
5371 predicate(Universe::narrow_oop_shift() == 0); |
|
5372 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5373 match(AddP (DecodeN reg) (LShiftL lreg scale)); |
|
5374 |
|
5375 op_cost(10); |
|
5376 format %{"[$reg + $lreg << $scale]" %} |
|
5377 interface(MEMORY_INTER) %{ |
|
5378 base($reg); |
|
5379 index($lreg); |
|
5380 scale($scale); |
|
5381 disp(0x0); |
|
5382 %} |
|
5383 %} |
|
5384 |
|
5385 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand |
|
5386 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) |
|
5387 %{ |
|
5388 predicate(Universe::narrow_oop_shift() == 0); |
|
5389 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5390 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); |
|
5391 |
|
5392 op_cost(10); |
|
5393 format %{"[$reg + $off + $lreg << $scale]" %} |
|
5394 interface(MEMORY_INTER) %{ |
|
5395 base($reg); |
|
5396 index($lreg); |
|
5397 scale($scale); |
|
5398 disp($off); |
|
5399 %} |
|
5400 %} |
|
5401 |
|
5402 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand |
|
5403 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) |
|
5404 %{ |
|
5405 constraint(ALLOC_IN_RC(ptr_reg)); |
|
5406 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); |
|
5407 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); |
|
5408 |
|
5409 op_cost(10); |
|
5410 format %{"[$reg + $off + $idx << $scale]" %} |
|
5411 interface(MEMORY_INTER) %{ |
|
5412 base($reg); |
|
5413 index($idx); |
|
5414 scale($scale); |
|
5415 disp($off); |
|
5416 %} |
|
5417 %} |
|
5418 |
5323 |
5419 |
5324 //----------Special Memory Operands-------------------------------------------- |
5420 //----------Special Memory Operands-------------------------------------------- |
5325 // Stack Slot Operand - This operand is used for loading and storing temporary |
5421 // Stack Slot Operand - This operand is used for loading and storing temporary |
5326 // values on the stack where a match requires a value to |
5422 // values on the stack where a match requires a value to |
5327 // flow through memory. |
5423 // flow through memory. |
5486 // multiple operand types with the same basic encoding and format. The classic |
5582 // multiple operand types with the same basic encoding and format. The classic |
5487 // case of this is memory operands. |
5583 // case of this is memory operands. |
5488 |
5584 |
5489 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, |
5585 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, |
5490 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, |
5586 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, |
5491 indNarrowOopOffset); |
5587 indCompressedOopOffset, |
|
5588 indirectNarrow, indOffset8Narrow, indOffset32Narrow, |
|
5589 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, |
|
5590 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); |
5492 |
5591 |
5493 //----------PIPELINE----------------------------------------------------------- |
5592 //----------PIPELINE----------------------------------------------------------- |
5494 // Rules which define the behavior of the target architectures pipeline. |
5593 // Rules which define the behavior of the target architectures pipeline. |
5495 pipeline %{ |
5594 pipeline %{ |
5496 |
5595 |
6416 opcode(0x8D); |
6511 opcode(0x8D); |
6417 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
6512 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
6418 ins_pipe(ialu_reg_reg_fat); |
6513 ins_pipe(ialu_reg_reg_fat); |
6419 %} |
6514 %} |
6420 |
6515 |
|
6516 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) |
|
6517 %{ |
|
6518 match(Set dst mem); |
|
6519 |
|
6520 ins_cost(110); |
|
6521 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} |
|
6522 opcode(0x8D); |
|
6523 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6524 ins_pipe(ialu_reg_reg_fat); |
|
6525 %} |
|
6526 |
|
6527 // Load Effective Address which uses Narrow (32-bits) oop |
|
6528 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) |
|
6529 %{ |
|
6530 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); |
|
6531 match(Set dst mem); |
|
6532 |
|
6533 ins_cost(110); |
|
6534 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} |
|
6535 opcode(0x8D); |
|
6536 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6537 ins_pipe(ialu_reg_reg_fat); |
|
6538 %} |
|
6539 |
|
6540 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) |
|
6541 %{ |
|
6542 predicate(Universe::narrow_oop_shift() == 0); |
|
6543 match(Set dst mem); |
|
6544 |
|
6545 ins_cost(110); // XXX |
|
6546 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} |
|
6547 opcode(0x8D); |
|
6548 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6549 ins_pipe(ialu_reg_reg_fat); |
|
6550 %} |
|
6551 |
|
6552 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) |
|
6553 %{ |
|
6554 predicate(Universe::narrow_oop_shift() == 0); |
|
6555 match(Set dst mem); |
|
6556 |
|
6557 ins_cost(110); |
|
6558 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} |
|
6559 opcode(0x8D); |
|
6560 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6561 ins_pipe(ialu_reg_reg_fat); |
|
6562 %} |
|
6563 |
|
6564 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) |
|
6565 %{ |
|
6566 predicate(Universe::narrow_oop_shift() == 0); |
|
6567 match(Set dst mem); |
|
6568 |
|
6569 ins_cost(110); |
|
6570 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} |
|
6571 opcode(0x8D); |
|
6572 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6573 ins_pipe(ialu_reg_reg_fat); |
|
6574 %} |
|
6575 |
|
6576 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) |
|
6577 %{ |
|
6578 predicate(Universe::narrow_oop_shift() == 0); |
|
6579 match(Set dst mem); |
|
6580 |
|
6581 ins_cost(110); |
|
6582 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} |
|
6583 opcode(0x8D); |
|
6584 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6585 ins_pipe(ialu_reg_reg_fat); |
|
6586 %} |
|
6587 |
|
6588 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) |
|
6589 %{ |
|
6590 predicate(Universe::narrow_oop_shift() == 0); |
|
6591 match(Set dst mem); |
|
6592 |
|
6593 ins_cost(110); |
|
6594 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} |
|
6595 opcode(0x8D); |
|
6596 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6597 ins_pipe(ialu_reg_reg_fat); |
|
6598 %} |
|
6599 |
|
6600 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) |
|
6601 %{ |
|
6602 predicate(Universe::narrow_oop_shift() == 0); |
|
6603 match(Set dst mem); |
|
6604 |
|
6605 ins_cost(110); |
|
6606 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} |
|
6607 opcode(0x8D); |
|
6608 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
|
6609 ins_pipe(ialu_reg_reg_fat); |
|
6610 %} |
|
6611 |
6421 instruct loadConI(rRegI dst, immI src) |
6612 instruct loadConI(rRegI dst, immI src) |
6422 %{ |
6613 %{ |
6423 match(Set dst src); |
6614 match(Set dst src); |
6424 |
6615 |
6425 format %{ "movl $dst, $src\t# int" %} |
6616 format %{ "movl $dst, $src\t# int" %} |
6792 opcode(0x89); |
6981 opcode(0x89); |
6793 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); |
6982 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); |
6794 ins_pipe(ialu_mem_reg); |
6983 ins_pipe(ialu_mem_reg); |
6795 %} |
6984 %} |
6796 |
6985 |
|
6986 instruct storeImmP0(memory mem, immP0 zero) |
|
6987 %{ |
|
6988 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
6989 match(Set mem (StoreP mem zero)); |
|
6990 |
|
6991 ins_cost(125); // XXX |
|
6992 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} |
|
6993 ins_encode %{ |
|
6994 __ movq($mem$$Address, r12); |
|
6995 %} |
|
6996 ins_pipe(ialu_mem_reg); |
|
6997 %} |
|
6998 |
6797 // Store NULL Pointer, mark word, or other simple pointer constant. |
6999 // Store NULL Pointer, mark word, or other simple pointer constant. |
6798 instruct storeImmP(memory mem, immP31 src) |
7000 instruct storeImmP(memory mem, immP31 src) |
6799 %{ |
7001 %{ |
6800 match(Set mem (StoreP mem src)); |
7002 match(Set mem (StoreP mem src)); |
6801 |
7003 |
6802 ins_cost(125); // XXX |
7004 ins_cost(150); // XXX |
6803 format %{ "movq $mem, $src\t# ptr" %} |
7005 format %{ "movq $mem, $src\t# ptr" %} |
6804 opcode(0xC7); /* C7 /0 */ |
7006 opcode(0xC7); /* C7 /0 */ |
6805 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
7007 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
6806 ins_pipe(ialu_mem_imm); |
7008 ins_pipe(ialu_mem_imm); |
6807 %} |
7009 %} |
6812 match(Set mem (StoreN mem src)); |
7014 match(Set mem (StoreN mem src)); |
6813 |
7015 |
6814 ins_cost(125); // XXX |
7016 ins_cost(125); // XXX |
6815 format %{ "movl $mem, $src\t# compressed ptr" %} |
7017 format %{ "movl $mem, $src\t# compressed ptr" %} |
6816 ins_encode %{ |
7018 ins_encode %{ |
6817 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); |
7019 __ movl($mem$$Address, $src$$Register); |
6818 Register src = as_Register($src$$reg); |
|
6819 __ movl(addr, src); |
|
6820 %} |
7020 %} |
6821 ins_pipe(ialu_mem_reg); |
7021 ins_pipe(ialu_mem_reg); |
6822 %} |
7022 %} |
6823 |
7023 |
|
7024 instruct storeImmN0(memory mem, immN0 zero) |
|
7025 %{ |
|
7026 predicate(Universe::narrow_oop_base() == NULL); |
|
7027 match(Set mem (StoreN mem zero)); |
|
7028 |
|
7029 ins_cost(125); // XXX |
|
7030 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} |
|
7031 ins_encode %{ |
|
7032 __ movl($mem$$Address, r12); |
|
7033 %} |
|
7034 ins_pipe(ialu_mem_reg); |
|
7035 %} |
|
7036 |
|
7037 instruct storeImmN(memory mem, immN src) |
|
7038 %{ |
|
7039 match(Set mem (StoreN mem src)); |
|
7040 |
|
7041 ins_cost(150); // XXX |
|
7042 format %{ "movl $mem, $src\t# compressed ptr" %} |
|
7043 ins_encode %{ |
|
7044 address con = (address)$src$$constant; |
|
7045 if (con == NULL) { |
|
7046 __ movl($mem$$Address, (int32_t)0); |
|
7047 } else { |
|
7048 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); |
|
7049 } |
|
7050 %} |
|
7051 ins_pipe(ialu_mem_imm); |
|
7052 %} |
|
7053 |
6824 // Store Integer Immediate |
7054 // Store Integer Immediate |
|
7055 instruct storeImmI0(memory mem, immI0 zero) |
|
7056 %{ |
|
7057 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7058 match(Set mem (StoreI mem zero)); |
|
7059 |
|
7060 ins_cost(125); // XXX |
|
7061 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} |
|
7062 ins_encode %{ |
|
7063 __ movl($mem$$Address, r12); |
|
7064 %} |
|
7065 ins_pipe(ialu_mem_reg); |
|
7066 %} |
|
7067 |
6825 instruct storeImmI(memory mem, immI src) |
7068 instruct storeImmI(memory mem, immI src) |
6826 %{ |
7069 %{ |
6827 match(Set mem (StoreI mem src)); |
7070 match(Set mem (StoreI mem src)); |
6828 |
7071 |
6829 ins_cost(150); |
7072 ins_cost(150); |
6832 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
7075 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
6833 ins_pipe(ialu_mem_imm); |
7076 ins_pipe(ialu_mem_imm); |
6834 %} |
7077 %} |
6835 |
7078 |
6836 // Store Long Immediate |
7079 // Store Long Immediate |
|
7080 instruct storeImmL0(memory mem, immL0 zero) |
|
7081 %{ |
|
7082 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7083 match(Set mem (StoreL mem zero)); |
|
7084 |
|
7085 ins_cost(125); // XXX |
|
7086 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} |
|
7087 ins_encode %{ |
|
7088 __ movq($mem$$Address, r12); |
|
7089 %} |
|
7090 ins_pipe(ialu_mem_reg); |
|
7091 %} |
|
7092 |
6837 instruct storeImmL(memory mem, immL32 src) |
7093 instruct storeImmL(memory mem, immL32 src) |
6838 %{ |
7094 %{ |
6839 match(Set mem (StoreL mem src)); |
7095 match(Set mem (StoreL mem src)); |
6840 |
7096 |
6841 ins_cost(150); |
7097 ins_cost(150); |
6844 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
7100 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
6845 ins_pipe(ialu_mem_imm); |
7101 ins_pipe(ialu_mem_imm); |
6846 %} |
7102 %} |
6847 |
7103 |
6848 // Store Short/Char Immediate |
7104 // Store Short/Char Immediate |
|
7105 instruct storeImmC0(memory mem, immI0 zero) |
|
7106 %{ |
|
7107 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7108 match(Set mem (StoreC mem zero)); |
|
7109 |
|
7110 ins_cost(125); // XXX |
|
7111 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} |
|
7112 ins_encode %{ |
|
7113 __ movw($mem$$Address, r12); |
|
7114 %} |
|
7115 ins_pipe(ialu_mem_reg); |
|
7116 %} |
|
7117 |
6849 instruct storeImmI16(memory mem, immI16 src) |
7118 instruct storeImmI16(memory mem, immI16 src) |
6850 %{ |
7119 %{ |
6851 predicate(UseStoreImmI16); |
7120 predicate(UseStoreImmI16); |
6852 match(Set mem (StoreC mem src)); |
7121 match(Set mem (StoreC mem src)); |
6853 |
7122 |
6857 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); |
7126 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); |
6858 ins_pipe(ialu_mem_imm); |
7127 ins_pipe(ialu_mem_imm); |
6859 %} |
7128 %} |
6860 |
7129 |
6861 // Store Byte Immediate |
7130 // Store Byte Immediate |
|
7131 instruct storeImmB0(memory mem, immI0 zero) |
|
7132 %{ |
|
7133 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7134 match(Set mem (StoreB mem zero)); |
|
7135 |
|
7136 ins_cost(125); // XXX |
|
7137 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} |
|
7138 ins_encode %{ |
|
7139 __ movb($mem$$Address, r12); |
|
7140 %} |
|
7141 ins_pipe(ialu_mem_reg); |
|
7142 %} |
|
7143 |
6862 instruct storeImmB(memory mem, immI8 src) |
7144 instruct storeImmB(memory mem, immI8 src) |
6863 %{ |
7145 %{ |
6864 match(Set mem (StoreB mem src)); |
7146 match(Set mem (StoreB mem src)); |
6865 |
7147 |
6866 ins_cost(150); // XXX |
7148 ins_cost(150); // XXX |
6896 ins_encode( movq_st(mem, src)); |
7178 ins_encode( movq_st(mem, src)); |
6897 ins_pipe( pipe_slow ); |
7179 ins_pipe( pipe_slow ); |
6898 %} |
7180 %} |
6899 |
7181 |
6900 // Store CMS card-mark Immediate |
7182 // Store CMS card-mark Immediate |
|
7183 instruct storeImmCM0_reg(memory mem, immI0 zero) |
|
7184 %{ |
|
7185 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7186 match(Set mem (StoreCM mem zero)); |
|
7187 |
|
7188 ins_cost(125); // XXX |
|
7189 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} |
|
7190 ins_encode %{ |
|
7191 __ movb($mem$$Address, r12); |
|
7192 %} |
|
7193 ins_pipe(ialu_mem_reg); |
|
7194 %} |
|
7195 |
6901 instruct storeImmCM0(memory mem, immI0 src) |
7196 instruct storeImmCM0(memory mem, immI0 src) |
6902 %{ |
7197 %{ |
6903 match(Set mem (StoreCM mem src)); |
7198 match(Set mem (StoreCM mem src)); |
6904 |
7199 |
6905 ins_cost(150); // XXX |
7200 ins_cost(150); // XXX |
6929 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); |
7224 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); |
6930 ins_pipe(pipe_slow); // XXX |
7225 ins_pipe(pipe_slow); // XXX |
6931 %} |
7226 %} |
6932 |
7227 |
6933 // Store immediate Float value (it is faster than store from XMM register) |
7228 // Store immediate Float value (it is faster than store from XMM register) |
|
7229 instruct storeF0(memory mem, immF0 zero) |
|
7230 %{ |
|
7231 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7232 match(Set mem (StoreF mem zero)); |
|
7233 |
|
7234 ins_cost(25); // XXX |
|
7235 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} |
|
7236 ins_encode %{ |
|
7237 __ movl($mem$$Address, r12); |
|
7238 %} |
|
7239 ins_pipe(ialu_mem_reg); |
|
7240 %} |
|
7241 |
6934 instruct storeF_imm(memory mem, immF src) |
7242 instruct storeF_imm(memory mem, immF src) |
6935 %{ |
7243 %{ |
6936 match(Set mem (StoreF mem src)); |
7244 match(Set mem (StoreF mem src)); |
6937 |
7245 |
6938 ins_cost(50); |
7246 ins_cost(50); |
6955 %} |
7263 %} |
6956 |
7264 |
6957 // Store immediate double 0.0 (it is faster than store from XMM register) |
7265 // Store immediate double 0.0 (it is faster than store from XMM register) |
6958 instruct storeD0_imm(memory mem, immD0 src) |
7266 instruct storeD0_imm(memory mem, immD0 src) |
6959 %{ |
7267 %{ |
|
7268 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); |
6960 match(Set mem (StoreD mem src)); |
7269 match(Set mem (StoreD mem src)); |
6961 |
7270 |
6962 ins_cost(50); |
7271 ins_cost(50); |
6963 format %{ "movq $mem, $src\t# double 0." %} |
7272 format %{ "movq $mem, $src\t# double 0." %} |
6964 opcode(0xC7); /* C7 /0 */ |
7273 opcode(0xC7); /* C7 /0 */ |
6965 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); |
7274 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); |
6966 ins_pipe(ialu_mem_imm); |
7275 ins_pipe(ialu_mem_imm); |
6967 %} |
7276 %} |
6968 |
7277 |
|
7278 instruct storeD0(memory mem, immD0 zero) |
|
7279 %{ |
|
7280 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
7281 match(Set mem (StoreD mem zero)); |
|
7282 |
|
7283 ins_cost(25); // XXX |
|
7284 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} |
|
7285 ins_encode %{ |
|
7286 __ movq($mem$$Address, r12); |
|
7287 %} |
|
7288 ins_pipe(ialu_mem_reg); |
|
7289 %} |
|
7290 |
6969 instruct storeSSI(stackSlotI dst, rRegI src) |
7291 instruct storeSSI(stackSlotI dst, rRegI src) |
6970 %{ |
7292 %{ |
6971 match(Set dst src); |
7293 match(Set dst src); |
6972 |
7294 |
6973 ins_cost(100); |
7295 ins_cost(100); |
7074 format %{ "movq_bswap $dst, $src" %} |
7396 format %{ "movq_bswap $dst, $src" %} |
7075 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */ |
7397 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */ |
7076 ins_encode( REX_reg_wide(src), OpcP, opc2_reg(src), REX_reg_mem_wide(src, dst), OpcT, reg_mem(src, dst) ); |
7398 ins_encode( REX_reg_wide(src), OpcP, opc2_reg(src), REX_reg_mem_wide(src, dst), OpcT, reg_mem(src, dst) ); |
7077 ins_pipe( ialu_mem_reg ); |
7399 ins_pipe( ialu_mem_reg ); |
7078 %} |
7400 %} |
|
7401 |
|
7402 |
|
7403 //---------- Population Count Instructions ------------------------------------- |
|
7404 |
|
7405 instruct popCountI(rRegI dst, rRegI src) %{ |
|
7406 predicate(UsePopCountInstruction); |
|
7407 match(Set dst (PopCountI src)); |
|
7408 |
|
7409 format %{ "popcnt $dst, $src" %} |
|
7410 ins_encode %{ |
|
7411 __ popcntl($dst$$Register, $src$$Register); |
|
7412 %} |
|
7413 ins_pipe(ialu_reg); |
|
7414 %} |
|
7415 |
|
7416 instruct popCountI_mem(rRegI dst, memory mem) %{ |
|
7417 predicate(UsePopCountInstruction); |
|
7418 match(Set dst (PopCountI (LoadI mem))); |
|
7419 |
|
7420 format %{ "popcnt $dst, $mem" %} |
|
7421 ins_encode %{ |
|
7422 __ popcntl($dst$$Register, $mem$$Address); |
|
7423 %} |
|
7424 ins_pipe(ialu_reg); |
|
7425 %} |
|
7426 |
|
7427 // Note: Long.bitCount(long) returns an int. |
|
7428 instruct popCountL(rRegI dst, rRegL src) %{ |
|
7429 predicate(UsePopCountInstruction); |
|
7430 match(Set dst (PopCountL src)); |
|
7431 |
|
7432 format %{ "popcnt $dst, $src" %} |
|
7433 ins_encode %{ |
|
7434 __ popcntq($dst$$Register, $src$$Register); |
|
7435 %} |
|
7436 ins_pipe(ialu_reg); |
|
7437 %} |
|
7438 |
|
7439 // Note: Long.bitCount(long) returns an int. |
|
7440 instruct popCountL_mem(rRegI dst, memory mem) %{ |
|
7441 predicate(UsePopCountInstruction); |
|
7442 match(Set dst (PopCountL (LoadL mem))); |
|
7443 |
|
7444 format %{ "popcnt $dst, $mem" %} |
|
7445 ins_encode %{ |
|
7446 __ popcntq($dst$$Register, $mem$$Address); |
|
7447 %} |
|
7448 ins_pipe(ialu_reg); |
|
7449 %} |
|
7450 |
7079 |
7451 |
7080 //----------MemBar Instructions----------------------------------------------- |
7452 //----------MemBar Instructions----------------------------------------------- |
7081 // Memory barrier flavors |
7453 // Memory barrier flavors |
7082 |
7454 |
7083 instruct membar_acquire() |
7455 instruct membar_acquire() |
7190 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); |
7562 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); |
7191 match(Set dst (EncodeP src)); |
7563 match(Set dst (EncodeP src)); |
7192 effect(KILL cr); |
7564 effect(KILL cr); |
7193 format %{ "encode_heap_oop_not_null $dst,$src" %} |
7565 format %{ "encode_heap_oop_not_null $dst,$src" %} |
7194 ins_encode %{ |
7566 ins_encode %{ |
7195 Register s = $src$$Register; |
7567 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); |
7196 Register d = $dst$$Register; |
|
7197 __ encode_heap_oop_not_null(d, s); |
|
7198 %} |
7568 %} |
7199 ins_pipe(ialu_reg_long); |
7569 ins_pipe(ialu_reg_long); |
7200 %} |
7570 %} |
7201 |
7571 |
7202 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ |
7572 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ |
11387 ins_pipe(ialu_cr_reg_imm); |
11761 ins_pipe(ialu_cr_reg_imm); |
11388 %} |
11762 %} |
11389 |
11763 |
11390 // This will generate a signed flags result. This should be OK since |
11764 // This will generate a signed flags result. This should be OK since |
11391 // any compare to a zero should be eq/neq. |
11765 // any compare to a zero should be eq/neq. |
11392 instruct testP_reg_mem(rFlagsReg cr, memory op, immP0 zero) |
11766 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) |
11393 %{ |
11767 %{ |
|
11768 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); |
11394 match(Set cr (CmpP (LoadP op) zero)); |
11769 match(Set cr (CmpP (LoadP op) zero)); |
11395 |
11770 |
11396 ins_cost(500); // XXX |
11771 ins_cost(500); // XXX |
11397 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} |
11772 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} |
11398 opcode(0xF7); /* Opcode F7 /0 */ |
11773 opcode(0xF7); /* Opcode F7 /0 */ |
11399 ins_encode(REX_mem_wide(op), |
11774 ins_encode(REX_mem_wide(op), |
11400 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); |
11775 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); |
11401 ins_pipe(ialu_cr_reg_imm); |
11776 ins_pipe(ialu_cr_reg_imm); |
11402 %} |
11777 %} |
11403 |
11778 |
|
11779 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) |
|
11780 %{ |
|
11781 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); |
|
11782 match(Set cr (CmpP (LoadP mem) zero)); |
|
11783 |
|
11784 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} |
|
11785 ins_encode %{ |
|
11786 __ cmpq(r12, $mem$$Address); |
|
11787 %} |
|
11788 ins_pipe(ialu_cr_reg_mem); |
|
11789 %} |
11404 |
11790 |
11405 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) |
11791 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) |
11406 %{ |
11792 %{ |
11407 match(Set cr (CmpN op1 op2)); |
11793 match(Set cr (CmpN op1 op2)); |
11408 |
11794 |
11409 format %{ "cmpl $op1, $op2\t# compressed ptr" %} |
11795 format %{ "cmpl $op1, $op2\t# compressed ptr" %} |
11410 ins_encode %{ __ cmpl(as_Register($op1$$reg), as_Register($op2$$reg)); %} |
11796 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} |
11411 ins_pipe(ialu_cr_reg_reg); |
11797 ins_pipe(ialu_cr_reg_reg); |
11412 %} |
11798 %} |
11413 |
11799 |
11414 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) |
11800 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) |
11415 %{ |
11801 %{ |
11416 match(Set cr (CmpN src (LoadN mem))); |
11802 match(Set cr (CmpN src (LoadN mem))); |
11417 |
11803 |
11418 ins_cost(500); // XXX |
11804 format %{ "cmpl $src, $mem\t# compressed ptr" %} |
11419 format %{ "cmpl $src, mem\t# compressed ptr" %} |
|
11420 ins_encode %{ |
11805 ins_encode %{ |
11421 Address adr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); |
11806 __ cmpl($src$$Register, $mem$$Address); |
11422 __ cmpl(as_Register($src$$reg), adr); |
11807 %} |
|
11808 ins_pipe(ialu_cr_reg_mem); |
|
11809 %} |
|
11810 |
|
11811 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ |
|
11812 match(Set cr (CmpN op1 op2)); |
|
11813 |
|
11814 format %{ "cmpl $op1, $op2\t# compressed ptr" %} |
|
11815 ins_encode %{ |
|
11816 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); |
|
11817 %} |
|
11818 ins_pipe(ialu_cr_reg_imm); |
|
11819 %} |
|
11820 |
|
11821 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) |
|
11822 %{ |
|
11823 match(Set cr (CmpN src (LoadN mem))); |
|
11824 |
|
11825 format %{ "cmpl $mem, $src\t# compressed ptr" %} |
|
11826 ins_encode %{ |
|
11827 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); |
11423 %} |
11828 %} |
11424 ins_pipe(ialu_cr_reg_mem); |
11829 ins_pipe(ialu_cr_reg_mem); |
11425 %} |
11830 %} |
11426 |
11831 |
11427 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ |
11832 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ |
11430 format %{ "testl $src, $src\t# compressed ptr" %} |
11835 format %{ "testl $src, $src\t# compressed ptr" %} |
11431 ins_encode %{ __ testl($src$$Register, $src$$Register); %} |
11836 ins_encode %{ __ testl($src$$Register, $src$$Register); %} |
11432 ins_pipe(ialu_cr_reg_imm); |
11837 ins_pipe(ialu_cr_reg_imm); |
11433 %} |
11838 %} |
11434 |
11839 |
11435 instruct testN_reg_mem(rFlagsReg cr, memory mem, immN0 zero) |
11840 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) |
11436 %{ |
11841 %{ |
|
11842 predicate(Universe::narrow_oop_base() != NULL); |
11437 match(Set cr (CmpN (LoadN mem) zero)); |
11843 match(Set cr (CmpN (LoadN mem) zero)); |
11438 |
11844 |
11439 ins_cost(500); // XXX |
11845 ins_cost(500); // XXX |
11440 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} |
11846 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} |
11441 ins_encode %{ |
11847 ins_encode %{ |
11442 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); |
11848 __ cmpl($mem$$Address, (int)0xFFFFFFFF); |
11443 __ cmpl(addr, (int)0xFFFFFFFF); |
11849 %} |
|
11850 ins_pipe(ialu_cr_reg_mem); |
|
11851 %} |
|
11852 |
|
11853 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) |
|
11854 %{ |
|
11855 predicate(Universe::narrow_oop_base() == NULL); |
|
11856 match(Set cr (CmpN (LoadN mem) zero)); |
|
11857 |
|
11858 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} |
|
11859 ins_encode %{ |
|
11860 __ cmpl(r12, $mem$$Address); |
11444 %} |
11861 %} |
11445 ins_pipe(ialu_cr_reg_mem); |
11862 ins_pipe(ialu_cr_reg_mem); |
11446 %} |
11863 %} |
11447 |
11864 |
11448 // Yanked all unsigned pointer compare operations. |
11865 // Yanked all unsigned pointer compare operations. |
11470 |
11887 |
11471 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) |
11888 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) |
11472 %{ |
11889 %{ |
11473 match(Set cr (CmpL op1 (LoadL op2))); |
11890 match(Set cr (CmpL op1 (LoadL op2))); |
11474 |
11891 |
11475 ins_cost(500); // XXX |
|
11476 format %{ "cmpq $op1, $op2" %} |
11892 format %{ "cmpq $op1, $op2" %} |
11477 opcode(0x3B); /* Opcode 3B /r */ |
11893 opcode(0x3B); /* Opcode 3B /r */ |
11478 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); |
11894 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); |
11479 ins_pipe(ialu_cr_reg_mem); |
11895 ins_pipe(ialu_cr_reg_mem); |
11480 %} |
11896 %} |
11731 %{ |
12147 %{ |
11732 match(Set result (PartialSubtypeCheck sub super)); |
12148 match(Set result (PartialSubtypeCheck sub super)); |
11733 effect(KILL rcx, KILL cr); |
12149 effect(KILL rcx, KILL cr); |
11734 |
12150 |
11735 ins_cost(1100); // slightly larger than the next version |
12151 ins_cost(1100); // slightly larger than the next version |
11736 format %{ "cmpq rax, rsi\n\t" |
12152 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" |
11737 "jeq,s hit\n\t" |
|
11738 "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" |
|
11739 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" |
12153 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" |
11740 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" |
12154 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" |
11741 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" |
12155 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" |
11742 "jne,s miss\t\t# Missed: rdi not-zero\n\t" |
12156 "jne,s miss\t\t# Missed: rdi not-zero\n\t" |
11743 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" |
12157 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" |
11744 "hit:\n\t" |
|
11745 "xorq $result, $result\t\t Hit: rdi zero\n\t" |
12158 "xorq $result, $result\t\t Hit: rdi zero\n\t" |
11746 "miss:\t" %} |
12159 "miss:\t" %} |
11747 |
12160 |
11748 opcode(0x1); // Force a XOR of RDI |
12161 opcode(0x1); // Force a XOR of RDI |
11749 ins_encode(enc_PartialSubtypeCheck()); |
12162 ins_encode(enc_PartialSubtypeCheck()); |
11754 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, |
12167 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, |
11755 immP0 zero, |
12168 immP0 zero, |
11756 rdi_RegP result) |
12169 rdi_RegP result) |
11757 %{ |
12170 %{ |
11758 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); |
12171 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); |
11759 predicate(!UseCompressedOops); // decoding oop kills condition codes |
|
11760 effect(KILL rcx, KILL result); |
12172 effect(KILL rcx, KILL result); |
11761 |
12173 |
11762 ins_cost(1000); |
12174 ins_cost(1000); |
11763 format %{ "cmpq rax, rsi\n\t" |
12175 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" |
11764 "jeq,s miss\t# Actually a hit; we are done.\n\t" |
|
11765 "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" |
|
11766 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" |
12176 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" |
11767 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" |
12177 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" |
11768 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" |
12178 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" |
11769 "jne,s miss\t\t# Missed: flags nz\n\t" |
12179 "jne,s miss\t\t# Missed: flags nz\n\t" |
11770 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" |
12180 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" |