Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.ad @ 647:bd441136a5ce
Merge
author | kvn |
---|---|
date | Thu, 19 Mar 2009 09:13:24 -0700 |
parents | 7bb995fbd3c0 c517646eef23 |
children | d0994e5bebce |
comparison
equal
deleted
inserted
replaced
640:ba50942c8138 | 647: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" |