comparison src/cpu/x86/vm/x86_32.ad @ 17729:8a8ff6b577ed

8031321: Support Intel bit manipulation instructions Summary: Add support for BMI1 instructions Reviewed-by: kvn, roland
author iveresov
date Wed, 12 Mar 2014 11:24:26 -0700
parents 085b304a1cc5
children 606acabe7b5c
comparison
equal deleted inserted replaced
17727:cfd4aac53239 17729:8a8ff6b577ed
5153 %} 5153 %}
5154 ins_pipe(ialu_reg); 5154 ins_pipe(ialu_reg);
5155 %} 5155 %}
5156 5156
5157 instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{ 5157 instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
5158 predicate(UseCountTrailingZerosInstruction);
5159 match(Set dst (CountTrailingZerosI src));
5160 effect(KILL cr);
5161
5162 format %{ "TZCNT $dst, $src\t# count trailing zeros (int)" %}
5163 ins_encode %{
5164 __ tzcntl($dst$$Register, $src$$Register);
5165 %}
5166 ins_pipe(ialu_reg);
5167 %}
5168
5169 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, eFlagsReg cr) %{
5170 predicate(!UseCountTrailingZerosInstruction);
5158 match(Set dst (CountTrailingZerosI src)); 5171 match(Set dst (CountTrailingZerosI src));
5159 effect(KILL cr); 5172 effect(KILL cr);
5160 5173
5161 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t" 5174 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t"
5162 "JNZ done\n\t" 5175 "JNZ done\n\t"
5172 %} 5185 %}
5173 ins_pipe(ialu_reg); 5186 ins_pipe(ialu_reg);
5174 %} 5187 %}
5175 5188
5176 instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{ 5189 instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
5190 predicate(UseCountTrailingZerosInstruction);
5191 match(Set dst (CountTrailingZerosL src));
5192 effect(TEMP dst, KILL cr);
5193
5194 format %{ "TZCNT $dst, $src.lo\t# count trailing zeros (long) \n\t"
5195 "JNC done\n\t"
5196 "TZCNT $dst, $src.hi\n\t"
5197 "ADD $dst, 32\n"
5198 "done:" %}
5199 ins_encode %{
5200 Register Rdst = $dst$$Register;
5201 Register Rsrc = $src$$Register;
5202 Label done;
5203 __ tzcntl(Rdst, Rsrc);
5204 __ jccb(Assembler::carryClear, done);
5205 __ tzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
5206 __ addl(Rdst, BitsPerInt);
5207 __ bind(done);
5208 %}
5209 ins_pipe(ialu_reg);
5210 %}
5211
5212 instruct countTrailingZerosL_bsf(rRegI dst, eRegL src, eFlagsReg cr) %{
5213 predicate(!UseCountTrailingZerosInstruction);
5177 match(Set dst (CountTrailingZerosL src)); 5214 match(Set dst (CountTrailingZerosL src));
5178 effect(TEMP dst, KILL cr); 5215 effect(TEMP dst, KILL cr);
5179 5216
5180 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t" 5217 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t"
5181 "JNZ done\n\t" 5218 "JNZ done\n\t"
8015 // ins_encode( MemImm( dst, src) ); 8052 // ins_encode( MemImm( dst, src) );
8016 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 8053 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8017 ins_pipe( ialu_mem_imm ); 8054 ins_pipe( ialu_mem_imm );
8018 %} 8055 %}
8019 8056
8057 // BMI1 instructions
8058 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, eFlagsReg cr) %{
8059 match(Set dst (AndI (XorI src1 minus_1) src2));
8060 predicate(UseBMI1Instructions);
8061 effect(KILL cr);
8062
8063 format %{ "ANDNL $dst, $src1, $src2" %}
8064
8065 ins_encode %{
8066 __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
8067 %}
8068 ins_pipe(ialu_reg);
8069 %}
8070
8071 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, eFlagsReg cr) %{
8072 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2) ));
8073 predicate(UseBMI1Instructions);
8074 effect(KILL cr);
8075
8076 ins_cost(125);
8077 format %{ "ANDNL $dst, $src1, $src2" %}
8078
8079 ins_encode %{
8080 __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
8081 %}
8082 ins_pipe(ialu_reg_mem);
8083 %}
8084
8085 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, eFlagsReg cr) %{
8086 match(Set dst (AndI (SubI imm_zero src) src));
8087 predicate(UseBMI1Instructions);
8088 effect(KILL cr);
8089
8090 format %{ "BLSIL $dst, $src" %}
8091
8092 ins_encode %{
8093 __ blsil($dst$$Register, $src$$Register);
8094 %}
8095 ins_pipe(ialu_reg);
8096 %}
8097
8098 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, eFlagsReg cr) %{
8099 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
8100 predicate(UseBMI1Instructions);
8101 effect(KILL cr);
8102
8103 ins_cost(125);
8104 format %{ "BLSIL $dst, $src" %}
8105
8106 ins_encode %{
8107 __ blsil($dst$$Register, $src$$Address);
8108 %}
8109 ins_pipe(ialu_reg_mem);
8110 %}
8111
8112 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, eFlagsReg cr)
8113 %{
8114 match(Set dst (XorI (AddI src minus_1) src));
8115 predicate(UseBMI1Instructions);
8116 effect(KILL cr);
8117
8118 format %{ "BLSMSKL $dst, $src" %}
8119
8120 ins_encode %{
8121 __ blsmskl($dst$$Register, $src$$Register);
8122 %}
8123
8124 ins_pipe(ialu_reg);
8125 %}
8126
8127 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, eFlagsReg cr)
8128 %{
8129 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ));
8130 predicate(UseBMI1Instructions);
8131 effect(KILL cr);
8132
8133 ins_cost(125);
8134 format %{ "BLSMSKL $dst, $src" %}
8135
8136 ins_encode %{
8137 __ blsmskl($dst$$Register, $src$$Address);
8138 %}
8139
8140 ins_pipe(ialu_reg_mem);
8141 %}
8142
8143 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, eFlagsReg cr)
8144 %{
8145 match(Set dst (AndI (AddI src minus_1) src) );
8146 predicate(UseBMI1Instructions);
8147 effect(KILL cr);
8148
8149 format %{ "BLSRL $dst, $src" %}
8150
8151 ins_encode %{
8152 __ blsrl($dst$$Register, $src$$Register);
8153 %}
8154
8155 ins_pipe(ialu_reg);
8156 %}
8157
8158 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, eFlagsReg cr)
8159 %{
8160 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ));
8161 predicate(UseBMI1Instructions);
8162 effect(KILL cr);
8163
8164 ins_cost(125);
8165 format %{ "BLSRL $dst, $src" %}
8166
8167 ins_encode %{
8168 __ blsrl($dst$$Register, $src$$Address);
8169 %}
8170
8171 ins_pipe(ialu_reg_mem);
8172 %}
8173
8020 // Or Instructions 8174 // Or Instructions
8021 // Or Register with Register 8175 // Or Register with Register
8022 instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 8176 instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
8023 match(Set dst (OrI dst src)); 8177 match(Set dst (OrI dst src));
8024 effect(KILL cr); 8178 effect(KILL cr);
8635 format %{ "AND $dst.lo,$mem\n\t" 8789 format %{ "AND $dst.lo,$mem\n\t"
8636 "AND $dst.hi,$mem+4" %} 8790 "AND $dst.hi,$mem+4" %}
8637 opcode(0x23, 0x23); 8791 opcode(0x23, 0x23);
8638 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 8792 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) );
8639 ins_pipe( ialu_reg_long_mem ); 8793 ins_pipe( ialu_reg_long_mem );
8794 %}
8795
8796 // BMI1 instructions
8797 instruct andnL_eReg_eReg_eReg(eRegL dst, eRegL src1, eRegL src2, immL_M1 minus_1, eFlagsReg cr) %{
8798 match(Set dst (AndL (XorL src1 minus_1) src2));
8799 predicate(UseBMI1Instructions);
8800 effect(KILL cr, TEMP dst);
8801
8802 format %{ "ANDNL $dst.lo, $src1.lo, $src2.lo\n\t"
8803 "ANDNL $dst.hi, $src1.hi, $src2.hi"
8804 %}
8805
8806 ins_encode %{
8807 Register Rdst = $dst$$Register;
8808 Register Rsrc1 = $src1$$Register;
8809 Register Rsrc2 = $src2$$Register;
8810 __ andnl(Rdst, Rsrc1, Rsrc2);
8811 __ andnl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc1), HIGH_FROM_LOW(Rsrc2));
8812 %}
8813 ins_pipe(ialu_reg_reg_long);
8814 %}
8815
8816 instruct andnL_eReg_eReg_mem(eRegL dst, eRegL src1, memory src2, immL_M1 minus_1, eFlagsReg cr) %{
8817 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2) ));
8818 predicate(UseBMI1Instructions);
8819 effect(KILL cr, TEMP dst);
8820
8821 ins_cost(125);
8822 format %{ "ANDNL $dst.lo, $src1.lo, $src2\n\t"
8823 "ANDNL $dst.hi, $src1.hi, $src2+4"
8824 %}
8825
8826 ins_encode %{
8827 Register Rdst = $dst$$Register;
8828 Register Rsrc1 = $src1$$Register;
8829 Address src2_hi = Address::make_raw($src2$$base, $src2$$index, $src2$$scale, $src2$$disp + 4, relocInfo::none);
8830
8831 __ andnl(Rdst, Rsrc1, $src2$$Address);
8832 __ andnl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc1), src2_hi);
8833 %}
8834 ins_pipe(ialu_reg_mem);
8835 %}
8836
8837 instruct blsiL_eReg_eReg(eRegL dst, eRegL src, immL0 imm_zero, eFlagsReg cr) %{
8838 match(Set dst (AndL (SubL imm_zero src) src));
8839 predicate(UseBMI1Instructions);
8840 effect(KILL cr, TEMP dst);
8841
8842 format %{ "MOVL $dst.hi, 0\n\t"
8843 "BLSIL $dst.lo, $src.lo\n\t"
8844 "JNZ done\n\t"
8845 "BLSIL $dst.hi, $src.hi\n"
8846 "done:"
8847 %}
8848
8849 ins_encode %{
8850 Label done;
8851 Register Rdst = $dst$$Register;
8852 Register Rsrc = $src$$Register;
8853 __ movl(HIGH_FROM_LOW(Rdst), 0);
8854 __ blsil(Rdst, Rsrc);
8855 __ jccb(Assembler::notZero, done);
8856 __ blsil(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
8857 __ bind(done);
8858 %}
8859 ins_pipe(ialu_reg);
8860 %}
8861
8862 instruct blsiL_eReg_mem(eRegL dst, memory src, immL0 imm_zero, eFlagsReg cr) %{
8863 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
8864 predicate(UseBMI1Instructions);
8865 effect(KILL cr, TEMP dst);
8866
8867 ins_cost(125);
8868 format %{ "MOVL $dst.hi, 0\n\t"
8869 "BLSIL $dst.lo, $src\n\t"
8870 "JNZ done\n\t"
8871 "BLSIL $dst.hi, $src+4\n"
8872 "done:"
8873 %}
8874
8875 ins_encode %{
8876 Label done;
8877 Register Rdst = $dst$$Register;
8878 Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
8879
8880 __ movl(HIGH_FROM_LOW(Rdst), 0);
8881 __ blsil(Rdst, $src$$Address);
8882 __ jccb(Assembler::notZero, done);
8883 __ blsil(HIGH_FROM_LOW(Rdst), src_hi);
8884 __ bind(done);
8885 %}
8886 ins_pipe(ialu_reg_mem);
8887 %}
8888
8889 instruct blsmskL_eReg_eReg(eRegL dst, eRegL src, immL_M1 minus_1, eFlagsReg cr)
8890 %{
8891 match(Set dst (XorL (AddL src minus_1) src));
8892 predicate(UseBMI1Instructions);
8893 effect(KILL cr, TEMP dst);
8894
8895 format %{ "MOVL $dst.hi, 0\n\t"
8896 "BLSMSKL $dst.lo, $src.lo\n\t"
8897 "JNC done\n\t"
8898 "BLSMSKL $dst.hi, $src.hi\n"
8899 "done:"
8900 %}
8901
8902 ins_encode %{
8903 Label done;
8904 Register Rdst = $dst$$Register;
8905 Register Rsrc = $src$$Register;
8906 __ movl(HIGH_FROM_LOW(Rdst), 0);
8907 __ blsmskl(Rdst, Rsrc);
8908 __ jccb(Assembler::carryClear, done);
8909 __ blsmskl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
8910 __ bind(done);
8911 %}
8912
8913 ins_pipe(ialu_reg);
8914 %}
8915
8916 instruct blsmskL_eReg_mem(eRegL dst, memory src, immL_M1 minus_1, eFlagsReg cr)
8917 %{
8918 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ));
8919 predicate(UseBMI1Instructions);
8920 effect(KILL cr, TEMP dst);
8921
8922 ins_cost(125);
8923 format %{ "MOVL $dst.hi, 0\n\t"
8924 "BLSMSKL $dst.lo, $src\n\t"
8925 "JNC done\n\t"
8926 "BLSMSKL $dst.hi, $src+4\n"
8927 "done:"
8928 %}
8929
8930 ins_encode %{
8931 Label done;
8932 Register Rdst = $dst$$Register;
8933 Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
8934
8935 __ movl(HIGH_FROM_LOW(Rdst), 0);
8936 __ blsmskl(Rdst, $src$$Address);
8937 __ jccb(Assembler::carryClear, done);
8938 __ blsmskl(HIGH_FROM_LOW(Rdst), src_hi);
8939 __ bind(done);
8940 %}
8941
8942 ins_pipe(ialu_reg_mem);
8943 %}
8944
8945 instruct blsrL_eReg_eReg(eRegL dst, eRegL src, immL_M1 minus_1, eFlagsReg cr)
8946 %{
8947 match(Set dst (AndL (AddL src minus_1) src) );
8948 predicate(UseBMI1Instructions);
8949 effect(KILL cr, TEMP dst);
8950
8951 format %{ "MOVL $dst.hi, $src.hi\n\t"
8952 "BLSRL $dst.lo, $src.lo\n\t"
8953 "JNC done\n\t"
8954 "BLSRL $dst.hi, $src.hi\n"
8955 "done:"
8956 %}
8957
8958 ins_encode %{
8959 Label done;
8960 Register Rdst = $dst$$Register;
8961 Register Rsrc = $src$$Register;
8962 __ movl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
8963 __ blsrl(Rdst, Rsrc);
8964 __ jccb(Assembler::carryClear, done);
8965 __ blsrl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
8966 __ bind(done);
8967 %}
8968
8969 ins_pipe(ialu_reg);
8970 %}
8971
8972 instruct blsrL_eReg_mem(eRegL dst, memory src, immL_M1 minus_1, eFlagsReg cr)
8973 %{
8974 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src) ));
8975 predicate(UseBMI1Instructions);
8976 effect(KILL cr, TEMP dst);
8977
8978 ins_cost(125);
8979 format %{ "MOVL $dst.hi, $src+4\n\t"
8980 "BLSRL $dst.lo, $src\n\t"
8981 "JNC done\n\t"
8982 "BLSRL $dst.hi, $src+4\n"
8983 "done:"
8984 %}
8985
8986 ins_encode %{
8987 Label done;
8988 Register Rdst = $dst$$Register;
8989 Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
8990 __ movl(HIGH_FROM_LOW(Rdst), src_hi);
8991 __ blsrl(Rdst, $src$$Address);
8992 __ jccb(Assembler::carryClear, done);
8993 __ blsrl(HIGH_FROM_LOW(Rdst), src_hi);
8994 __ bind(done);
8995 %}
8996
8997 ins_pipe(ialu_reg_mem);
8640 %} 8998 %}
8641 8999
8642 // Or Long Register with Register 9000 // Or Long Register with Register
8643 instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9001 instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
8644 match(Set dst (OrL dst src)); 9002 match(Set dst (OrL dst src));