hotspot/src/cpu/x86/vm/x86_64.ad
changeset 2154 72a9b7284ccf
parent 2105 347008ce7984
parent 2150 0d91d17158cc
child 2259 d3c946e7f127
equal deleted inserted replaced
2106:ec595a5e793e 2154:72a9b7284ccf
  3460   %}
  3460   %}
  3461 
  3461 
  3462 
  3462 
  3463   enc_class movq_ld(regD dst, memory mem) %{
  3463   enc_class movq_ld(regD dst, memory mem) %{
  3464     MacroAssembler _masm(&cbuf);
  3464     MacroAssembler _masm(&cbuf);
  3465     Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
  3465     __ movq($dst$$XMMRegister, $mem$$Address);
  3466     __ movq(as_XMMRegister($dst$$reg), madr);
       
  3467   %}
  3466   %}
  3468 
  3467 
  3469   enc_class movq_st(memory mem, regD src) %{
  3468   enc_class movq_st(memory mem, regD src) %{
  3470     MacroAssembler _masm(&cbuf);
  3469     MacroAssembler _masm(&cbuf);
  3471     Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
  3470     __ movq($mem$$Address, $src$$XMMRegister);
  3472     __ movq(madr, as_XMMRegister($src$$reg));
       
  3473   %}
  3471   %}
  3474 
  3472 
  3475   enc_class pshufd_8x8(regF dst, regF src) %{
  3473   enc_class pshufd_8x8(regF dst, regF src) %{
  3476     MacroAssembler _masm(&cbuf);
  3474     MacroAssembler _masm(&cbuf);
  3477 
  3475 
  3763     masm.bind(RCX_GOOD_LABEL);
  3761     masm.bind(RCX_GOOD_LABEL);
  3764     masm.testl(rsi, rsi);
  3762     masm.testl(rsi, rsi);
  3765     masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
  3763     masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
  3766 
  3764 
  3767     // Load first characters
  3765     // Load first characters
  3768     masm.load_unsigned_word(rcx, Address(rbx, 0));
  3766     masm.load_unsigned_short(rcx, Address(rbx, 0));
  3769     masm.load_unsigned_word(rdi, Address(rax, 0));
  3767     masm.load_unsigned_short(rdi, Address(rax, 0));
  3770 
  3768 
  3771     // Compare first characters
  3769     // Compare first characters
  3772     masm.subl(rcx, rdi);
  3770     masm.subl(rcx, rdi);
  3773     masm.jcc(Assembler::notZero,  POP_LABEL);
  3771     masm.jcc(Assembler::notZero,  POP_LABEL);
  3774     masm.decrementl(rsi);
  3772     masm.decrementl(rsi);
  3794     masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2));
  3792     masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2));
  3795     masm.negptr(rsi);
  3793     masm.negptr(rsi);
  3796 
  3794 
  3797     // Compare the rest of the characters
  3795     // Compare the rest of the characters
  3798     masm.bind(WHILE_HEAD_LABEL);
  3796     masm.bind(WHILE_HEAD_LABEL);
  3799     masm.load_unsigned_word(rcx, Address(rbx, rsi, Address::times_2, 0));
  3797     masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
  3800     masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0));
  3798     masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
  3801     masm.subl(rcx, rdi);
  3799     masm.subl(rcx, rdi);
  3802     masm.jcc(Assembler::notZero, POP_LABEL);
  3800     masm.jcc(Assembler::notZero, POP_LABEL);
  3803     masm.increment(rsi);
  3801     masm.increment(rsi);
  3804     masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
  3802     masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
  3805 
  3803 
  3852     masm.andl(tmp2Reg, 1);
  3850     masm.andl(tmp2Reg, 1);
  3853     masm.testl(tmp2Reg, tmp2Reg);
  3851     masm.testl(tmp2Reg, tmp2Reg);
  3854     masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
  3852     masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
  3855 
  3853 
  3856     // Compare 2-byte "tail" at end of arrays
  3854     // Compare 2-byte "tail" at end of arrays
  3857     masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
  3855     masm.load_unsigned_short(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
  3858     masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
  3856     masm.load_unsigned_short(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
  3859     masm.cmpl(tmp1Reg, tmp2Reg);
  3857     masm.cmpl(tmp1Reg, tmp2Reg);
  3860     masm.jcc(Assembler::notEqual, FALSE_LABEL);
  3858     masm.jcc(Assembler::notEqual, FALSE_LABEL);
  3861     masm.testl(resultReg, resultReg);
  3859     masm.testl(resultReg, resultReg);
  3862     masm.jcc(Assembler::zero, TRUE_LABEL);
  3860     masm.jcc(Assembler::zero, TRUE_LABEL);
  3863 
  3861 
  5481 %}
  5479 %}
  5482 
  5480 
  5483 
  5481 
  5484 //----------OPERAND CLASSES----------------------------------------------------
  5482 //----------OPERAND CLASSES----------------------------------------------------
  5485 // Operand Classes are groups of operands that are used as to simplify
  5483 // Operand Classes are groups of operands that are used as to simplify
  5486 // instruction definitions by not requiring the AD writer to specify seperate
  5484 // instruction definitions by not requiring the AD writer to specify separate
  5487 // instructions for every form of operand when the instruction accepts
  5485 // instructions for every form of operand when the instruction accepts
  5488 // multiple operand types with the same basic encoding and format.  The classic
  5486 // multiple operand types with the same basic encoding and format.  The classic
  5489 // case of this is memory operands.
  5487 // case of this is memory operands.
  5490 
  5488 
  5491 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
  5489 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
  6029 %{
  6027 %{
  6030   match(Set dst (LoadB mem));
  6028   match(Set dst (LoadB mem));
  6031 
  6029 
  6032   ins_cost(125);
  6030   ins_cost(125);
  6033   format %{ "movsbl  $dst, $mem\t# byte" %}
  6031   format %{ "movsbl  $dst, $mem\t# byte" %}
  6034   opcode(0x0F, 0xBE);
  6032 
  6035   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6033   ins_encode %{
       
  6034     __ movsbl($dst$$Register, $mem$$Address);
       
  6035   %}
       
  6036 
  6036   ins_pipe(ialu_reg_mem);
  6037   ins_pipe(ialu_reg_mem);
  6037 %}
  6038 %}
  6038 
  6039 
  6039 // Load Byte (8 bit signed) into long
  6040 // Load Byte (8 bit signed) into Long Register
  6040 // instruct loadB2L(rRegL dst, memory mem)
  6041 instruct loadB2L(rRegL dst, memory mem)
  6041 // %{
  6042 %{
  6042 //   match(Set dst (ConvI2L (LoadB mem)));
  6043   match(Set dst (ConvI2L (LoadB mem)));
  6043 
  6044 
  6044 //   ins_cost(125);
  6045   ins_cost(125);
  6045 //   format %{ "movsbq  $dst, $mem\t# byte -> long" %}
  6046   format %{ "movsbq  $dst, $mem\t# byte -> long" %}
  6046 //   opcode(0x0F, 0xBE);
  6047 
  6047 //   ins_encode(REX_reg_mem_wide(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6048   ins_encode %{
  6048 //   ins_pipe(ialu_reg_mem);
  6049     __ movsbq($dst$$Register, $mem$$Address);
  6049 // %}
  6050   %}
  6050 
  6051 
  6051 // Load Byte (8 bit UNsigned)
  6052   ins_pipe(ialu_reg_mem);
  6052 instruct loadUB(rRegI dst, memory mem, immI_255 bytemask)
  6053 %}
  6053 %{
  6054 
  6054   match(Set dst (AndI (LoadB mem) bytemask));
  6055 // Load Unsigned Byte (8 bit UNsigned)
       
  6056 instruct loadUB(rRegI dst, memory mem)
       
  6057 %{
       
  6058   match(Set dst (LoadUB mem));
  6055 
  6059 
  6056   ins_cost(125);
  6060   ins_cost(125);
  6057   format %{ "movzbl  $dst, $mem\t# ubyte" %}
  6061   format %{ "movzbl  $dst, $mem\t# ubyte" %}
  6058   opcode(0x0F, 0xB6);
  6062 
  6059   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6063   ins_encode %{
       
  6064     __ movzbl($dst$$Register, $mem$$Address);
       
  6065   %}
       
  6066 
  6060   ins_pipe(ialu_reg_mem);
  6067   ins_pipe(ialu_reg_mem);
  6061 %}
  6068 %}
  6062 
  6069 
  6063 // Load Byte (8 bit UNsigned) into long
  6070 // Load Unsigned Byte (8 bit UNsigned) into Long Register
  6064 // instruct loadUB2L(rRegL dst, memory mem, immI_255 bytemask)
  6071 instruct loadUB2L(rRegL dst, memory mem)
  6065 // %{
  6072 %{
  6066 //   match(Set dst (ConvI2L (AndI (LoadB mem) bytemask)));
  6073   match(Set dst (ConvI2L (LoadUB mem)));
  6067 
  6074 
  6068 //   ins_cost(125);
  6075   ins_cost(125);
  6069 //   format %{ "movzbl  $dst, $mem\t# ubyte -> long" %}
  6076   format %{ "movzbq  $dst, $mem\t# ubyte -> long" %}
  6070 //   opcode(0x0F, 0xB6);
  6077 
  6071 //   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6078   ins_encode %{
  6072 //   ins_pipe(ialu_reg_mem);
  6079     __ movzbq($dst$$Register, $mem$$Address);
  6073 // %}
  6080   %}
       
  6081 
       
  6082   ins_pipe(ialu_reg_mem);
       
  6083 %}
  6074 
  6084 
  6075 // Load Short (16 bit signed)
  6085 // Load Short (16 bit signed)
  6076 instruct loadS(rRegI dst, memory mem)
  6086 instruct loadS(rRegI dst, memory mem)
  6077 %{
  6087 %{
  6078   match(Set dst (LoadS mem));
  6088   match(Set dst (LoadS mem));
  6079 
  6089 
  6080   ins_cost(125); // XXX
  6090   ins_cost(125);
  6081   format %{ "movswl $dst, $mem\t# short" %}
  6091   format %{ "movswl $dst, $mem\t# short" %}
  6082   opcode(0x0F, 0xBF);
  6092 
  6083   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6093   ins_encode %{
       
  6094     __ movswl($dst$$Register, $mem$$Address);
       
  6095   %}
       
  6096 
  6084   ins_pipe(ialu_reg_mem);
  6097   ins_pipe(ialu_reg_mem);
  6085 %}
  6098 %}
  6086 
  6099 
  6087 // Load Short (16 bit signed) into long
  6100 // Load Short (16 bit signed) into Long Register
  6088 // instruct loadS2L(rRegL dst, memory mem)
  6101 instruct loadS2L(rRegL dst, memory mem)
  6089 // %{
  6102 %{
  6090 //   match(Set dst (ConvI2L (LoadS mem)));
  6103   match(Set dst (ConvI2L (LoadS mem)));
  6091 
  6104 
  6092 //   ins_cost(125); // XXX
  6105   ins_cost(125);
  6093 //   format %{ "movswq $dst, $mem\t# short -> long" %}
  6106   format %{ "movswq $dst, $mem\t# short -> long" %}
  6094 //   opcode(0x0F, 0xBF);
  6107 
  6095 //   ins_encode(REX_reg_mem_wide(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6108   ins_encode %{
  6096 //   ins_pipe(ialu_reg_mem);
  6109     __ movswq($dst$$Register, $mem$$Address);
  6097 // %}
  6110   %}
       
  6111 
       
  6112   ins_pipe(ialu_reg_mem);
       
  6113 %}
  6098 
  6114 
  6099 // Load Unsigned Short/Char (16 bit UNsigned)
  6115 // Load Unsigned Short/Char (16 bit UNsigned)
  6100 instruct loadUS(rRegI dst, memory mem)
  6116 instruct loadUS(rRegI dst, memory mem)
  6101 %{
  6117 %{
  6102   match(Set dst (LoadUS mem));
  6118   match(Set dst (LoadUS mem));
  6103 
  6119 
  6104   ins_cost(125);
  6120   ins_cost(125);
  6105   format %{ "movzwl  $dst, $mem\t# ushort/char" %}
  6121   format %{ "movzwl  $dst, $mem\t# ushort/char" %}
  6106   opcode(0x0F, 0xB7);
  6122 
  6107   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6123   ins_encode %{
       
  6124     __ movzwl($dst$$Register, $mem$$Address);
       
  6125   %}
       
  6126 
  6108   ins_pipe(ialu_reg_mem);
  6127   ins_pipe(ialu_reg_mem);
  6109 %}
  6128 %}
  6110 
  6129 
  6111 // Load Unsigned Short/Char (16 bit UNsigned) into long
  6130 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
  6112 // instruct loadUS2L(rRegL dst, memory mem)
  6131 instruct loadUS2L(rRegL dst, memory mem)
  6113 // %{
  6132 %{
  6114 //   match(Set dst (ConvI2L (LoadUS mem)));
  6133   match(Set dst (ConvI2L (LoadUS mem)));
  6115 
  6134 
  6116 //   ins_cost(125);
  6135   ins_cost(125);
  6117 //   format %{ "movzwl  $dst, $mem\t# ushort/char -> long" %}
  6136   format %{ "movzwq  $dst, $mem\t# ushort/char -> long" %}
  6118 //   opcode(0x0F, 0xB7);
  6137 
  6119 //   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
  6138   ins_encode %{
  6120 //   ins_pipe(ialu_reg_mem);
  6139     __ movzwq($dst$$Register, $mem$$Address);
  6121 // %}
  6140   %}
       
  6141 
       
  6142   ins_pipe(ialu_reg_mem);
       
  6143 %}
  6122 
  6144 
  6123 // Load Integer
  6145 // Load Integer
  6124 instruct loadI(rRegI dst, memory mem)
  6146 instruct loadI(rRegI dst, memory mem)
  6125 %{
  6147 %{
  6126   match(Set dst (LoadI mem));
  6148   match(Set dst (LoadI mem));
  6127 
  6149 
  6128   ins_cost(125); // XXX
  6150   ins_cost(125);
  6129   format %{ "movl    $dst, $mem\t# int" %}
  6151   format %{ "movl    $dst, $mem\t# int" %}
  6130   opcode(0x8B);
  6152 
  6131   ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
  6153   ins_encode %{
       
  6154     __ movl($dst$$Register, $mem$$Address);
       
  6155   %}
       
  6156 
       
  6157   ins_pipe(ialu_reg_mem);
       
  6158 %}
       
  6159 
       
  6160 // Load Integer into Long Register
       
  6161 instruct loadI2L(rRegL dst, memory mem)
       
  6162 %{
       
  6163   match(Set dst (ConvI2L (LoadI mem)));
       
  6164 
       
  6165   ins_cost(125);
       
  6166   format %{ "movslq  $dst, $mem\t# int -> long" %}
       
  6167 
       
  6168   ins_encode %{
       
  6169     __ movslq($dst$$Register, $mem$$Address);
       
  6170   %}
       
  6171 
       
  6172   ins_pipe(ialu_reg_mem);
       
  6173 %}
       
  6174 
       
  6175 // Load Unsigned Integer into Long Register
       
  6176 instruct loadUI2L(rRegL dst, memory mem)
       
  6177 %{
       
  6178   match(Set dst (LoadUI2L mem));
       
  6179 
       
  6180   ins_cost(125);
       
  6181   format %{ "movl    $dst, $mem\t# uint -> long" %}
       
  6182 
       
  6183   ins_encode %{
       
  6184     __ movl($dst$$Register, $mem$$Address);
       
  6185   %}
       
  6186 
  6132   ins_pipe(ialu_reg_mem);
  6187   ins_pipe(ialu_reg_mem);
  6133 %}
  6188 %}
  6134 
  6189 
  6135 // Load Long
  6190 // Load Long
  6136 instruct loadL(rRegL dst, memory mem)
  6191 instruct loadL(rRegL dst, memory mem)
  6137 %{
  6192 %{
  6138   match(Set dst (LoadL mem));
  6193   match(Set dst (LoadL mem));
  6139 
  6194 
  6140   ins_cost(125); // XXX
  6195   ins_cost(125);
  6141   format %{ "movq    $dst, $mem\t# long" %}
  6196   format %{ "movq    $dst, $mem\t# long" %}
  6142   opcode(0x8B);
  6197 
  6143   ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
  6198   ins_encode %{
       
  6199     __ movq($dst$$Register, $mem$$Address);
       
  6200   %}
       
  6201 
  6144   ins_pipe(ialu_reg_mem); // XXX
  6202   ins_pipe(ialu_reg_mem); // XXX
  6145 %}
  6203 %}
  6146 
  6204 
  6147 // Load Range
  6205 // Load Range
  6148 instruct loadRange(rRegI dst, memory mem)
  6206 instruct loadRange(rRegI dst, memory mem)
  8361 %}
  8419 %}
  8362 
  8420 
  8363 //----------- DivL-By-Constant-Expansions--------------------------------------
  8421 //----------- DivL-By-Constant-Expansions--------------------------------------
  8364 // DivI cases are handled by the compiler
  8422 // DivI cases are handled by the compiler
  8365 
  8423 
  8366 // Magic constant, reciprical of 10
  8424 // Magic constant, reciprocal of 10
  8367 instruct loadConL_0x6666666666666667(rRegL dst)
  8425 instruct loadConL_0x6666666666666667(rRegL dst)
  8368 %{
  8426 %{
  8369   effect(DEF dst);
  8427   effect(DEF dst);
  8370 
  8428 
  8371   format %{ "movq    $dst, #0x666666666666667\t# Used in div-by-10" %}
  8429   format %{ "movq    $dst, #0x666666666666667\t# Used in div-by-10" %}
 10801 //   ins_encode(enc_copy(dst, src));
 10859 //   ins_encode(enc_copy(dst, src));
 10802 // //   opcode(0x63); // needs REX.W
 10860 // //   opcode(0x63); // needs REX.W
 10803 // //   ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
 10861 // //   ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
 10804 //   ins_pipe(ialu_reg_reg);
 10862 //   ins_pipe(ialu_reg_reg);
 10805 // %}
 10863 // %}
 10806 
       
 10807 instruct convI2L_reg_mem(rRegL dst, memory src)
       
 10808 %{
       
 10809   match(Set dst (ConvI2L (LoadI src)));
       
 10810 
       
 10811   format %{ "movslq  $dst, $src\t# i2l" %}
       
 10812   opcode(0x63); // needs REX.W
       
 10813   ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst,src));
       
 10814   ins_pipe(ialu_reg_mem);
       
 10815 %}
       
 10816 
 10864 
 10817 // Zero-extend convert int to long
 10865 // Zero-extend convert int to long
 10818 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
 10866 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
 10819 %{
 10867 %{
 10820   match(Set dst (AndL (ConvI2L src) mask));
 10868   match(Set dst (AndL (ConvI2L src) mask));
 12080 
 12128 
 12081 //----------PEEPHOLE RULES-----------------------------------------------------
 12129 //----------PEEPHOLE RULES-----------------------------------------------------
 12082 // These must follow all instruction definitions as they use the names
 12130 // These must follow all instruction definitions as they use the names
 12083 // defined in the instructions definitions.
 12131 // defined in the instructions definitions.
 12084 //
 12132 //
 12085 // peepmatch ( root_instr_name [precerding_instruction]* );
 12133 // peepmatch ( root_instr_name [preceding_instruction]* );
 12086 //
 12134 //
 12087 // peepconstraint %{
 12135 // peepconstraint %{
 12088 // (instruction_number.operand_name relational_op instruction_number.operand_name
 12136 // (instruction_number.operand_name relational_op instruction_number.operand_name
 12089 //  [, ...] );
 12137 //  [, ...] );
 12090 // // instruction numbers are zero-based using left to right order in peepmatch
 12138 // // instruction numbers are zero-based using left to right order in peepmatch