src/cpu/x86/vm/x86_64.ad

changeset 1082
bd441136a5ce
parent 1063
7bb995fbd3c0
parent 1079
c517646eef23
child 1106
d0994e5bebce
equal deleted inserted replaced
1075:ba50942c8138 1082:bd441136a5ce
324 RBX, RBX_H, 324 RBX, RBX_H,
325 R8, R8_H, 325 R8, R8_H,
326 R9, R9_H, 326 R9, R9_H,
327 R10, R10_H, 327 R10, R10_H,
328 R11, R11_H, 328 R11, R11_H,
329 R12, R12_H,
330 R13, R13_H, 329 R13, R13_H,
331 R14, R14_H); 330 R14, R14_H);
332 331
333 reg_class ptr_no_rbp_reg(RDX, RDX_H, 332 reg_class ptr_no_rbp_reg(RDX, RDX_H,
334 RAX, RAX_H, 333 RAX, RAX_H,
338 RBX, RBX_H, 337 RBX, RBX_H,
339 R8, R8_H, 338 R8, R8_H,
340 R9, R9_H, 339 R9, R9_H,
341 R10, R10_H, 340 R10, R10_H,
342 R11, R11_H, 341 R11, R11_H,
343 R12, R12_H,
344 R13, R13_H, 342 R13, R13_H,
345 R14, R14_H); 343 R14, R14_H);
346 344
347 // Class for all pointer registers except RAX, RBX and RSP 345 // Class for all pointer registers except RAX, RBX and RSP
348 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 346 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
352 RCX, RCX_H, 350 RCX, RCX_H,
353 R8, R8_H, 351 R8, R8_H,
354 R9, R9_H, 352 R9, R9_H,
355 R10, R10_H, 353 R10, R10_H,
356 R11, R11_H, 354 R11, R11_H,
357 R12, R12_H,
358 R13, R13_H, 355 R13, R13_H,
359 R14, R14_H); 356 R14, R14_H);
360 357
361 // Singleton class for RAX pointer register 358 // Singleton class for RAX pointer register
362 reg_class ptr_rax_reg(RAX, RAX_H); 359 reg_class ptr_rax_reg(RAX, RAX_H);
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 }
1889 } 1885 }
1890 1886
1891 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1887 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1892 { 1888 {
1893 if (UseCompressedOops) { 1889 if (UseCompressedOops) {
1894 return OptoBreakpoint ? 19 : 20; 1890 if (Universe::narrow_oop_shift() == 0) {
1891 return OptoBreakpoint ? 15 : 16;
1892 } else {
1893 return OptoBreakpoint ? 19 : 20;
1894 }
1895 } else { 1895 } else {
1896 return OptoBreakpoint ? 11 : 12; 1896 return OptoBreakpoint ? 11 : 12;
1897 } 1897 }
1898 } 1898 }
1899 1899
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 %}
4904 4872
4905 format %{ %} 4873 format %{ %}
4906 interface(REG_INTER); 4874 interface(REG_INTER);
4907 %} 4875 %}
4908 4876
4909
4910 operand r12RegL() %{
4911 constraint(ALLOC_IN_RC(long_r12_reg));
4912 match(RegL);
4913
4914 format %{ %}
4915 interface(REG_INTER);
4916 %}
4917
4918 operand rRegN() %{ 4877 operand rRegN() %{
4919 constraint(ALLOC_IN_RC(int_reg)); 4878 constraint(ALLOC_IN_RC(int_reg));
4920 match(RegN); 4879 match(RegN);
4921 4880
4922 format %{ %} 4881 format %{ %}
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
6232 match(Set dst (LoadN mem)); 6331 match(Set dst (LoadN mem));
6233 6332
6234 ins_cost(125); // XXX 6333 ins_cost(125); // XXX
6235 format %{ "movl $dst, $mem\t# compressed ptr" %} 6334 format %{ "movl $dst, $mem\t# compressed ptr" %}
6236 ins_encode %{ 6335 ins_encode %{
6237 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6336 __ movl($dst$$Register, $mem$$Address);
6238 Register dst = as_Register($dst$$reg);
6239 __ movl(dst, addr);
6240 %} 6337 %}
6241 ins_pipe(ialu_reg_mem); // XXX 6338 ins_pipe(ialu_reg_mem); // XXX
6242 %} 6339 %}
6243 6340
6244 6341
6260 match(Set dst (LoadNKlass mem)); 6357 match(Set dst (LoadNKlass mem));
6261 6358
6262 ins_cost(125); // XXX 6359 ins_cost(125); // XXX
6263 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 6360 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
6264 ins_encode %{ 6361 ins_encode %{
6265 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6362 __ movl($dst$$Register, $mem$$Address);
6266 Register dst = as_Register($dst$$reg);
6267 __ movl(dst, addr);
6268 %} 6363 %}
6269 ins_pipe(ialu_reg_mem); // XXX 6364 ins_pipe(ialu_reg_mem); // XXX
6270 %} 6365 %}
6271 6366
6272 // Load Float 6367 // Load Float
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" %}
6526 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 6717 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6527 match(Set dst src); 6718 match(Set dst src);
6528 effect(KILL cr); 6719 effect(KILL cr);
6529 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 6720 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
6530 ins_encode %{ 6721 ins_encode %{
6531 Register dst = $dst$$Register; 6722 __ xorq($dst$$Register, $dst$$Register);
6532 __ xorq(dst, dst);
6533 %} 6723 %}
6534 ins_pipe(ialu_reg); 6724 ins_pipe(ialu_reg);
6535 %} 6725 %}
6536 6726
6537 instruct loadConN(rRegN dst, immN src) %{ 6727 instruct loadConN(rRegN dst, immN src) %{
6539 6729
6540 ins_cost(125); 6730 ins_cost(125);
6541 format %{ "movl $dst, $src\t# compressed ptr" %} 6731 format %{ "movl $dst, $src\t# compressed ptr" %}
6542 ins_encode %{ 6732 ins_encode %{
6543 address con = (address)$src$$constant; 6733 address con = (address)$src$$constant;
6544 Register dst = $dst$$Register;
6545 if (con == NULL) { 6734 if (con == NULL) {
6546 ShouldNotReachHere(); 6735 ShouldNotReachHere();
6547 } else { 6736 } else {
6548 __ set_narrow_oop(dst, (jobject)$src$$constant); 6737 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
6549 } 6738 }
6550 %} 6739 %}
6551 ins_pipe(ialu_reg_fat); // XXX 6740 ins_pipe(ialu_reg_fat); // XXX
6552 %} 6741 %}
6553 6742
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) %{
7222 match(Set dst (DecodeN src)); 7592 match(Set dst (DecodeN src));
7223 format %{ "decode_heap_oop_not_null $dst,$src" %} 7593 format %{ "decode_heap_oop_not_null $dst,$src" %}
7224 ins_encode %{ 7594 ins_encode %{
7225 Register s = $src$$Register; 7595 Register s = $src$$Register;
7226 Register d = $dst$$Register; 7596 Register d = $dst$$Register;
7227 __ decode_heap_oop_not_null(d, s); 7597 if (s != d) {
7598 __ decode_heap_oop_not_null(d, s);
7599 } else {
7600 __ decode_heap_oop_not_null(d);
7601 }
7228 %} 7602 %}
7229 ins_pipe(ialu_reg_long); 7603 ins_pipe(ialu_reg_long);
7230 %} 7604 %}
7231 7605
7232 7606
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"

mercurial