--- old/src/cpu/x86/vm/x86_32.ad 2009-04-22 20:27:24.165389448 +0200 +++ new/src/cpu/x86/vm/x86_32.ad 2009-04-22 20:27:24.033513041 +0200 @@ -1281,6 +1281,13 @@ } +const bool Matcher::match_rule_supported(int opcode) { + if (!has_match_rule(opcode)) + return false; + + return true; // Per default match rules are supported. +} + int Matcher::regnum_to_fpu_offset(int regnum) { return regnum - 32; // The FP registers are in the second chunk } @@ -6644,6 +6651,156 @@ %} +//---------- Zeros Count Instructions ------------------------------------------ + +instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{ + predicate(UseCountLeadingZerosInstruction); + match(Set dst (CountLeadingZerosI src)); + effect(KILL cr); + + format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %} + ins_encode %{ + __ lzcntl($dst$$Register, $src$$Register); + %} + ins_pipe(ialu_reg); +%} + +instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eRegI tmp, eFlagsReg cr) %{ + predicate(!UseCountLeadingZerosInstruction); + match(Set dst (CountLeadingZerosI src)); + effect(TEMP dst, TEMP tmp, KILL cr); + + format %{ "BSR $tmp, $src\t# count leading zeros (int)\n\t" + "JNZ skip\n\t" + "MOV $tmp, -1\n" + "skip:\n\t" + "MOV $dst, 31\n\t" + "SUB $dst, $tmp" %} + ins_encode %{ + Label skip; + __ bsrl($tmp$$Register, $src$$Register); + __ jccb(Assembler::notZero, skip); + __ movl($tmp$$Register, -1); + __ bind(skip); + __ movl($dst$$Register, BitsPerInt - 1); + __ subl($dst$$Register, $tmp$$Register); + %} + ins_pipe(ialu_reg); +%} + +instruct countLeadingZerosL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ + predicate(UseCountLeadingZerosInstruction); + match(Set dst (CountLeadingZerosL src)); + effect(TEMP dst, TEMP tmp, KILL cr); + + format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t" + "JNC done\n\t" + "LZCNT $tmp, $src.lo\n\t" + "ADD $dst, $tmp\n" + "done:" %} + ins_encode %{ + Register Rdst = $dst$$Register; + Register Rsrc = $src$$Register; + Register Rtmp = $tmp$$Register; + Label done; + __ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc)); + __ jccb(Assembler::carryClear, done); + __ lzcntl(Rtmp, Rsrc); + __ addl(Rdst, Rtmp); + __ bind(done); + %} + ins_pipe(ialu_reg); +%} + +instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ + predicate(!UseCountLeadingZerosInstruction); + match(Set dst (CountLeadingZerosL src)); + effect(TEMP dst, TEMP tmp, KILL cr); + + format %{ "BSR $tmp, $src.hi\t# count leading zeros (long)\n\t" + "JZ msw_is_zero\n\t" + "MOV $dst, 31\n\t" + "SUB $dst, $tmp\n\t" + "JMP done\n" + "msw_is_zero:\n\t" + "BSR $tmp, $src.lo\n\t" + "JNZ lsw_is_not_zero\n\t" + "MOV $tmp, -1\n" + "lsw_is_not_zero:\n\t" + "MOV $dst, 63\n\t" + "SUB $dst, $tmp\n" + "done:" %} + ins_encode %{ + Register Rdst = $dst$$Register; + Register Rsrc = $src$$Register; + Register Rtmp = $tmp$$Register; + Label msw_is_zero; + Label lsw_is_not_zero; + Label done; + __ bsrl(Rtmp, HIGH_FROM_LOW(Rsrc)); + __ jccb(Assembler::zero, msw_is_zero); + __ movl(Rdst, BitsPerLong - 1 - BitsPerInt); // Subtract 32 bit positions for LSW + __ subl(Rdst, Rtmp); + __ jmpb(done); + __ bind(msw_is_zero); + __ bsrl(Rtmp, Rsrc); + __ jccb(Assembler::notZero, lsw_is_not_zero); + __ movl(Rtmp, -1); + __ bind(lsw_is_not_zero); + __ movl(Rdst, BitsPerLong - 1); + __ subl(Rdst, Rtmp); + __ bind(done); + + %} + ins_pipe(ialu_reg); +%} + +instruct countTrailingZerosI(eRegI dst, eRegI src, eRegI tmp, eFlagsReg cr) %{ + match(Set dst (CountTrailingZerosI src)); + effect(TEMP tmp, KILL cr); + + format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t" + "JNZ done\n\t" + "MOV $dst, 32\n" + "done:" %} + ins_encode %{ + Label done; + __ bsfl($dst$$Register, $src$$Register); + __ jccb(Assembler::notZero, done); + __ movl($dst$$Register, BitsPerInt); + __ bind(done); + %} + ins_pipe(ialu_reg); +%} + +instruct countTrailingZerosL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ + match(Set dst (CountTrailingZerosL src)); + effect(TEMP dst, TEMP tmp, KILL cr); + + format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t" + "JNZ done\n\t" + "BSF $tmp, $src.hi\n\t" + "MOV $dst, 32\n\t" + "CMOVZ $tmp, $dst\n\t" + "ADD $dst, $tmp\n" + "done:" %} + ins_encode %{ + Register Rdst = $dst$$Register; + Register Rsrc = $src$$Register; + Register Rtmp = $tmp$$Register; + Label done; + __ bsfl(Rdst, Rsrc); + __ jccb(Assembler::notZero, done); + __ bsfl(Rtmp, HIGH_FROM_LOW(Rsrc)); + __ movl(Rdst, BitsPerInt); + __ cmovl(Assembler::zero, Rtmp, Rdst); + __ addl(Rdst, Rtmp); + __ bind(done); + %} + ins_pipe(ialu_reg); +%} + + //---------- Population Count Instructions ------------------------------------- instruct popCountI(eRegI dst, eRegI src) %{