Mercurial > hg > graal-compiler
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)); |