--- a/hotspot/src/cpu/x86/vm/x86_32.ad Tue Mar 11 14:54:47 2014 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Mar 12 11:24:26 2014 -0700
@@ -5163,6 +5163,19 @@
%}
instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
+ predicate(UseCountTrailingZerosInstruction);
+ match(Set dst (CountTrailingZerosI src));
+ effect(KILL cr);
+
+ format %{ "TZCNT $dst, $src\t# count trailing zeros (int)" %}
+ ins_encode %{
+ __ tzcntl($dst$$Register, $src$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, eFlagsReg cr) %{
+ predicate(!UseCountTrailingZerosInstruction);
match(Set dst (CountTrailingZerosI src));
effect(KILL cr);
@@ -5182,6 +5195,30 @@
%}
instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
+ predicate(UseCountTrailingZerosInstruction);
+ match(Set dst (CountTrailingZerosL src));
+ effect(TEMP dst, KILL cr);
+
+ format %{ "TZCNT $dst, $src.lo\t# count trailing zeros (long) \n\t"
+ "JNC done\n\t"
+ "TZCNT $dst, $src.hi\n\t"
+ "ADD $dst, 32\n"
+ "done:" %}
+ ins_encode %{
+ Register Rdst = $dst$$Register;
+ Register Rsrc = $src$$Register;
+ Label done;
+ __ tzcntl(Rdst, Rsrc);
+ __ jccb(Assembler::carryClear, done);
+ __ tzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
+ __ addl(Rdst, BitsPerInt);
+ __ bind(done);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct countTrailingZerosL_bsf(rRegI dst, eRegL src, eFlagsReg cr) %{
+ predicate(!UseCountTrailingZerosInstruction);
match(Set dst (CountTrailingZerosL src));
effect(TEMP dst, KILL cr);
@@ -8027,6 +8064,123 @@
ins_pipe( ialu_mem_imm );
%}
+// BMI1 instructions
+instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, eFlagsReg cr) %{
+ match(Set dst (AndI (XorI src1 minus_1) src2));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ format %{ "ANDNL $dst, $src1, $src2" %}
+
+ ins_encode %{
+ __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, eFlagsReg cr) %{
+ match(Set dst (AndI (XorI src1 minus_1) (LoadI src2) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ ins_cost(125);
+ format %{ "ANDNL $dst, $src1, $src2" %}
+
+ ins_encode %{
+ __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
+ %}
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, eFlagsReg cr) %{
+ match(Set dst (AndI (SubI imm_zero src) src));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ format %{ "BLSIL $dst, $src" %}
+
+ ins_encode %{
+ __ blsil($dst$$Register, $src$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, eFlagsReg cr) %{
+ match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ ins_cost(125);
+ format %{ "BLSIL $dst, $src" %}
+
+ ins_encode %{
+ __ blsil($dst$$Register, $src$$Address);
+ %}
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (XorI (AddI src minus_1) src));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ format %{ "BLSMSKL $dst, $src" %}
+
+ ins_encode %{
+ __ blsmskl($dst$$Register, $src$$Register);
+ %}
+
+ ins_pipe(ialu_reg);
+%}
+
+instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ ins_cost(125);
+ format %{ "BLSMSKL $dst, $src" %}
+
+ ins_encode %{
+ __ blsmskl($dst$$Register, $src$$Address);
+ %}
+
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (AndI (AddI src minus_1) src) );
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ format %{ "BLSRL $dst, $src" %}
+
+ ins_encode %{
+ __ blsrl($dst$$Register, $src$$Register);
+ %}
+
+ ins_pipe(ialu_reg);
+%}
+
+instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr);
+
+ ins_cost(125);
+ format %{ "BLSRL $dst, $src" %}
+
+ ins_encode %{
+ __ blsrl($dst$$Register, $src$$Address);
+ %}
+
+ ins_pipe(ialu_reg_mem);
+%}
+
// Or Instructions
// Or Register with Register
instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
@@ -8649,6 +8803,210 @@
ins_pipe( ialu_reg_long_mem );
%}
+// BMI1 instructions
+instruct andnL_eReg_eReg_eReg(eRegL dst, eRegL src1, eRegL src2, immL_M1 minus_1, eFlagsReg cr) %{
+ match(Set dst (AndL (XorL src1 minus_1) src2));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ format %{ "ANDNL $dst.lo, $src1.lo, $src2.lo\n\t"
+ "ANDNL $dst.hi, $src1.hi, $src2.hi"
+ %}
+
+ ins_encode %{
+ Register Rdst = $dst$$Register;
+ Register Rsrc1 = $src1$$Register;
+ Register Rsrc2 = $src2$$Register;
+ __ andnl(Rdst, Rsrc1, Rsrc2);
+ __ andnl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc1), HIGH_FROM_LOW(Rsrc2));
+ %}
+ ins_pipe(ialu_reg_reg_long);
+%}
+
+instruct andnL_eReg_eReg_mem(eRegL dst, eRegL src1, memory src2, immL_M1 minus_1, eFlagsReg cr) %{
+ match(Set dst (AndL (XorL src1 minus_1) (LoadL src2) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ ins_cost(125);
+ format %{ "ANDNL $dst.lo, $src1.lo, $src2\n\t"
+ "ANDNL $dst.hi, $src1.hi, $src2+4"
+ %}
+
+ ins_encode %{
+ Register Rdst = $dst$$Register;
+ Register Rsrc1 = $src1$$Register;
+ Address src2_hi = Address::make_raw($src2$$base, $src2$$index, $src2$$scale, $src2$$disp + 4, relocInfo::none);
+
+ __ andnl(Rdst, Rsrc1, $src2$$Address);
+ __ andnl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc1), src2_hi);
+ %}
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsiL_eReg_eReg(eRegL dst, eRegL src, immL0 imm_zero, eFlagsReg cr) %{
+ match(Set dst (AndL (SubL imm_zero src) src));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ format %{ "MOVL $dst.hi, 0\n\t"
+ "BLSIL $dst.lo, $src.lo\n\t"
+ "JNZ done\n\t"
+ "BLSIL $dst.hi, $src.hi\n"
+ "done:"
+ %}
+
+ ins_encode %{
+ Label done;
+ Register Rdst = $dst$$Register;
+ Register Rsrc = $src$$Register;
+ __ movl(HIGH_FROM_LOW(Rdst), 0);
+ __ blsil(Rdst, Rsrc);
+ __ jccb(Assembler::notZero, done);
+ __ blsil(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+ __ bind(done);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct blsiL_eReg_mem(eRegL dst, memory src, immL0 imm_zero, eFlagsReg cr) %{
+ match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ ins_cost(125);
+ format %{ "MOVL $dst.hi, 0\n\t"
+ "BLSIL $dst.lo, $src\n\t"
+ "JNZ done\n\t"
+ "BLSIL $dst.hi, $src+4\n"
+ "done:"
+ %}
+
+ ins_encode %{
+ Label done;
+ Register Rdst = $dst$$Register;
+ Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
+
+ __ movl(HIGH_FROM_LOW(Rdst), 0);
+ __ blsil(Rdst, $src$$Address);
+ __ jccb(Assembler::notZero, done);
+ __ blsil(HIGH_FROM_LOW(Rdst), src_hi);
+ __ bind(done);
+ %}
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskL_eReg_eReg(eRegL dst, eRegL src, immL_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (XorL (AddL src minus_1) src));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ format %{ "MOVL $dst.hi, 0\n\t"
+ "BLSMSKL $dst.lo, $src.lo\n\t"
+ "JNC done\n\t"
+ "BLSMSKL $dst.hi, $src.hi\n"
+ "done:"
+ %}
+
+ ins_encode %{
+ Label done;
+ Register Rdst = $dst$$Register;
+ Register Rsrc = $src$$Register;
+ __ movl(HIGH_FROM_LOW(Rdst), 0);
+ __ blsmskl(Rdst, Rsrc);
+ __ jccb(Assembler::carryClear, done);
+ __ blsmskl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+ __ bind(done);
+ %}
+
+ ins_pipe(ialu_reg);
+%}
+
+instruct blsmskL_eReg_mem(eRegL dst, memory src, immL_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ ins_cost(125);
+ format %{ "MOVL $dst.hi, 0\n\t"
+ "BLSMSKL $dst.lo, $src\n\t"
+ "JNC done\n\t"
+ "BLSMSKL $dst.hi, $src+4\n"
+ "done:"
+ %}
+
+ ins_encode %{
+ Label done;
+ Register Rdst = $dst$$Register;
+ Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
+
+ __ movl(HIGH_FROM_LOW(Rdst), 0);
+ __ blsmskl(Rdst, $src$$Address);
+ __ jccb(Assembler::carryClear, done);
+ __ blsmskl(HIGH_FROM_LOW(Rdst), src_hi);
+ __ bind(done);
+ %}
+
+ ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsrL_eReg_eReg(eRegL dst, eRegL src, immL_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (AndL (AddL src minus_1) src) );
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ format %{ "MOVL $dst.hi, $src.hi\n\t"
+ "BLSRL $dst.lo, $src.lo\n\t"
+ "JNC done\n\t"
+ "BLSRL $dst.hi, $src.hi\n"
+ "done:"
+ %}
+
+ ins_encode %{
+ Label done;
+ Register Rdst = $dst$$Register;
+ Register Rsrc = $src$$Register;
+ __ movl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+ __ blsrl(Rdst, Rsrc);
+ __ jccb(Assembler::carryClear, done);
+ __ blsrl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+ __ bind(done);
+ %}
+
+ ins_pipe(ialu_reg);
+%}
+
+instruct blsrL_eReg_mem(eRegL dst, memory src, immL_M1 minus_1, eFlagsReg cr)
+%{
+ match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src) ));
+ predicate(UseBMI1Instructions);
+ effect(KILL cr, TEMP dst);
+
+ ins_cost(125);
+ format %{ "MOVL $dst.hi, $src+4\n\t"
+ "BLSRL $dst.lo, $src\n\t"
+ "JNC done\n\t"
+ "BLSRL $dst.hi, $src+4\n"
+ "done:"
+ %}
+
+ ins_encode %{
+ Label done;
+ Register Rdst = $dst$$Register;
+ Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
+ __ movl(HIGH_FROM_LOW(Rdst), src_hi);
+ __ blsrl(Rdst, $src$$Address);
+ __ jccb(Assembler::carryClear, done);
+ __ blsrl(HIGH_FROM_LOW(Rdst), src_hi);
+ __ bind(done);
+ %}
+
+ ins_pipe(ialu_reg_mem);
+%}
+
// Or Long Register with Register
instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
match(Set dst (OrL dst src));