Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.ad @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | 3d62cb85208d |
children | b130b98db9cf |
comparison
equal
deleted
inserted
replaced
110:a49a647afe9a | 113:ba764ed4b6f2 |
---|---|
310 RBX, RBX_H, | 310 RBX, RBX_H, |
311 R8, R8_H, | 311 R8, R8_H, |
312 R9, R9_H, | 312 R9, R9_H, |
313 R10, R10_H, | 313 R10, R10_H, |
314 R11, R11_H, | 314 R11, R11_H, |
315 R12, R12_H, | |
316 R13, R13_H, | 315 R13, R13_H, |
317 R14, R14_H); | 316 R14, R14_H); |
318 | 317 |
319 // Class for all pointer registers except RAX and RSP | 318 // Class for all pointer registers except RAX and RSP |
320 reg_class ptr_no_rax_reg(RDX, RDX_H, | 319 reg_class ptr_no_rax_reg(RDX, RDX_H, |
390 RBX, RBX_H, | 389 RBX, RBX_H, |
391 R8, R8_H, | 390 R8, R8_H, |
392 R9, R9_H, | 391 R9, R9_H, |
393 R10, R10_H, | 392 R10, R10_H, |
394 R11, R11_H, | 393 R11, R11_H, |
395 R12, R12_H, | |
396 R13, R13_H, | 394 R13, R13_H, |
397 R14, R14_H); | 395 R14, R14_H); |
398 | 396 |
399 // Class for all long registers except RAX, RDX (and RSP) | 397 // Class for all long registers except RAX, RDX (and RSP) |
400 reg_class long_no_rax_rdx_reg(RBP, RBP_H, | 398 reg_class long_no_rax_rdx_reg(RBP, RBP_H, |
404 RBX, RBX_H, | 402 RBX, RBX_H, |
405 R8, R8_H, | 403 R8, R8_H, |
406 R9, R9_H, | 404 R9, R9_H, |
407 R10, R10_H, | 405 R10, R10_H, |
408 R11, R11_H, | 406 R11, R11_H, |
409 R12, R12_H, | |
410 R13, R13_H, | 407 R13, R13_H, |
411 R14, R14_H); | 408 R14, R14_H); |
412 | 409 |
413 // Class for all long registers except RCX (and RSP) | 410 // Class for all long registers except RCX (and RSP) |
414 reg_class long_no_rcx_reg(RBP, RBP_H, | 411 reg_class long_no_rcx_reg(RBP, RBP_H, |
419 RBX, RBX_H, | 416 RBX, RBX_H, |
420 R8, R8_H, | 417 R8, R8_H, |
421 R9, R9_H, | 418 R9, R9_H, |
422 R10, R10_H, | 419 R10, R10_H, |
423 R11, R11_H, | 420 R11, R11_H, |
424 R12, R12_H, | |
425 R13, R13_H, | 421 R13, R13_H, |
426 R14, R14_H); | 422 R14, R14_H); |
427 | 423 |
428 // Class for all long registers except RAX (and RSP) | 424 // Class for all long registers except RAX (and RSP) |
429 reg_class long_no_rax_reg(RBP, RBP_H, | 425 reg_class long_no_rax_reg(RBP, RBP_H, |
434 RBX, RBX_H, | 430 RBX, RBX_H, |
435 R8, R8_H, | 431 R8, R8_H, |
436 R9, R9_H, | 432 R9, R9_H, |
437 R10, R10_H, | 433 R10, R10_H, |
438 R11, R11_H, | 434 R11, R11_H, |
439 R12, R12_H, | |
440 R13, R13_H, | 435 R13, R13_H, |
441 R14, R14_H); | 436 R14, R14_H); |
442 | 437 |
443 // Singleton class for RAX long register | 438 // Singleton class for RAX long register |
444 reg_class long_rax_reg(RAX, RAX_H); | 439 reg_class long_rax_reg(RAX, RAX_H); |
446 // Singleton class for RCX long register | 441 // Singleton class for RCX long register |
447 reg_class long_rcx_reg(RCX, RCX_H); | 442 reg_class long_rcx_reg(RCX, RCX_H); |
448 | 443 |
449 // Singleton class for RDX long register | 444 // Singleton class for RDX long register |
450 reg_class long_rdx_reg(RDX, RDX_H); | 445 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); | |
451 | 449 |
452 // Class for all int registers (except RSP) | 450 // Class for all int registers (except RSP) |
453 reg_class int_reg(RAX, | 451 reg_class int_reg(RAX, |
454 RDX, | 452 RDX, |
455 RBP, | 453 RBP, |
459 RBX, | 457 RBX, |
460 R8, | 458 R8, |
461 R9, | 459 R9, |
462 R10, | 460 R10, |
463 R11, | 461 R11, |
464 R12, | |
465 R13, | 462 R13, |
466 R14); | 463 R14); |
467 | 464 |
468 // Class for all int registers except RCX (and RSP) | 465 // Class for all int registers except RCX (and RSP) |
469 reg_class int_no_rcx_reg(RAX, | 466 reg_class int_no_rcx_reg(RAX, |
474 RBX, | 471 RBX, |
475 R8, | 472 R8, |
476 R9, | 473 R9, |
477 R10, | 474 R10, |
478 R11, | 475 R11, |
479 R12, | |
480 R13, | 476 R13, |
481 R14); | 477 R14); |
482 | 478 |
483 // Class for all int registers except RAX, RDX (and RSP) | 479 // Class for all int registers except RAX, RDX (and RSP) |
484 reg_class int_no_rax_rdx_reg(RBP, | 480 reg_class int_no_rax_rdx_reg(RBP, |
488 RBX, | 484 RBX, |
489 R8, | 485 R8, |
490 R9, | 486 R9, |
491 R10, | 487 R10, |
492 R11, | 488 R11, |
493 R12, | |
494 R13, | 489 R13, |
495 R14); | 490 R14); |
496 | 491 |
497 // Singleton class for RAX int register | 492 // Singleton class for RAX int register |
498 reg_class int_rax_reg(RAX); | 493 reg_class int_rax_reg(RAX); |
1842 | 1837 |
1843 //============================================================================= | 1838 //============================================================================= |
1844 #ifndef PRODUCT | 1839 #ifndef PRODUCT |
1845 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const | 1840 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const |
1846 { | 1841 { |
1847 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" | 1842 if (UseCompressedOops) { |
1848 "# Inline cache check", oopDesc::klass_offset_in_bytes()); | 1843 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes()); |
1844 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]"); | |
1845 st->print_cr("cmpq rax, rscratch1\t # Inline cache check"); | |
1846 } else { | |
1847 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" | |
1848 "# Inline cache check", oopDesc::klass_offset_in_bytes()); | |
1849 } | |
1849 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); | 1850 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); |
1850 st->print_cr("\tnop"); | 1851 st->print_cr("\tnop"); |
1851 if (!OptoBreakpoint) { | 1852 if (!OptoBreakpoint) { |
1852 st->print_cr("\tnop"); | 1853 st->print_cr("\tnop"); |
1853 } | 1854 } |
1858 { | 1859 { |
1859 MacroAssembler masm(&cbuf); | 1860 MacroAssembler masm(&cbuf); |
1860 #ifdef ASSERT | 1861 #ifdef ASSERT |
1861 uint code_size = cbuf.code_size(); | 1862 uint code_size = cbuf.code_size(); |
1862 #endif | 1863 #endif |
1863 masm.cmpq(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); | 1864 if (UseCompressedOops) { |
1865 masm.load_klass(rscratch1, j_rarg0); | |
1866 masm.cmpq(rax, rscratch1); | |
1867 } else { | |
1868 masm.cmpq(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); | |
1869 } | |
1864 | 1870 |
1865 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | 1871 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
1866 | 1872 |
1867 /* WARNING these NOPs are critical so that verified entry point is properly | 1873 /* WARNING these NOPs are critical so that verified entry point is properly |
1868 aligned for patching by NativeJump::patch_verified_entry() */ | 1874 aligned for patching by NativeJump::patch_verified_entry() */ |
1869 int nops_cnt = 1; | 1875 int nops_cnt = 1; |
1870 if (!OptoBreakpoint) { | 1876 if (!OptoBreakpoint) { |
1871 // Leave space for int3 | 1877 // Leave space for int3 |
1872 nops_cnt += 1; | 1878 nops_cnt += 1; |
1873 } | 1879 } |
1880 if (UseCompressedOops) { | |
1881 // ??? divisible by 4 is aligned? | |
1882 nops_cnt += 1; | |
1883 } | |
1874 masm.nop(nops_cnt); | 1884 masm.nop(nops_cnt); |
1875 | 1885 |
1876 assert(cbuf.code_size() - code_size == size(ra_), | 1886 assert(cbuf.code_size() - code_size == size(ra_), |
1877 "checking code size of inline cache node"); | 1887 "checking code size of inline cache node"); |
1878 } | 1888 } |
1879 | 1889 |
1880 uint MachUEPNode::size(PhaseRegAlloc* ra_) const | 1890 uint MachUEPNode::size(PhaseRegAlloc* ra_) const |
1881 { | 1891 { |
1882 return OptoBreakpoint ? 11 : 12; | 1892 if (UseCompressedOops) { |
1893 return OptoBreakpoint ? 19 : 20; | |
1894 } else { | |
1895 return OptoBreakpoint ? 11 : 12; | |
1896 } | |
1883 } | 1897 } |
1884 | 1898 |
1885 | 1899 |
1886 //============================================================================= | 1900 //============================================================================= |
1887 uint size_exception_handler() | 1901 uint size_exception_handler() |
2050 reg == RSI_num || reg == RSI_H_num || | 2064 reg == RSI_num || reg == RSI_H_num || |
2051 reg == RDX_num || reg == RDX_H_num || | 2065 reg == RDX_num || reg == RDX_H_num || |
2052 reg == RCX_num || reg == RCX_H_num || | 2066 reg == RCX_num || reg == RCX_H_num || |
2053 reg == R8_num || reg == R8_H_num || | 2067 reg == R8_num || reg == R8_H_num || |
2054 reg == R9_num || reg == R9_H_num || | 2068 reg == R9_num || reg == R9_H_num || |
2069 reg == R12_num || reg == R12_H_num || | |
2055 reg == XMM0_num || reg == XMM0_H_num || | 2070 reg == XMM0_num || reg == XMM0_H_num || |
2056 reg == XMM1_num || reg == XMM1_H_num || | 2071 reg == XMM1_num || reg == XMM1_H_num || |
2057 reg == XMM2_num || reg == XMM2_H_num || | 2072 reg == XMM2_num || reg == XMM2_H_num || |
2058 reg == XMM3_num || reg == XMM3_H_num || | 2073 reg == XMM3_num || reg == XMM3_H_num || |
2059 reg == XMM4_num || reg == XMM4_H_num || | 2074 reg == XMM4_num || reg == XMM4_H_num || |
2083 } | 2098 } |
2084 | 2099 |
2085 // Register for MODL projection of divmodL | 2100 // Register for MODL projection of divmodL |
2086 RegMask Matcher::modL_proj_mask() { | 2101 RegMask Matcher::modL_proj_mask() { |
2087 return LONG_RDX_REG_mask; | 2102 return LONG_RDX_REG_mask; |
2103 } | |
2104 | |
2105 static Address build_address(int b, int i, int s, int d) { | |
2106 Register index = as_Register(i); | |
2107 Address::ScaleFactor scale = (Address::ScaleFactor)s; | |
2108 if (index == rsp) { | |
2109 index = noreg; | |
2110 scale = Address::no_scale; | |
2111 } | |
2112 Address addr(as_Register(b), index, scale, d); | |
2113 return addr; | |
2088 } | 2114 } |
2089 | 2115 |
2090 %} | 2116 %} |
2091 | 2117 |
2092 //----------ENCODING BLOCK----------------------------------------------------- | 2118 //----------ENCODING BLOCK----------------------------------------------------- |
2543 %{ | 2569 %{ |
2544 Register Rrdi = as_Register(RDI_enc); // result register | 2570 Register Rrdi = as_Register(RDI_enc); // result register |
2545 Register Rrax = as_Register(RAX_enc); // super class | 2571 Register Rrax = as_Register(RAX_enc); // super class |
2546 Register Rrcx = as_Register(RCX_enc); // killed | 2572 Register Rrcx = as_Register(RCX_enc); // killed |
2547 Register Rrsi = as_Register(RSI_enc); // sub class | 2573 Register Rrsi = as_Register(RSI_enc); // sub class |
2548 Label hit, miss; | 2574 Label hit, miss, cmiss; |
2549 | 2575 |
2550 MacroAssembler _masm(&cbuf); | 2576 MacroAssembler _masm(&cbuf); |
2551 // Compare super with sub directly, since super is not in its own SSA. | 2577 // Compare super with sub directly, since super is not in its own SSA. |
2552 // The compiler used to emit this test, but we fold it in here, | 2578 // The compiler used to emit this test, but we fold it in here, |
2553 // to allow platform-specific tweaking on sparc. | 2579 // to allow platform-specific tweaking on sparc. |
2560 __ movq(Rrdi, Address(Rrsi, | 2586 __ movq(Rrdi, Address(Rrsi, |
2561 sizeof(oopDesc) + | 2587 sizeof(oopDesc) + |
2562 Klass::secondary_supers_offset_in_bytes())); | 2588 Klass::secondary_supers_offset_in_bytes())); |
2563 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); | 2589 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); |
2564 __ addq(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); | 2590 __ addq(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
2565 __ repne_scan(); | 2591 if (UseCompressedOops) { |
2566 __ jcc(Assembler::notEqual, miss); | 2592 __ encode_heap_oop(Rrax); |
2567 __ movq(Address(Rrsi, | 2593 __ repne_scanl(); |
2568 sizeof(oopDesc) + | 2594 __ jcc(Assembler::notEqual, cmiss); |
2569 Klass::secondary_super_cache_offset_in_bytes()), | 2595 __ decode_heap_oop(Rrax); |
2570 Rrax); | 2596 __ movq(Address(Rrsi, |
2597 sizeof(oopDesc) + | |
2598 Klass::secondary_super_cache_offset_in_bytes()), | |
2599 Rrax); | |
2600 __ jmp(hit); | |
2601 __ bind(cmiss); | |
2602 __ decode_heap_oop(Rrax); | |
2603 __ jmp(miss); | |
2604 } else { | |
2605 __ repne_scanq(); | |
2606 __ jcc(Assembler::notEqual, miss); | |
2607 __ movq(Address(Rrsi, | |
2608 sizeof(oopDesc) + | |
2609 Klass::secondary_super_cache_offset_in_bytes()), | |
2610 Rrax); | |
2611 } | |
2571 __ bind(hit); | 2612 __ bind(hit); |
2572 if ($primary) { | 2613 if ($primary) { |
2573 __ xorq(Rrdi, Rrdi); | 2614 __ xorq(Rrdi, Rrdi); |
2574 } | 2615 } |
2575 __ bind(miss); | 2616 __ bind(miss); |
3691 int value_offset = java_lang_String::value_offset_in_bytes(); | 3732 int value_offset = java_lang_String::value_offset_in_bytes(); |
3692 int offset_offset = java_lang_String::offset_offset_in_bytes(); | 3733 int offset_offset = java_lang_String::offset_offset_in_bytes(); |
3693 int count_offset = java_lang_String::count_offset_in_bytes(); | 3734 int count_offset = java_lang_String::count_offset_in_bytes(); |
3694 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); | 3735 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); |
3695 | 3736 |
3696 masm.movq(rax, Address(rsi, value_offset)); | 3737 masm.load_heap_oop(rax, Address(rsi, value_offset)); |
3697 masm.movl(rcx, Address(rsi, offset_offset)); | 3738 masm.movl(rcx, Address(rsi, offset_offset)); |
3698 masm.leaq(rax, Address(rax, rcx, Address::times_2, base_offset)); | 3739 masm.leaq(rax, Address(rax, rcx, Address::times_2, base_offset)); |
3699 masm.movq(rbx, Address(rdi, value_offset)); | 3740 masm.load_heap_oop(rbx, Address(rdi, value_offset)); |
3700 masm.movl(rcx, Address(rdi, offset_offset)); | 3741 masm.movl(rcx, Address(rdi, offset_offset)); |
3701 masm.leaq(rbx, Address(rbx, rcx, Address::times_2, base_offset)); | 3742 masm.leaq(rbx, Address(rbx, rcx, Address::times_2, base_offset)); |
3702 | 3743 |
3703 // Compute the minimum of the string lengths(rsi) and the | 3744 // Compute the minimum of the string lengths(rsi) and the |
3704 // difference of the string lengths (stack) | 3745 // difference of the string lengths (stack) |
4116 // cbuf.inst_mark() is beginning of instruction | 4157 // cbuf.inst_mark() is beginning of instruction |
4117 emit_d32_reloc(cbuf, os::get_polling_page()); | 4158 emit_d32_reloc(cbuf, os::get_polling_page()); |
4118 // relocInfo::poll_type, | 4159 // relocInfo::poll_type, |
4119 %} | 4160 %} |
4120 %} | 4161 %} |
4162 | |
4121 | 4163 |
4122 | 4164 |
4123 //----------FRAME-------------------------------------------------------------- | 4165 //----------FRAME-------------------------------------------------------------- |
4124 // Definition of frame structure and management information. | 4166 // Definition of frame structure and management information. |
4125 // | 4167 // |
4253 "only return normal values"); | 4295 "only return normal values"); |
4254 | 4296 |
4255 static const int lo[Op_RegL + 1] = { | 4297 static const int lo[Op_RegL + 1] = { |
4256 0, | 4298 0, |
4257 0, | 4299 0, |
4300 RAX_num, // Op_RegN | |
4258 RAX_num, // Op_RegI | 4301 RAX_num, // Op_RegI |
4259 RAX_num, // Op_RegP | 4302 RAX_num, // Op_RegP |
4260 XMM0_num, // Op_RegF | 4303 XMM0_num, // Op_RegF |
4261 XMM0_num, // Op_RegD | 4304 XMM0_num, // Op_RegD |
4262 RAX_num // Op_RegL | 4305 RAX_num // Op_RegL |
4263 }; | 4306 }; |
4264 static const int hi[Op_RegL + 1] = { | 4307 static const int hi[Op_RegL + 1] = { |
4265 0, | 4308 0, |
4266 0, | 4309 0, |
4310 OptoReg::Bad, // Op_RegN | |
4267 OptoReg::Bad, // Op_RegI | 4311 OptoReg::Bad, // Op_RegI |
4268 RAX_H_num, // Op_RegP | 4312 RAX_H_num, // Op_RegP |
4269 OptoReg::Bad, // Op_RegF | 4313 OptoReg::Bad, // Op_RegF |
4270 XMM0_H_num, // Op_RegD | 4314 XMM0_H_num, // Op_RegD |
4271 RAX_H_num // Op_RegL | 4315 RAX_H_num // Op_RegL |
4272 }; | 4316 }; |
4273 | 4317 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type"); |
4274 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); | 4318 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); |
4275 %} | 4319 %} |
4276 %} | 4320 %} |
4277 | 4321 |
4278 //----------ATTRIBUTES--------------------------------------------------------- | 4322 //----------ATTRIBUTES--------------------------------------------------------- |
4415 op_cost(5); | 4459 op_cost(5); |
4416 format %{ %} | 4460 format %{ %} |
4417 interface(CONST_INTER); | 4461 interface(CONST_INTER); |
4418 %} | 4462 %} |
4419 | 4463 |
4420 // Unsigned 31-bit Pointer Immediate | 4464 // Pointer Immediate |
4421 // Can be used in both 32-bit signed and 32-bit unsigned insns. | 4465 operand immN() %{ |
4422 // Works for nulls and markOops; not for relocatable (oop) pointers. | 4466 match(ConN); |
4467 | |
4468 op_cost(10); | |
4469 format %{ %} | |
4470 interface(CONST_INTER); | |
4471 %} | |
4472 | |
4473 // NULL Pointer Immediate | |
4474 operand immN0() %{ | |
4475 predicate(n->get_narrowcon() == 0); | |
4476 match(ConN); | |
4477 | |
4478 op_cost(5); | |
4479 format %{ %} | |
4480 interface(CONST_INTER); | |
4481 %} | |
4482 | |
4423 operand immP31() | 4483 operand immP31() |
4424 %{ | 4484 %{ |
4425 predicate(!n->as_Type()->type()->isa_oopptr() | 4485 predicate(!n->as_Type()->type()->isa_oopptr() |
4426 && (n->get_ptr() >> 31) == 0); | 4486 && (n->get_ptr() >> 31) == 0); |
4427 match(ConP); | 4487 match(ConP); |
4428 | 4488 |
4429 op_cost(5); | 4489 op_cost(5); |
4430 format %{ %} | 4490 format %{ %} |
4431 interface(CONST_INTER); | 4491 interface(CONST_INTER); |
4432 %} | 4492 %} |
4493 | |
4433 | 4494 |
4434 // Long Immediate | 4495 // Long Immediate |
4435 operand immL() | 4496 operand immL() |
4436 %{ | 4497 %{ |
4437 match(ConL); | 4498 match(ConL); |
4765 | 4826 |
4766 format %{ %} | 4827 format %{ %} |
4767 interface(REG_INTER); | 4828 interface(REG_INTER); |
4768 %} | 4829 %} |
4769 | 4830 |
4831 | |
4832 operand r12RegL() %{ | |
4833 constraint(ALLOC_IN_RC(long_r12_reg)); | |
4834 match(RegL); | |
4835 | |
4836 format %{ %} | |
4837 interface(REG_INTER); | |
4838 %} | |
4839 | |
4840 operand rRegN() %{ | |
4841 constraint(ALLOC_IN_RC(int_reg)); | |
4842 match(RegN); | |
4843 | |
4844 format %{ %} | |
4845 interface(REG_INTER); | |
4846 %} | |
4847 | |
4770 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? | 4848 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? |
4771 // Answer: Operand match rules govern the DFA as it processes instruction inputs. | 4849 // Answer: Operand match rules govern the DFA as it processes instruction inputs. |
4772 // It's fine for an instruction input which expects rRegP to match a r15_RegP. | 4850 // It's fine for an instruction input which expects rRegP to match a r15_RegP. |
4773 // The output of an instruction is controlled by the allocator, which respects | 4851 // The output of an instruction is controlled by the allocator, which respects |
4774 // register class masks, not match rules. Unless an instruction mentions | 4852 // register class masks, not match rules. Unless an instruction mentions |
4815 operand rax_RegP() | 4893 operand rax_RegP() |
4816 %{ | 4894 %{ |
4817 constraint(ALLOC_IN_RC(ptr_rax_reg)); | 4895 constraint(ALLOC_IN_RC(ptr_rax_reg)); |
4818 match(RegP); | 4896 match(RegP); |
4819 match(rRegP); | 4897 match(rRegP); |
4898 | |
4899 format %{ %} | |
4900 interface(REG_INTER); | |
4901 %} | |
4902 | |
4903 // Special Registers | |
4904 // Return a compressed pointer value | |
4905 operand rax_RegN() | |
4906 %{ | |
4907 constraint(ALLOC_IN_RC(int_rax_reg)); | |
4908 match(RegN); | |
4909 match(rRegN); | |
4820 | 4910 |
4821 format %{ %} | 4911 format %{ %} |
4822 interface(REG_INTER); | 4912 interface(REG_INTER); |
4823 %} | 4913 %} |
4824 | 4914 |
5106 format %{"[$reg + $off + $lreg << $scale]" %} | 5196 format %{"[$reg + $off + $lreg << $scale]" %} |
5107 interface(MEMORY_INTER) %{ | 5197 interface(MEMORY_INTER) %{ |
5108 base($reg); | 5198 base($reg); |
5109 index($lreg); | 5199 index($lreg); |
5110 scale($scale); | 5200 scale($scale); |
5201 disp($off); | |
5202 %} | |
5203 %} | |
5204 | |
5205 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand | |
5206 operand indIndexScaleOffsetComp(rRegN src, immL32 off, r12RegL base) %{ | |
5207 constraint(ALLOC_IN_RC(ptr_reg)); | |
5208 match(AddP (DecodeN src base) off); | |
5209 | |
5210 op_cost(10); | |
5211 format %{"[$base + $src << 3 + $off] (compressed)" %} | |
5212 interface(MEMORY_INTER) %{ | |
5213 base($base); | |
5214 index($src); | |
5215 scale(0x3); | |
5111 disp($off); | 5216 disp($off); |
5112 %} | 5217 %} |
5113 %} | 5218 %} |
5114 | 5219 |
5115 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand | 5220 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand |
5257 // instructions for every form of operand when the instruction accepts | 5362 // instructions for every form of operand when the instruction accepts |
5258 // multiple operand types with the same basic encoding and format. The classic | 5363 // multiple operand types with the same basic encoding and format. The classic |
5259 // case of this is memory operands. | 5364 // case of this is memory operands. |
5260 | 5365 |
5261 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, | 5366 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, |
5262 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset); | 5367 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, |
5368 indIndexScaleOffsetComp); | |
5263 | 5369 |
5264 //----------PIPELINE----------------------------------------------------------- | 5370 //----------PIPELINE----------------------------------------------------------- |
5265 // Rules which define the behavior of the target architectures pipeline. | 5371 // Rules which define the behavior of the target architectures pipeline. |
5266 pipeline %{ | 5372 pipeline %{ |
5267 | 5373 |
5935 opcode(0x8B); | 6041 opcode(0x8B); |
5936 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | 6042 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
5937 ins_pipe(ialu_reg_mem); // XXX | 6043 ins_pipe(ialu_reg_mem); // XXX |
5938 %} | 6044 %} |
5939 | 6045 |
6046 // Load Compressed Pointer | |
6047 instruct loadN(rRegN dst, memory mem, rFlagsReg cr) | |
6048 %{ | |
6049 match(Set dst (LoadN mem)); | |
6050 effect(KILL cr); | |
6051 | |
6052 ins_cost(125); // XXX | |
6053 format %{ "movl $dst, $mem\t# compressed ptr" %} | |
6054 ins_encode %{ | |
6055 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); | |
6056 Register dst = as_Register($dst$$reg); | |
6057 __ movl(dst, addr); | |
6058 %} | |
6059 ins_pipe(ialu_reg_mem); // XXX | |
6060 %} | |
6061 | |
6062 | |
5940 // Load Klass Pointer | 6063 // Load Klass Pointer |
5941 instruct loadKlass(rRegP dst, memory mem) | 6064 instruct loadKlass(rRegP dst, memory mem) |
5942 %{ | 6065 %{ |
5943 match(Set dst (LoadKlass mem)); | 6066 match(Set dst (LoadKlass mem)); |
6067 predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow()); | |
5944 | 6068 |
5945 ins_cost(125); // XXX | 6069 ins_cost(125); // XXX |
5946 format %{ "movq $dst, $mem\t# class" %} | 6070 format %{ "movq $dst, $mem\t# class" %} |
5947 opcode(0x8B); | 6071 opcode(0x8B); |
5948 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); | 6072 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); |
6073 ins_pipe(ialu_reg_mem); // XXX | |
6074 %} | |
6075 | |
6076 // Load Klass Pointer | |
6077 instruct loadKlassComp(rRegP dst, memory mem) | |
6078 %{ | |
6079 match(Set dst (LoadKlass mem)); | |
6080 predicate(n->in(MemNode::Address)->bottom_type()->is_narrow()); | |
6081 | |
6082 ins_cost(125); // XXX | |
6083 format %{ "movl $dst, $mem\t# compressed class" %} | |
6084 ins_encode %{ | |
6085 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); | |
6086 Register dst = as_Register($dst$$reg); | |
6087 __ movl(dst, addr); | |
6088 // klass is never null in the header but this is generated for all | |
6089 // klass loads not just the _klass field in the header. | |
6090 __ decode_heap_oop(dst); | |
6091 %} | |
5949 ins_pipe(ialu_reg_mem); // XXX | 6092 ins_pipe(ialu_reg_mem); // XXX |
5950 %} | 6093 %} |
5951 | 6094 |
5952 // Load Float | 6095 // Load Float |
5953 instruct loadF(regF dst, memory mem) | 6096 instruct loadF(regF dst, memory mem) |
6201 format %{ "movss $dst, [$src]" %} | 6344 format %{ "movss $dst, [$src]" %} |
6202 ins_encode(load_conF(dst, src)); | 6345 ins_encode(load_conF(dst, src)); |
6203 ins_pipe(pipe_slow); | 6346 ins_pipe(pipe_slow); |
6204 %} | 6347 %} |
6205 | 6348 |
6349 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ | |
6350 match(Set dst src); | |
6351 effect(KILL cr); | |
6352 format %{ "xorq $dst, $src\t# compressed ptr" %} | |
6353 ins_encode %{ | |
6354 Register dst = $dst$$Register; | |
6355 __ xorq(dst, dst); | |
6356 %} | |
6357 ins_pipe(ialu_reg); | |
6358 %} | |
6359 | |
6360 instruct loadConN(rRegN dst, immN src) %{ | |
6361 match(Set dst src); | |
6362 | |
6363 ins_cost(125); | |
6364 format %{ "movl $dst, $src\t# compressed ptr" %} | |
6365 ins_encode %{ | |
6366 address con = (address)$src$$constant; | |
6367 Register dst = $dst$$Register; | |
6368 if (con == NULL) { | |
6369 ShouldNotReachHere(); | |
6370 } else { | |
6371 __ movoop(dst, (jobject)$src$$constant); | |
6372 __ encode_heap_oop_not_null(dst); | |
6373 } | |
6374 %} | |
6375 ins_pipe(ialu_reg_fat); // XXX | |
6376 %} | |
6377 | |
6206 instruct loadConF0(regF dst, immF0 src) | 6378 instruct loadConF0(regF dst, immF0 src) |
6207 %{ | 6379 %{ |
6208 match(Set dst src); | 6380 match(Set dst src); |
6209 ins_cost(100); | 6381 ins_cost(100); |
6210 | 6382 |
6454 ins_cost(125); // XXX | 6626 ins_cost(125); // XXX |
6455 format %{ "movq $mem, $src\t# ptr" %} | 6627 format %{ "movq $mem, $src\t# ptr" %} |
6456 opcode(0xC7); /* C7 /0 */ | 6628 opcode(0xC7); /* C7 /0 */ |
6457 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); | 6629 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); |
6458 ins_pipe(ialu_mem_imm); | 6630 ins_pipe(ialu_mem_imm); |
6631 %} | |
6632 | |
6633 // Store Compressed Pointer | |
6634 instruct storeN(memory mem, rRegN src, rFlagsReg cr) | |
6635 %{ | |
6636 match(Set mem (StoreN mem src)); | |
6637 effect(KILL cr); | |
6638 | |
6639 ins_cost(125); // XXX | |
6640 format %{ "movl $mem, $src\t# ptr" %} | |
6641 ins_encode %{ | |
6642 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); | |
6643 Register src = as_Register($src$$reg); | |
6644 __ movl(addr, src); | |
6645 %} | |
6646 ins_pipe(ialu_mem_reg); | |
6459 %} | 6647 %} |
6460 | 6648 |
6461 // Store Integer Immediate | 6649 // Store Integer Immediate |
6462 instruct storeImmI(memory mem, immI src) | 6650 instruct storeImmI(memory mem, immI src) |
6463 %{ | 6651 %{ |
6802 | 6990 |
6803 format %{ "movq $dst, $src\t# ptr -> long" %} | 6991 format %{ "movq $dst, $src\t# ptr -> long" %} |
6804 ins_encode(enc_copy_wide(dst, src)); | 6992 ins_encode(enc_copy_wide(dst, src)); |
6805 ins_pipe(ialu_reg_reg); // XXX | 6993 ins_pipe(ialu_reg_reg); // XXX |
6806 %} | 6994 %} |
6995 | |
6996 | |
6997 // Convert oop pointer into compressed form | |
6998 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ | |
6999 match(Set dst (EncodeP src)); | |
7000 effect(KILL cr); | |
7001 format %{ "encode_heap_oop $dst,$src" %} | |
7002 ins_encode %{ | |
7003 Register s = $src$$Register; | |
7004 Register d = $dst$$Register; | |
7005 if (s != d) { | |
7006 __ movq(d, s); | |
7007 } | |
7008 __ encode_heap_oop(d); | |
7009 %} | |
7010 ins_pipe(ialu_reg_long); | |
7011 %} | |
7012 | |
7013 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ | |
7014 match(Set dst (DecodeN src)); | |
7015 effect(KILL cr); | |
7016 format %{ "decode_heap_oop $dst,$src" %} | |
7017 ins_encode %{ | |
7018 Register s = $src$$Register; | |
7019 Register d = $dst$$Register; | |
7020 if (s != d) { | |
7021 __ movq(d, s); | |
7022 } | |
7023 __ decode_heap_oop(d); | |
7024 %} | |
7025 ins_pipe(ialu_reg_long); | |
7026 %} | |
7027 | |
6807 | 7028 |
6808 //----------Conditional Move--------------------------------------------------- | 7029 //----------Conditional Move--------------------------------------------------- |
6809 // Jump | 7030 // Jump |
6810 // dummy instruction for generating temp registers | 7031 // dummy instruction for generating temp registers |
6811 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ | 7032 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ |
7519 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | 7740 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); |
7520 ins_pipe( pipe_cmpxchg ); | 7741 ins_pipe( pipe_cmpxchg ); |
7521 %} | 7742 %} |
7522 | 7743 |
7523 | 7744 |
7745 instruct compareAndSwapN(rRegI res, | |
7746 memory mem_ptr, | |
7747 rax_RegN oldval, rRegN newval, | |
7748 rFlagsReg cr) %{ | |
7749 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); | |
7750 effect(KILL cr, KILL oldval); | |
7751 | |
7752 format %{ "cmpxchgl $mem_ptr,$newval\t# " | |
7753 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" | |
7754 "sete $res\n\t" | |
7755 "movzbl $res, $res" %} | |
7756 opcode(0x0F, 0xB1); | |
7757 ins_encode(lock_prefix, | |
7758 REX_reg_mem(newval, mem_ptr), | |
7759 OpcP, OpcS, | |
7760 reg_mem(newval, mem_ptr), | |
7761 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete | |
7762 REX_reg_breg(res, res), // movzbl | |
7763 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | |
7764 ins_pipe( pipe_cmpxchg ); | |
7765 %} | |
7766 | |
7524 //----------Subtraction Instructions------------------------------------------- | 7767 //----------Subtraction Instructions------------------------------------------- |
7525 | 7768 |
7526 // Integer Subtraction Instructions | 7769 // Integer Subtraction Instructions |
7527 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | 7770 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) |
7528 %{ | 7771 %{ |
10769 ins_encode(REX_mem_wide(op), | 11012 ins_encode(REX_mem_wide(op), |
10770 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); | 11013 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); |
10771 ins_pipe(ialu_cr_reg_imm); | 11014 ins_pipe(ialu_cr_reg_imm); |
10772 %} | 11015 %} |
10773 | 11016 |
11017 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ | |
11018 match(Set cr (CmpN src zero)); | |
11019 | |
11020 format %{ "testl $src, $src" %} | |
11021 ins_encode %{ __ testl($src$$Register, $src$$Register); %} | |
11022 ins_pipe(ialu_cr_reg_imm); | |
11023 %} | |
11024 | |
10774 // Yanked all unsigned pointer compare operations. | 11025 // Yanked all unsigned pointer compare operations. |
10775 // Pointer compares are done with CmpP which is already unsigned. | 11026 // Pointer compares are done with CmpP which is already unsigned. |
10776 | 11027 |
10777 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) | 11028 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) |
10778 %{ | 11029 %{ |
11016 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, | 11267 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, |
11017 immP0 zero, | 11268 immP0 zero, |
11018 rdi_RegP result) | 11269 rdi_RegP result) |
11019 %{ | 11270 %{ |
11020 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); | 11271 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); |
11272 predicate(!UseCompressedOops); // decoding oop kills condition codes | |
11021 effect(KILL rcx, KILL result); | 11273 effect(KILL rcx, KILL result); |
11022 | 11274 |
11023 ins_cost(1000); | 11275 ins_cost(1000); |
11024 format %{ "cmpq rax, rsi\n\t" | 11276 format %{ "cmpq rax, rsi\n\t" |
11025 "jeq,s miss\t# Actually a hit; we are done.\n\t" | 11277 "jeq,s miss\t# Actually a hit; we are done.\n\t" |