1392 // Update current stubs pointer and restore insts_end.
1393 __ end_a_stub();
1394 }
1395
1396 // size of call stub, compiled java to interpretor
1397 uint size_java_to_interp()
1398 {
1399 return 15; // movq (1+1+8); jmp (1+4)
1400 }
1401
1402 // relocation entries for call stub, compiled java to interpretor
1403 uint reloc_java_to_interp()
1404 {
1405 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1406 }
1407
1408 //=============================================================================
1409 #ifndef PRODUCT
1410 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1411 {
1412 if (UseCompressedOops) {
1413 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1414 if (Universe::narrow_oop_shift() != 0) {
1415 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1");
1416 }
1417 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1418 } else {
1419 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1420 "# Inline cache check");
1421 }
1422 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1423 st->print_cr("\tnop\t# nops to align entry point");
1424 }
1425 #endif
1426
1427 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1428 {
1429 MacroAssembler masm(&cbuf);
1430 uint insts_size = cbuf.insts_size();
1431 if (UseCompressedOops) {
1432 masm.load_klass(rscratch1, j_rarg0);
1433 masm.cmpptr(rax, rscratch1);
1434 } else {
1435 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1436 }
1437
1438 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1439
1440 /* WARNING these NOPs are critical so that verified entry point is properly
1441 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1442 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1443 if (OptoBreakpoint) {
1444 // Leave space for int3
1445 nops_cnt -= 1;
1446 }
1447 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1448 if (nops_cnt > 0)
1449 masm.nop(nops_cnt);
1450 }
1451
1559 // No additional cost for CMOVL.
1560 const int Matcher::long_cmove_cost() { return 0; }
1561
1562 // No CMOVF/CMOVD with SSE2
1563 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1564
1565 // Should the Matcher clone shifts on addressing modes, expecting them
1566 // to be subsumed into complex addressing expressions or compute them
1567 // into registers? True for Intel but false for most RISCs
1568 const bool Matcher::clone_shift_expressions = true;
1569
1570 // Do we need to mask the count passed to shift instructions or does
1571 // the cpu only look at the lower 5/6 bits anyway?
1572 const bool Matcher::need_masked_shift_count = false;
1573
1574 bool Matcher::narrow_oop_use_complex_address() {
1575 assert(UseCompressedOops, "only for compressed oops code");
1576 return (LogMinObjAlignmentInBytes <= 3);
1577 }
1578
1579 // Is it better to copy float constants, or load them directly from
1580 // memory? Intel can load a float constant from a direct address,
1581 // requiring no extra registers. Most RISCs will have to materialize
1582 // an address into a register first, so they would do better to copy
1583 // the constant from stack.
1584 const bool Matcher::rematerialize_float_constants = true; // XXX
1585
1586 // If CPU can load and store mis-aligned doubles directly then no
1587 // fixup is needed. Else we split the double into 2 integer pieces
1588 // and move it piece-by-piece. Only happens when passing doubles into
1589 // C code as the Java calling convention forces doubles to be aligned.
1590 const bool Matcher::misaligned_doubles_ok = true;
1591
1592 // No-op on amd64
1593 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1594
1595 // Advertise here if the CPU requires explicit rounding operations to
1596 // implement the UseStrictFP mode.
1597 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1598
3122 // NULL Pointer Immediate
3123 operand immP0()
3124 %{
3125 predicate(n->get_ptr() == 0);
3126 match(ConP);
3127
3128 op_cost(5);
3129 format %{ %}
3130 interface(CONST_INTER);
3131 %}
3132
3133 // Pointer Immediate
3134 operand immN() %{
3135 match(ConN);
3136
3137 op_cost(10);
3138 format %{ %}
3139 interface(CONST_INTER);
3140 %}
3141
3142 // NULL Pointer Immediate
3143 operand immN0() %{
3144 predicate(n->get_narrowcon() == 0);
3145 match(ConN);
3146
3147 op_cost(5);
3148 format %{ %}
3149 interface(CONST_INTER);
3150 %}
3151
3152 operand immP31()
3153 %{
3154 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3155 && (n->get_ptr() >> 31) == 0);
3156 match(ConP);
3157
3158 op_cost(5);
3159 format %{ %}
3160 interface(CONST_INTER);
3161 %}
4021 %}
4022 %}
4023
4024 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4025 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4026 %{
4027 constraint(ALLOC_IN_RC(ptr_reg));
4028 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4029 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4030
4031 op_cost(10);
4032 format %{"[$reg + $off + $idx << $scale]" %}
4033 interface(MEMORY_INTER) %{
4034 base($reg);
4035 index($idx);
4036 scale($scale);
4037 disp($off);
4038 %}
4039 %}
4040
4041
4042 //----------Special Memory Operands--------------------------------------------
4043 // Stack Slot Operand - This operand is used for loading and storing temporary
4044 // values on the stack where a match requires a value to
4045 // flow through memory.
4046 operand stackSlotP(sRegP reg)
4047 %{
4048 constraint(ALLOC_IN_RC(stack_slots));
4049 // No match rule because this operand is only generated in matching
4050
4051 format %{ "[$reg]" %}
4052 interface(MEMORY_INTER) %{
4053 base(0x4); // RSP
4054 index(0x4); // No Index
4055 scale(0x0); // No Scale
4056 disp($reg); // Stack Offset
4057 %}
4058 %}
4059
4060 operand stackSlotI(sRegI reg)
4192 less(0x2, "b");
4193 greater_equal(0x3, "nb");
4194 less_equal(0x6, "be");
4195 greater(0x7, "nbe");
4196 %}
4197 %}
4198
4199
4200 //----------OPERAND CLASSES----------------------------------------------------
4201 // Operand Classes are groups of operands that are used as to simplify
4202 // instruction definitions by not requiring the AD writer to specify separate
4203 // instructions for every form of operand when the instruction accepts
4204 // multiple operand types with the same basic encoding and format. The classic
4205 // case of this is memory operands.
4206
4207 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4208 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4209 indCompressedOopOffset,
4210 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4211 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4212 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
4213
4214 //----------PIPELINE-----------------------------------------------------------
4215 // Rules which define the behavior of the target architectures pipeline.
4216 pipeline %{
4217
4218 //----------ATTRIBUTES---------------------------------------------------------
4219 attributes %{
4220 variable_size_instructions; // Fixed size instructions
4221 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4222 instruction_unit_size = 1; // An instruction is 1 bytes long
4223 instruction_fetch_unit_size = 16; // The processor fetches one line
4224 instruction_fetch_units = 1; // of 16 bytes
4225
4226 // List of nop instructions
4227 nops( MachNop );
4228 %}
4229
4230 //----------RESOURCES----------------------------------------------------------
4231 // Resources are the functional units available to the machine
4232
5452 %}
5453 ins_pipe(ialu_reg);
5454 %}
5455
5456 instruct loadConN(rRegN dst, immN src) %{
5457 match(Set dst src);
5458
5459 ins_cost(125);
5460 format %{ "movl $dst, $src\t# compressed ptr" %}
5461 ins_encode %{
5462 address con = (address)$src$$constant;
5463 if (con == NULL) {
5464 ShouldNotReachHere();
5465 } else {
5466 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5467 }
5468 %}
5469 ins_pipe(ialu_reg_fat); // XXX
5470 %}
5471
5472 instruct loadConF0(regF dst, immF0 src)
5473 %{
5474 match(Set dst src);
5475 ins_cost(100);
5476
5477 format %{ "xorps $dst, $dst\t# float 0.0" %}
5478 ins_encode %{
5479 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5480 %}
5481 ins_pipe(pipe_slow);
5482 %}
5483
5484 // Use the same format since predicate() can not be used here.
5485 instruct loadConD(regD dst, immD con) %{
5486 match(Set dst con);
5487 ins_cost(125);
5488 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5489 ins_encode %{
5490 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5491 %}
5721 format %{ "movq $mem, $src\t# long" %}
5722 opcode(0x89);
5723 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5724 ins_pipe(ialu_mem_reg); // XXX
5725 %}
5726
5727 // Store Pointer
5728 instruct storeP(memory mem, any_RegP src)
5729 %{
5730 match(Set mem (StoreP mem src));
5731
5732 ins_cost(125); // XXX
5733 format %{ "movq $mem, $src\t# ptr" %}
5734 opcode(0x89);
5735 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5736 ins_pipe(ialu_mem_reg);
5737 %}
5738
5739 instruct storeImmP0(memory mem, immP0 zero)
5740 %{
5741 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5742 match(Set mem (StoreP mem zero));
5743
5744 ins_cost(125); // XXX
5745 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
5746 ins_encode %{
5747 __ movq($mem$$Address, r12);
5748 %}
5749 ins_pipe(ialu_mem_reg);
5750 %}
5751
5752 // Store NULL Pointer, mark word, or other simple pointer constant.
5753 instruct storeImmP(memory mem, immP31 src)
5754 %{
5755 match(Set mem (StoreP mem src));
5756
5757 ins_cost(150); // XXX
5758 format %{ "movq $mem, $src\t# ptr" %}
5759 opcode(0xC7); /* C7 /0 */
5760 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5761 ins_pipe(ialu_mem_imm);
5762 %}
5763
5764 // Store Compressed Pointer
5765 instruct storeN(memory mem, rRegN src)
5766 %{
5767 match(Set mem (StoreN mem src));
5768
5769 ins_cost(125); // XXX
5770 format %{ "movl $mem, $src\t# compressed ptr" %}
5771 ins_encode %{
5772 __ movl($mem$$Address, $src$$Register);
5773 %}
5774 ins_pipe(ialu_mem_reg);
5775 %}
5776
5777 instruct storeImmN0(memory mem, immN0 zero)
5778 %{
5779 predicate(Universe::narrow_oop_base() == NULL);
5780 match(Set mem (StoreN mem zero));
5781
5782 ins_cost(125); // XXX
5783 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
5784 ins_encode %{
5785 __ movl($mem$$Address, r12);
5786 %}
5787 ins_pipe(ialu_mem_reg);
5788 %}
5789
5790 instruct storeImmN(memory mem, immN src)
5791 %{
5792 match(Set mem (StoreN mem src));
5793
5794 ins_cost(150); // XXX
5795 format %{ "movl $mem, $src\t# compressed ptr" %}
5796 ins_encode %{
5797 address con = (address)$src$$constant;
5798 if (con == NULL) {
5799 __ movl($mem$$Address, (int32_t)0);
5800 } else {
5801 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
5802 }
5803 %}
5804 ins_pipe(ialu_mem_imm);
5805 %}
5806
5807 // Store Integer Immediate
5808 instruct storeImmI0(memory mem, immI0 zero)
5809 %{
5810 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5811 match(Set mem (StoreI mem zero));
5812
5813 ins_cost(125); // XXX
5814 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
5815 ins_encode %{
5816 __ movl($mem$$Address, r12);
5817 %}
5818 ins_pipe(ialu_mem_reg);
5819 %}
5820
5821 instruct storeImmI(memory mem, immI src)
5822 %{
5823 match(Set mem (StoreI mem src));
5824
5825 ins_cost(150);
5826 format %{ "movl $mem, $src\t# int" %}
5827 opcode(0xC7); /* C7 /0 */
5828 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5829 ins_pipe(ialu_mem_imm);
5830 %}
5831
5832 // Store Long Immediate
5833 instruct storeImmL0(memory mem, immL0 zero)
5834 %{
5835 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5836 match(Set mem (StoreL mem zero));
5837
5838 ins_cost(125); // XXX
5839 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
5840 ins_encode %{
5841 __ movq($mem$$Address, r12);
5842 %}
5843 ins_pipe(ialu_mem_reg);
5844 %}
5845
5846 instruct storeImmL(memory mem, immL32 src)
5847 %{
5848 match(Set mem (StoreL mem src));
5849
5850 ins_cost(150);
5851 format %{ "movq $mem, $src\t# long" %}
5852 opcode(0xC7); /* C7 /0 */
5853 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5854 ins_pipe(ialu_mem_imm);
5855 %}
5856
5857 // Store Short/Char Immediate
5858 instruct storeImmC0(memory mem, immI0 zero)
5859 %{
5860 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5861 match(Set mem (StoreC mem zero));
5862
5863 ins_cost(125); // XXX
5864 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
5865 ins_encode %{
5866 __ movw($mem$$Address, r12);
5867 %}
5868 ins_pipe(ialu_mem_reg);
5869 %}
5870
5871 instruct storeImmI16(memory mem, immI16 src)
5872 %{
5873 predicate(UseStoreImmI16);
5874 match(Set mem (StoreC mem src));
5875
5876 ins_cost(150);
5877 format %{ "movw $mem, $src\t# short/char" %}
5878 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
5879 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
5880 ins_pipe(ialu_mem_imm);
5881 %}
5882
5883 // Store Byte Immediate
5884 instruct storeImmB0(memory mem, immI0 zero)
5885 %{
5886 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5887 match(Set mem (StoreB mem zero));
5888
5889 ins_cost(125); // XXX
5890 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
5891 ins_encode %{
5892 __ movb($mem$$Address, r12);
5893 %}
5894 ins_pipe(ialu_mem_reg);
5895 %}
5896
5897 instruct storeImmB(memory mem, immI8 src)
5898 %{
5899 match(Set mem (StoreB mem src));
5900
5901 ins_cost(150); // XXX
5902 format %{ "movb $mem, $src\t# byte" %}
5903 opcode(0xC6); /* C6 /0 */
5904 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
5905 ins_pipe(ialu_mem_imm);
5906 %}
5907
5908 // Store CMS card-mark Immediate
5909 instruct storeImmCM0_reg(memory mem, immI0 zero)
5910 %{
5911 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5912 match(Set mem (StoreCM mem zero));
5913
5914 ins_cost(125); // XXX
5915 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
5916 ins_encode %{
5917 __ movb($mem$$Address, r12);
5918 %}
5919 ins_pipe(ialu_mem_reg);
5920 %}
5921
5922 instruct storeImmCM0(memory mem, immI0 src)
5923 %{
5924 match(Set mem (StoreCM mem src));
5925
5926 ins_cost(150); // XXX
5927 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
5928 opcode(0xC6); /* C6 /0 */
5929 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
5930 ins_pipe(ialu_mem_imm);
5931 %}
5932
5933 // Store Float
5934 instruct storeF(memory mem, regF src)
5935 %{
5936 match(Set mem (StoreF mem src));
5937
5938 ins_cost(95); // XXX
5939 format %{ "movss $mem, $src\t# float" %}
5940 ins_encode %{
5941 __ movflt($mem$$Address, $src$$XMMRegister);
5942 %}
5943 ins_pipe(pipe_slow); // XXX
5944 %}
5945
5946 // Store immediate Float value (it is faster than store from XMM register)
5947 instruct storeF0(memory mem, immF0 zero)
5948 %{
5949 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
5950 match(Set mem (StoreF mem zero));
5951
5952 ins_cost(25); // XXX
5953 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
5954 ins_encode %{
5955 __ movl($mem$$Address, r12);
5956 %}
5957 ins_pipe(ialu_mem_reg);
5958 %}
5959
5960 instruct storeF_imm(memory mem, immF src)
5961 %{
5962 match(Set mem (StoreF mem src));
5963
5964 ins_cost(50);
5965 format %{ "movl $mem, $src\t# float" %}
5966 opcode(0xC7); /* C7 /0 */
5967 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
5968 ins_pipe(ialu_mem_imm);
5969 %}
5979 __ movdbl($mem$$Address, $src$$XMMRegister);
5980 %}
5981 ins_pipe(pipe_slow); // XXX
5982 %}
5983
5984 // Store immediate double 0.0 (it is faster than store from XMM register)
5985 instruct storeD0_imm(memory mem, immD0 src)
5986 %{
5987 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
5988 match(Set mem (StoreD mem src));
5989
5990 ins_cost(50);
5991 format %{ "movq $mem, $src\t# double 0." %}
5992 opcode(0xC7); /* C7 /0 */
5993 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
5994 ins_pipe(ialu_mem_imm);
5995 %}
5996
5997 instruct storeD0(memory mem, immD0 zero)
5998 %{
5999 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6000 match(Set mem (StoreD mem zero));
6001
6002 ins_cost(25); // XXX
6003 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
6004 ins_encode %{
6005 __ movq($mem$$Address, r12);
6006 %}
6007 ins_pipe(ialu_mem_reg);
6008 %}
6009
6010 instruct storeSSI(stackSlotI dst, rRegI src)
6011 %{
6012 match(Set dst src);
6013
6014 ins_cost(100);
6015 format %{ "movl $dst, $src\t# int stk" %}
6016 opcode(0x89);
6017 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6018 ins_pipe( ialu_mem_reg );
6019 %}
6465 %}
6466
6467 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6468 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6469 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6470 match(Set dst (DecodeN src));
6471 effect(KILL cr);
6472 format %{ "decode_heap_oop_not_null $dst,$src" %}
6473 ins_encode %{
6474 Register s = $src$$Register;
6475 Register d = $dst$$Register;
6476 if (s != d) {
6477 __ decode_heap_oop_not_null(d, s);
6478 } else {
6479 __ decode_heap_oop_not_null(d);
6480 }
6481 %}
6482 ins_pipe(ialu_reg_long);
6483 %}
6484
6485
6486 //----------Conditional Move---------------------------------------------------
6487 // Jump
6488 // dummy instruction for generating temp registers
6489 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6490 match(Jump (LShiftL switch_val shift));
6491 ins_cost(350);
6492 predicate(false);
6493 effect(TEMP dest);
6494
6495 format %{ "leaq $dest, [$constantaddress]\n\t"
6496 "jmp [$dest + $switch_val << $shift]\n\t" %}
6497 ins_encode %{
6498 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6499 // to do that and the compiler is using that register as one it can allocate.
6500 // So we build it all by hand.
6501 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6502 // ArrayAddress dispatch(table, index);
6503 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6504 __ lea($dest$$Register, $constantaddress);
10435 ins_pipe(ialu_cr_reg_imm);
10436 %}
10437
10438 // This will generate a signed flags result. This should be OK since
10439 // any compare to a zero should be eq/neq.
10440 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
10441 %{
10442 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
10443 match(Set cr (CmpP (LoadP op) zero));
10444
10445 ins_cost(500); // XXX
10446 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
10447 opcode(0xF7); /* Opcode F7 /0 */
10448 ins_encode(REX_mem_wide(op),
10449 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10450 ins_pipe(ialu_cr_reg_imm);
10451 %}
10452
10453 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
10454 %{
10455 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
10456 match(Set cr (CmpP (LoadP mem) zero));
10457
10458 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
10459 ins_encode %{
10460 __ cmpq(r12, $mem$$Address);
10461 %}
10462 ins_pipe(ialu_cr_reg_mem);
10463 %}
10464
10465 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
10466 %{
10467 match(Set cr (CmpN op1 op2));
10468
10469 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10470 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
10471 ins_pipe(ialu_cr_reg_reg);
10472 %}
10473
10474 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
10475 %{
10486 match(Set cr (CmpN op1 op2));
10487
10488 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10489 ins_encode %{
10490 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
10491 %}
10492 ins_pipe(ialu_cr_reg_imm);
10493 %}
10494
10495 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
10496 %{
10497 match(Set cr (CmpN src (LoadN mem)));
10498
10499 format %{ "cmpl $mem, $src\t# compressed ptr" %}
10500 ins_encode %{
10501 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
10502 %}
10503 ins_pipe(ialu_cr_reg_mem);
10504 %}
10505
10506 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
10507 match(Set cr (CmpN src zero));
10508
10509 format %{ "testl $src, $src\t# compressed ptr" %}
10510 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
10511 ins_pipe(ialu_cr_reg_imm);
10512 %}
10513
10514 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
10515 %{
10516 predicate(Universe::narrow_oop_base() != NULL);
10517 match(Set cr (CmpN (LoadN mem) zero));
10518
10519 ins_cost(500); // XXX
10520 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
10521 ins_encode %{
10522 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
10523 %}
10524 ins_pipe(ialu_cr_reg_mem);
10525 %}
10526
10527 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
10528 %{
10529 predicate(Universe::narrow_oop_base() == NULL);
10530 match(Set cr (CmpN (LoadN mem) zero));
10531
10532 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
10533 ins_encode %{
10534 __ cmpl(r12, $mem$$Address);
10535 %}
10536 ins_pipe(ialu_cr_reg_mem);
10537 %}
10538
10539 // Yanked all unsigned pointer compare operations.
10540 // Pointer compares are done with CmpP which is already unsigned.
10541
10542 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10543 %{
10544 match(Set cr (CmpL op1 op2));
10545
10546 format %{ "cmpq $op1, $op2" %}
10547 opcode(0x3B); /* Opcode 3B /r */
10548 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10549 ins_pipe(ialu_cr_reg_reg);
|
1392 // Update current stubs pointer and restore insts_end.
1393 __ end_a_stub();
1394 }
1395
1396 // size of call stub, compiled java to interpretor
1397 uint size_java_to_interp()
1398 {
1399 return 15; // movq (1+1+8); jmp (1+4)
1400 }
1401
1402 // relocation entries for call stub, compiled java to interpretor
1403 uint reloc_java_to_interp()
1404 {
1405 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1406 }
1407
1408 //=============================================================================
1409 #ifndef PRODUCT
1410 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1411 {
1412 if (UseCompressedKlassPointers) {
1413 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1414 if (Universe::narrow_klass_shift() != 0) {
1415 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1416 }
1417 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1418 } else {
1419 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1420 "# Inline cache check");
1421 }
1422 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1423 st->print_cr("\tnop\t# nops to align entry point");
1424 }
1425 #endif
1426
1427 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1428 {
1429 MacroAssembler masm(&cbuf);
1430 uint insts_size = cbuf.insts_size();
1431 if (UseCompressedKlassPointers) {
1432 masm.load_klass(rscratch1, j_rarg0);
1433 masm.cmpptr(rax, rscratch1);
1434 } else {
1435 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1436 }
1437
1438 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1439
1440 /* WARNING these NOPs are critical so that verified entry point is properly
1441 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1442 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1443 if (OptoBreakpoint) {
1444 // Leave space for int3
1445 nops_cnt -= 1;
1446 }
1447 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1448 if (nops_cnt > 0)
1449 masm.nop(nops_cnt);
1450 }
1451
1559 // No additional cost for CMOVL.
1560 const int Matcher::long_cmove_cost() { return 0; }
1561
1562 // No CMOVF/CMOVD with SSE2
1563 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1564
1565 // Should the Matcher clone shifts on addressing modes, expecting them
1566 // to be subsumed into complex addressing expressions or compute them
1567 // into registers? True for Intel but false for most RISCs
1568 const bool Matcher::clone_shift_expressions = true;
1569
1570 // Do we need to mask the count passed to shift instructions or does
1571 // the cpu only look at the lower 5/6 bits anyway?
1572 const bool Matcher::need_masked_shift_count = false;
1573
1574 bool Matcher::narrow_oop_use_complex_address() {
1575 assert(UseCompressedOops, "only for compressed oops code");
1576 return (LogMinObjAlignmentInBytes <= 3);
1577 }
1578
1579 bool Matcher::narrow_klass_use_complex_address() {
1580 assert(UseCompressedKlassPointers, "only for compressed klass code");
1581 return (LogKlassAlignmentInBytes <= 3);
1582 }
1583
1584 // Is it better to copy float constants, or load them directly from
1585 // memory? Intel can load a float constant from a direct address,
1586 // requiring no extra registers. Most RISCs will have to materialize
1587 // an address into a register first, so they would do better to copy
1588 // the constant from stack.
1589 const bool Matcher::rematerialize_float_constants = true; // XXX
1590
1591 // If CPU can load and store mis-aligned doubles directly then no
1592 // fixup is needed. Else we split the double into 2 integer pieces
1593 // and move it piece-by-piece. Only happens when passing doubles into
1594 // C code as the Java calling convention forces doubles to be aligned.
1595 const bool Matcher::misaligned_doubles_ok = true;
1596
1597 // No-op on amd64
1598 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1599
1600 // Advertise here if the CPU requires explicit rounding operations to
1601 // implement the UseStrictFP mode.
1602 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1603
3127 // NULL Pointer Immediate
3128 operand immP0()
3129 %{
3130 predicate(n->get_ptr() == 0);
3131 match(ConP);
3132
3133 op_cost(5);
3134 format %{ %}
3135 interface(CONST_INTER);
3136 %}
3137
3138 // Pointer Immediate
3139 operand immN() %{
3140 match(ConN);
3141
3142 op_cost(10);
3143 format %{ %}
3144 interface(CONST_INTER);
3145 %}
3146
3147 operand immNKlass() %{
3148 match(ConNKlass);
3149
3150 op_cost(10);
3151 format %{ %}
3152 interface(CONST_INTER);
3153 %}
3154
3155 // NULL Pointer Immediate
3156 operand immN0() %{
3157 predicate(n->get_narrowcon() == 0);
3158 match(ConN);
3159
3160 op_cost(5);
3161 format %{ %}
3162 interface(CONST_INTER);
3163 %}
3164
3165 operand immP31()
3166 %{
3167 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3168 && (n->get_ptr() >> 31) == 0);
3169 match(ConP);
3170
3171 op_cost(5);
3172 format %{ %}
3173 interface(CONST_INTER);
3174 %}
4034 %}
4035 %}
4036
4037 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4038 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4039 %{
4040 constraint(ALLOC_IN_RC(ptr_reg));
4041 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4042 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4043
4044 op_cost(10);
4045 format %{"[$reg + $off + $idx << $scale]" %}
4046 interface(MEMORY_INTER) %{
4047 base($reg);
4048 index($idx);
4049 scale($scale);
4050 disp($off);
4051 %}
4052 %}
4053
4054 operand indirectNarrowKlass(rRegN reg)
4055 %{
4056 predicate(Universe::narrow_klass_shift() == 0);
4057 constraint(ALLOC_IN_RC(ptr_reg));
4058 match(DecodeNKlass reg);
4059
4060 format %{ "[$reg]" %}
4061 interface(MEMORY_INTER) %{
4062 base($reg);
4063 index(0x4);
4064 scale(0x0);
4065 disp(0x0);
4066 %}
4067 %}
4068
4069 operand indOffset8NarrowKlass(rRegN reg, immL8 off)
4070 %{
4071 predicate(Universe::narrow_klass_shift() == 0);
4072 constraint(ALLOC_IN_RC(ptr_reg));
4073 match(AddP (DecodeNKlass reg) off);
4074
4075 format %{ "[$reg + $off (8-bit)]" %}
4076 interface(MEMORY_INTER) %{
4077 base($reg);
4078 index(0x4);
4079 scale(0x0);
4080 disp($off);
4081 %}
4082 %}
4083
4084 operand indOffset32NarrowKlass(rRegN reg, immL32 off)
4085 %{
4086 predicate(Universe::narrow_klass_shift() == 0);
4087 constraint(ALLOC_IN_RC(ptr_reg));
4088 match(AddP (DecodeNKlass reg) off);
4089
4090 format %{ "[$reg + $off (32-bit)]" %}
4091 interface(MEMORY_INTER) %{
4092 base($reg);
4093 index(0x4);
4094 scale(0x0);
4095 disp($off);
4096 %}
4097 %}
4098
4099 operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off)
4100 %{
4101 predicate(Universe::narrow_klass_shift() == 0);
4102 constraint(ALLOC_IN_RC(ptr_reg));
4103 match(AddP (AddP (DecodeNKlass reg) lreg) off);
4104
4105 op_cost(10);
4106 format %{"[$reg + $off + $lreg]" %}
4107 interface(MEMORY_INTER) %{
4108 base($reg);
4109 index($lreg);
4110 scale(0x0);
4111 disp($off);
4112 %}
4113 %}
4114
4115 operand indIndexNarrowKlass(rRegN reg, rRegL lreg)
4116 %{
4117 predicate(Universe::narrow_klass_shift() == 0);
4118 constraint(ALLOC_IN_RC(ptr_reg));
4119 match(AddP (DecodeNKlass reg) lreg);
4120
4121 op_cost(10);
4122 format %{"[$reg + $lreg]" %}
4123 interface(MEMORY_INTER) %{
4124 base($reg);
4125 index($lreg);
4126 scale(0x0);
4127 disp(0x0);
4128 %}
4129 %}
4130
4131 operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale)
4132 %{
4133 predicate(Universe::narrow_klass_shift() == 0);
4134 constraint(ALLOC_IN_RC(ptr_reg));
4135 match(AddP (DecodeNKlass reg) (LShiftL lreg scale));
4136
4137 op_cost(10);
4138 format %{"[$reg + $lreg << $scale]" %}
4139 interface(MEMORY_INTER) %{
4140 base($reg);
4141 index($lreg);
4142 scale($scale);
4143 disp(0x0);
4144 %}
4145 %}
4146
4147 operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4148 %{
4149 predicate(Universe::narrow_klass_shift() == 0);
4150 constraint(ALLOC_IN_RC(ptr_reg));
4151 match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off);
4152
4153 op_cost(10);
4154 format %{"[$reg + $off + $lreg << $scale]" %}
4155 interface(MEMORY_INTER) %{
4156 base($reg);
4157 index($lreg);
4158 scale($scale);
4159 disp($off);
4160 %}
4161 %}
4162
4163 operand indCompressedKlassOffset(rRegN reg, immL32 off) %{
4164 predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8));
4165 constraint(ALLOC_IN_RC(ptr_reg));
4166 match(AddP (DecodeNKlass reg) off);
4167
4168 op_cost(10);
4169 format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %}
4170 interface(MEMORY_INTER) %{
4171 base(0xc); // R12
4172 index($reg);
4173 scale(0x3);
4174 disp($off);
4175 %}
4176 %}
4177
4178 operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4179 %{
4180 constraint(ALLOC_IN_RC(ptr_reg));
4181 predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4182 match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off);
4183
4184 op_cost(10);
4185 format %{"[$reg + $off + $idx << $scale]" %}
4186 interface(MEMORY_INTER) %{
4187 base($reg);
4188 index($idx);
4189 scale($scale);
4190 disp($off);
4191 %}
4192 %}
4193
4194 //----------Special Memory Operands--------------------------------------------
4195 // Stack Slot Operand - This operand is used for loading and storing temporary
4196 // values on the stack where a match requires a value to
4197 // flow through memory.
4198 operand stackSlotP(sRegP reg)
4199 %{
4200 constraint(ALLOC_IN_RC(stack_slots));
4201 // No match rule because this operand is only generated in matching
4202
4203 format %{ "[$reg]" %}
4204 interface(MEMORY_INTER) %{
4205 base(0x4); // RSP
4206 index(0x4); // No Index
4207 scale(0x0); // No Scale
4208 disp($reg); // Stack Offset
4209 %}
4210 %}
4211
4212 operand stackSlotI(sRegI reg)
4344 less(0x2, "b");
4345 greater_equal(0x3, "nb");
4346 less_equal(0x6, "be");
4347 greater(0x7, "nbe");
4348 %}
4349 %}
4350
4351
4352 //----------OPERAND CLASSES----------------------------------------------------
4353 // Operand Classes are groups of operands that are used as to simplify
4354 // instruction definitions by not requiring the AD writer to specify separate
4355 // instructions for every form of operand when the instruction accepts
4356 // multiple operand types with the same basic encoding and format. The classic
4357 // case of this is memory operands.
4358
4359 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4360 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4361 indCompressedOopOffset,
4362 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4363 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4364 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow,
4365 indCompressedKlassOffset,
4366 indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass,
4367 indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass,
4368 indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass);
4369
4370 //----------PIPELINE-----------------------------------------------------------
4371 // Rules which define the behavior of the target architectures pipeline.
4372 pipeline %{
4373
4374 //----------ATTRIBUTES---------------------------------------------------------
4375 attributes %{
4376 variable_size_instructions; // Fixed size instructions
4377 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4378 instruction_unit_size = 1; // An instruction is 1 bytes long
4379 instruction_fetch_unit_size = 16; // The processor fetches one line
4380 instruction_fetch_units = 1; // of 16 bytes
4381
4382 // List of nop instructions
4383 nops( MachNop );
4384 %}
4385
4386 //----------RESOURCES----------------------------------------------------------
4387 // Resources are the functional units available to the machine
4388
5608 %}
5609 ins_pipe(ialu_reg);
5610 %}
5611
5612 instruct loadConN(rRegN dst, immN src) %{
5613 match(Set dst src);
5614
5615 ins_cost(125);
5616 format %{ "movl $dst, $src\t# compressed ptr" %}
5617 ins_encode %{
5618 address con = (address)$src$$constant;
5619 if (con == NULL) {
5620 ShouldNotReachHere();
5621 } else {
5622 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5623 }
5624 %}
5625 ins_pipe(ialu_reg_fat); // XXX
5626 %}
5627
5628 instruct loadConNKlass(rRegN dst, immNKlass src) %{
5629 match(Set dst src);
5630
5631 ins_cost(125);
5632 format %{ "movl $dst, $src\t# compressed klass ptr" %}
5633 ins_encode %{
5634 address con = (address)$src$$constant;
5635 if (con == NULL) {
5636 ShouldNotReachHere();
5637 } else {
5638 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
5639 }
5640 %}
5641 ins_pipe(ialu_reg_fat); // XXX
5642 %}
5643
5644 instruct loadConF0(regF dst, immF0 src)
5645 %{
5646 match(Set dst src);
5647 ins_cost(100);
5648
5649 format %{ "xorps $dst, $dst\t# float 0.0" %}
5650 ins_encode %{
5651 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5652 %}
5653 ins_pipe(pipe_slow);
5654 %}
5655
5656 // Use the same format since predicate() can not be used here.
5657 instruct loadConD(regD dst, immD con) %{
5658 match(Set dst con);
5659 ins_cost(125);
5660 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5661 ins_encode %{
5662 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5663 %}
5893 format %{ "movq $mem, $src\t# long" %}
5894 opcode(0x89);
5895 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5896 ins_pipe(ialu_mem_reg); // XXX
5897 %}
5898
5899 // Store Pointer
5900 instruct storeP(memory mem, any_RegP src)
5901 %{
5902 match(Set mem (StoreP mem src));
5903
5904 ins_cost(125); // XXX
5905 format %{ "movq $mem, $src\t# ptr" %}
5906 opcode(0x89);
5907 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5908 ins_pipe(ialu_mem_reg);
5909 %}
5910
5911 instruct storeImmP0(memory mem, immP0 zero)
5912 %{
5913 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5914 match(Set mem (StoreP mem zero));
5915
5916 ins_cost(125); // XXX
5917 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
5918 ins_encode %{
5919 __ movq($mem$$Address, r12);
5920 %}
5921 ins_pipe(ialu_mem_reg);
5922 %}
5923
5924 // Store NULL Pointer, mark word, or other simple pointer constant.
5925 instruct storeImmP(memory mem, immP31 src)
5926 %{
5927 match(Set mem (StoreP mem src));
5928
5929 ins_cost(150); // XXX
5930 format %{ "movq $mem, $src\t# ptr" %}
5931 opcode(0xC7); /* C7 /0 */
5932 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5933 ins_pipe(ialu_mem_imm);
5934 %}
5935
5936 // Store Compressed Pointer
5937 instruct storeN(memory mem, rRegN src)
5938 %{
5939 match(Set mem (StoreN mem src));
5940
5941 ins_cost(125); // XXX
5942 format %{ "movl $mem, $src\t# compressed ptr" %}
5943 ins_encode %{
5944 __ movl($mem$$Address, $src$$Register);
5945 %}
5946 ins_pipe(ialu_mem_reg);
5947 %}
5948
5949 instruct storeNKlass(memory mem, rRegN src)
5950 %{
5951 match(Set mem (StoreNKlass mem src));
5952
5953 ins_cost(125); // XXX
5954 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5955 ins_encode %{
5956 __ movl($mem$$Address, $src$$Register);
5957 %}
5958 ins_pipe(ialu_mem_reg);
5959 %}
5960
5961 instruct storeImmN0(memory mem, immN0 zero)
5962 %{
5963 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL);
5964 match(Set mem (StoreN mem zero));
5965
5966 ins_cost(125); // XXX
5967 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
5968 ins_encode %{
5969 __ movl($mem$$Address, r12);
5970 %}
5971 ins_pipe(ialu_mem_reg);
5972 %}
5973
5974 instruct storeImmN(memory mem, immN src)
5975 %{
5976 match(Set mem (StoreN mem src));
5977
5978 ins_cost(150); // XXX
5979 format %{ "movl $mem, $src\t# compressed ptr" %}
5980 ins_encode %{
5981 address con = (address)$src$$constant;
5982 if (con == NULL) {
5983 __ movl($mem$$Address, (int32_t)0);
5984 } else {
5985 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
5986 }
5987 %}
5988 ins_pipe(ialu_mem_imm);
5989 %}
5990
5991 instruct storeImmNKlass(memory mem, immNKlass src)
5992 %{
5993 match(Set mem (StoreNKlass mem src));
5994
5995 ins_cost(150); // XXX
5996 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5997 ins_encode %{
5998 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
5999 %}
6000 ins_pipe(ialu_mem_imm);
6001 %}
6002
6003 // Store Integer Immediate
6004 instruct storeImmI0(memory mem, immI0 zero)
6005 %{
6006 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6007 match(Set mem (StoreI mem zero));
6008
6009 ins_cost(125); // XXX
6010 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
6011 ins_encode %{
6012 __ movl($mem$$Address, r12);
6013 %}
6014 ins_pipe(ialu_mem_reg);
6015 %}
6016
6017 instruct storeImmI(memory mem, immI src)
6018 %{
6019 match(Set mem (StoreI mem src));
6020
6021 ins_cost(150);
6022 format %{ "movl $mem, $src\t# int" %}
6023 opcode(0xC7); /* C7 /0 */
6024 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6025 ins_pipe(ialu_mem_imm);
6026 %}
6027
6028 // Store Long Immediate
6029 instruct storeImmL0(memory mem, immL0 zero)
6030 %{
6031 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6032 match(Set mem (StoreL mem zero));
6033
6034 ins_cost(125); // XXX
6035 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
6036 ins_encode %{
6037 __ movq($mem$$Address, r12);
6038 %}
6039 ins_pipe(ialu_mem_reg);
6040 %}
6041
6042 instruct storeImmL(memory mem, immL32 src)
6043 %{
6044 match(Set mem (StoreL mem src));
6045
6046 ins_cost(150);
6047 format %{ "movq $mem, $src\t# long" %}
6048 opcode(0xC7); /* C7 /0 */
6049 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6050 ins_pipe(ialu_mem_imm);
6051 %}
6052
6053 // Store Short/Char Immediate
6054 instruct storeImmC0(memory mem, immI0 zero)
6055 %{
6056 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6057 match(Set mem (StoreC mem zero));
6058
6059 ins_cost(125); // XXX
6060 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
6061 ins_encode %{
6062 __ movw($mem$$Address, r12);
6063 %}
6064 ins_pipe(ialu_mem_reg);
6065 %}
6066
6067 instruct storeImmI16(memory mem, immI16 src)
6068 %{
6069 predicate(UseStoreImmI16);
6070 match(Set mem (StoreC mem src));
6071
6072 ins_cost(150);
6073 format %{ "movw $mem, $src\t# short/char" %}
6074 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
6075 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
6076 ins_pipe(ialu_mem_imm);
6077 %}
6078
6079 // Store Byte Immediate
6080 instruct storeImmB0(memory mem, immI0 zero)
6081 %{
6082 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6083 match(Set mem (StoreB mem zero));
6084
6085 ins_cost(125); // XXX
6086 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
6087 ins_encode %{
6088 __ movb($mem$$Address, r12);
6089 %}
6090 ins_pipe(ialu_mem_reg);
6091 %}
6092
6093 instruct storeImmB(memory mem, immI8 src)
6094 %{
6095 match(Set mem (StoreB mem src));
6096
6097 ins_cost(150); // XXX
6098 format %{ "movb $mem, $src\t# byte" %}
6099 opcode(0xC6); /* C6 /0 */
6100 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6101 ins_pipe(ialu_mem_imm);
6102 %}
6103
6104 // Store CMS card-mark Immediate
6105 instruct storeImmCM0_reg(memory mem, immI0 zero)
6106 %{
6107 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6108 match(Set mem (StoreCM mem zero));
6109
6110 ins_cost(125); // XXX
6111 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
6112 ins_encode %{
6113 __ movb($mem$$Address, r12);
6114 %}
6115 ins_pipe(ialu_mem_reg);
6116 %}
6117
6118 instruct storeImmCM0(memory mem, immI0 src)
6119 %{
6120 match(Set mem (StoreCM mem src));
6121
6122 ins_cost(150); // XXX
6123 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
6124 opcode(0xC6); /* C6 /0 */
6125 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6126 ins_pipe(ialu_mem_imm);
6127 %}
6128
6129 // Store Float
6130 instruct storeF(memory mem, regF src)
6131 %{
6132 match(Set mem (StoreF mem src));
6133
6134 ins_cost(95); // XXX
6135 format %{ "movss $mem, $src\t# float" %}
6136 ins_encode %{
6137 __ movflt($mem$$Address, $src$$XMMRegister);
6138 %}
6139 ins_pipe(pipe_slow); // XXX
6140 %}
6141
6142 // Store immediate Float value (it is faster than store from XMM register)
6143 instruct storeF0(memory mem, immF0 zero)
6144 %{
6145 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6146 match(Set mem (StoreF mem zero));
6147
6148 ins_cost(25); // XXX
6149 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
6150 ins_encode %{
6151 __ movl($mem$$Address, r12);
6152 %}
6153 ins_pipe(ialu_mem_reg);
6154 %}
6155
6156 instruct storeF_imm(memory mem, immF src)
6157 %{
6158 match(Set mem (StoreF mem src));
6159
6160 ins_cost(50);
6161 format %{ "movl $mem, $src\t# float" %}
6162 opcode(0xC7); /* C7 /0 */
6163 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6164 ins_pipe(ialu_mem_imm);
6165 %}
6175 __ movdbl($mem$$Address, $src$$XMMRegister);
6176 %}
6177 ins_pipe(pipe_slow); // XXX
6178 %}
6179
6180 // Store immediate double 0.0 (it is faster than store from XMM register)
6181 instruct storeD0_imm(memory mem, immD0 src)
6182 %{
6183 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
6184 match(Set mem (StoreD mem src));
6185
6186 ins_cost(50);
6187 format %{ "movq $mem, $src\t# double 0." %}
6188 opcode(0xC7); /* C7 /0 */
6189 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6190 ins_pipe(ialu_mem_imm);
6191 %}
6192
6193 instruct storeD0(memory mem, immD0 zero)
6194 %{
6195 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6196 match(Set mem (StoreD mem zero));
6197
6198 ins_cost(25); // XXX
6199 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
6200 ins_encode %{
6201 __ movq($mem$$Address, r12);
6202 %}
6203 ins_pipe(ialu_mem_reg);
6204 %}
6205
6206 instruct storeSSI(stackSlotI dst, rRegI src)
6207 %{
6208 match(Set dst src);
6209
6210 ins_cost(100);
6211 format %{ "movl $dst, $src\t# int stk" %}
6212 opcode(0x89);
6213 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6214 ins_pipe( ialu_mem_reg );
6215 %}
6661 %}
6662
6663 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6664 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6665 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6666 match(Set dst (DecodeN src));
6667 effect(KILL cr);
6668 format %{ "decode_heap_oop_not_null $dst,$src" %}
6669 ins_encode %{
6670 Register s = $src$$Register;
6671 Register d = $dst$$Register;
6672 if (s != d) {
6673 __ decode_heap_oop_not_null(d, s);
6674 } else {
6675 __ decode_heap_oop_not_null(d);
6676 }
6677 %}
6678 ins_pipe(ialu_reg_long);
6679 %}
6680
6681 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6682 match(Set dst (EncodePKlass src));
6683 effect(KILL cr);
6684 format %{ "encode_heap_oop_not_null $dst,$src" %}
6685 ins_encode %{
6686 __ encode_klass_not_null($dst$$Register, $src$$Register);
6687 %}
6688 ins_pipe(ialu_reg_long);
6689 %}
6690
6691 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6692 match(Set dst (DecodeNKlass src));
6693 effect(KILL cr);
6694 format %{ "decode_heap_oop_not_null $dst,$src" %}
6695 ins_encode %{
6696 Register s = $src$$Register;
6697 Register d = $dst$$Register;
6698 if (s != d) {
6699 __ decode_klass_not_null(d, s);
6700 } else {
6701 __ decode_klass_not_null(d);
6702 }
6703 %}
6704 ins_pipe(ialu_reg_long);
6705 %}
6706
6707
6708 //----------Conditional Move---------------------------------------------------
6709 // Jump
6710 // dummy instruction for generating temp registers
6711 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6712 match(Jump (LShiftL switch_val shift));
6713 ins_cost(350);
6714 predicate(false);
6715 effect(TEMP dest);
6716
6717 format %{ "leaq $dest, [$constantaddress]\n\t"
6718 "jmp [$dest + $switch_val << $shift]\n\t" %}
6719 ins_encode %{
6720 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6721 // to do that and the compiler is using that register as one it can allocate.
6722 // So we build it all by hand.
6723 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6724 // ArrayAddress dispatch(table, index);
6725 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6726 __ lea($dest$$Register, $constantaddress);
10657 ins_pipe(ialu_cr_reg_imm);
10658 %}
10659
10660 // This will generate a signed flags result. This should be OK since
10661 // any compare to a zero should be eq/neq.
10662 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
10663 %{
10664 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
10665 match(Set cr (CmpP (LoadP op) zero));
10666
10667 ins_cost(500); // XXX
10668 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
10669 opcode(0xF7); /* Opcode F7 /0 */
10670 ins_encode(REX_mem_wide(op),
10671 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10672 ins_pipe(ialu_cr_reg_imm);
10673 %}
10674
10675 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
10676 %{
10677 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
10678 match(Set cr (CmpP (LoadP mem) zero));
10679
10680 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
10681 ins_encode %{
10682 __ cmpq(r12, $mem$$Address);
10683 %}
10684 ins_pipe(ialu_cr_reg_mem);
10685 %}
10686
10687 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
10688 %{
10689 match(Set cr (CmpN op1 op2));
10690
10691 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10692 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
10693 ins_pipe(ialu_cr_reg_reg);
10694 %}
10695
10696 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
10697 %{
10708 match(Set cr (CmpN op1 op2));
10709
10710 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10711 ins_encode %{
10712 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
10713 %}
10714 ins_pipe(ialu_cr_reg_imm);
10715 %}
10716
10717 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
10718 %{
10719 match(Set cr (CmpN src (LoadN mem)));
10720
10721 format %{ "cmpl $mem, $src\t# compressed ptr" %}
10722 ins_encode %{
10723 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
10724 %}
10725 ins_pipe(ialu_cr_reg_mem);
10726 %}
10727
10728 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
10729 match(Set cr (CmpN op1 op2));
10730
10731 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
10732 ins_encode %{
10733 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
10734 %}
10735 ins_pipe(ialu_cr_reg_imm);
10736 %}
10737
10738 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
10739 %{
10740 match(Set cr (CmpN src (LoadNKlass mem)));
10741
10742 format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
10743 ins_encode %{
10744 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
10745 %}
10746 ins_pipe(ialu_cr_reg_mem);
10747 %}
10748
10749 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
10750 match(Set cr (CmpN src zero));
10751
10752 format %{ "testl $src, $src\t# compressed ptr" %}
10753 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
10754 ins_pipe(ialu_cr_reg_imm);
10755 %}
10756
10757 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
10758 %{
10759 predicate(Universe::narrow_oop_base() != NULL);
10760 match(Set cr (CmpN (LoadN mem) zero));
10761
10762 ins_cost(500); // XXX
10763 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
10764 ins_encode %{
10765 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
10766 %}
10767 ins_pipe(ialu_cr_reg_mem);
10768 %}
10769
10770 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
10771 %{
10772 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL));
10773 match(Set cr (CmpN (LoadN mem) zero));
10774
10775 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
10776 ins_encode %{
10777 __ cmpl(r12, $mem$$Address);
10778 %}
10779 ins_pipe(ialu_cr_reg_mem);
10780 %}
10781
10782 // Yanked all unsigned pointer compare operations.
10783 // Pointer compares are done with CmpP which is already unsigned.
10784
10785 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10786 %{
10787 match(Set cr (CmpL op1 op2));
10788
10789 format %{ "cmpq $op1, $op2" %}
10790 opcode(0x3B); /* Opcode 3B /r */
10791 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10792 ins_pipe(ialu_cr_reg_reg);
|