comparison src/cpu/sparc/vm/sparc.ad @ 775:93c14e5562c4

6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}() Summary: These methods can be instrinsified by using bit scan, bit test, and population count instructions. Reviewed-by: kvn, never
author twisti
date Wed, 06 May 2009 00:27:52 -0700
parents fb4c18a2ec66
children 2056494941db
comparison
equal deleted inserted replaced
755:36ee9b69616e 775:93c14e5562c4
1708 // Given a register encoding, produce a double-precision Float Register object 1708 // Given a register encoding, produce a double-precision Float Register object
1709 static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) { 1709 static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) {
1710 assert(F4->encoding(FloatRegisterImpl::D) == R_F4_enc, "right coding"); 1710 assert(F4->encoding(FloatRegisterImpl::D) == R_F4_enc, "right coding");
1711 assert(F32->encoding(FloatRegisterImpl::D) == R_D32_enc, "right coding"); 1711 assert(F32->encoding(FloatRegisterImpl::D) == R_D32_enc, "right coding");
1712 return as_DoubleFloatRegister(register_encoding); 1712 return as_DoubleFloatRegister(register_encoding);
1713 }
1714
1715 const bool Matcher::match_rule_supported(int opcode) {
1716 if (!has_match_rule(opcode))
1717 return false;
1718
1719 switch (opcode) {
1720 case Op_CountLeadingZerosI:
1721 case Op_CountLeadingZerosL:
1722 case Op_CountTrailingZerosI:
1723 case Op_CountTrailingZerosL:
1724 if (!UsePopCountInstruction)
1725 return false;
1726 break;
1727 }
1728
1729 return true; // Per default match rules are supported.
1713 } 1730 }
1714 1731
1715 int Matcher::regnum_to_fpu_offset(int regnum) { 1732 int Matcher::regnum_to_fpu_offset(int regnum) {
1716 return regnum - 32; // The FP registers are in the second chunk 1733 return regnum - 32; // The FP registers are in the second chunk
1717 } 1734 }
9185 ins_cost(300); 9202 ins_cost(300);
9186 format %{ "Array Equals $ary1,$ary2 -> $result" %} 9203 format %{ "Array Equals $ary1,$ary2 -> $result" %}
9187 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result)); 9204 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result));
9188 ins_pipe(long_memory_op); 9205 ins_pipe(long_memory_op);
9189 %} 9206 %}
9207
9208
9209 //---------- Zeros Count Instructions ------------------------------------------
9210
9211 instruct countLeadingZerosI(iRegI dst, iRegI src, iRegI tmp, flagsReg cr) %{
9212 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
9213 match(Set dst (CountLeadingZerosI src));
9214 effect(TEMP dst, TEMP tmp, KILL cr);
9215
9216 // x |= (x >> 1);
9217 // x |= (x >> 2);
9218 // x |= (x >> 4);
9219 // x |= (x >> 8);
9220 // x |= (x >> 16);
9221 // return (WORDBITS - popc(x));
9222 format %{ "SRL $src,1,$dst\t! count leading zeros (int)\n\t"
9223 "OR $src,$tmp,$dst\n\t"
9224 "SRL $dst,2,$tmp\n\t"
9225 "OR $dst,$tmp,$dst\n\t"
9226 "SRL $dst,4,$tmp\n\t"
9227 "OR $dst,$tmp,$dst\n\t"
9228 "SRL $dst,8,$tmp\n\t"
9229 "OR $dst,$tmp,$dst\n\t"
9230 "SRL $dst,16,$tmp\n\t"
9231 "OR $dst,$tmp,$dst\n\t"
9232 "POPC $dst,$dst\n\t"
9233 "MOV 32,$tmp\n\t"
9234 "SUB $tmp,$dst,$dst" %}
9235 ins_encode %{
9236 Register Rdst = $dst$$Register;
9237 Register Rsrc = $src$$Register;
9238 Register Rtmp = $tmp$$Register;
9239 __ srl(Rsrc, 1, Rtmp);
9240 __ or3(Rsrc, Rtmp, Rdst);
9241 __ srl(Rdst, 2, Rtmp);
9242 __ or3(Rdst, Rtmp, Rdst);
9243 __ srl(Rdst, 4, Rtmp);
9244 __ or3(Rdst, Rtmp, Rdst);
9245 __ srl(Rdst, 8, Rtmp);
9246 __ or3(Rdst, Rtmp, Rdst);
9247 __ srl(Rdst, 16, Rtmp);
9248 __ or3(Rdst, Rtmp, Rdst);
9249 __ popc(Rdst, Rdst);
9250 __ mov(BitsPerInt, Rtmp);
9251 __ sub(Rtmp, Rdst, Rdst);
9252 %}
9253 ins_pipe(ialu_reg);
9254 %}
9255
9256 instruct countLeadingZerosL(iRegI dst, iRegL src, iRegL tmp, flagsReg cr) %{
9257 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
9258 match(Set dst (CountLeadingZerosL src));
9259 effect(TEMP dst, TEMP tmp, KILL cr);
9260
9261 // x |= (x >> 1);
9262 // x |= (x >> 2);
9263 // x |= (x >> 4);
9264 // x |= (x >> 8);
9265 // x |= (x >> 16);
9266 // x |= (x >> 32);
9267 // return (WORDBITS - popc(x));
9268 format %{ "SRLX $src,1,$dst\t! count leading zeros (long)\n\t"
9269 "OR $src,$tmp,$dst\n\t"
9270 "SRLX $dst,2,$tmp\n\t"
9271 "OR $dst,$tmp,$dst\n\t"
9272 "SRLX $dst,4,$tmp\n\t"
9273 "OR $dst,$tmp,$dst\n\t"
9274 "SRLX $dst,8,$tmp\n\t"
9275 "OR $dst,$tmp,$dst\n\t"
9276 "SRLX $dst,16,$tmp\n\t"
9277 "OR $dst,$tmp,$dst\n\t"
9278 "SRLX $dst,32,$tmp\n\t"
9279 "OR $dst,$tmp,$dst\n\t"
9280 "POPC $dst,$dst\n\t"
9281 "MOV 64,$tmp\n\t"
9282 "SUB $tmp,$dst,$dst" %}
9283 ins_encode %{
9284 Register Rdst = $dst$$Register;
9285 Register Rsrc = $src$$Register;
9286 Register Rtmp = $tmp$$Register;
9287 __ srlx(Rsrc, 1, Rtmp);
9288 __ or3(Rsrc, Rtmp, Rdst);
9289 __ srlx(Rdst, 2, Rtmp);
9290 __ or3(Rdst, Rtmp, Rdst);
9291 __ srlx(Rdst, 4, Rtmp);
9292 __ or3(Rdst, Rtmp, Rdst);
9293 __ srlx(Rdst, 8, Rtmp);
9294 __ or3(Rdst, Rtmp, Rdst);
9295 __ srlx(Rdst, 16, Rtmp);
9296 __ or3(Rdst, Rtmp, Rdst);
9297 __ srlx(Rdst, 32, Rtmp);
9298 __ or3(Rdst, Rtmp, Rdst);
9299 __ popc(Rdst, Rdst);
9300 __ mov(BitsPerLong, Rtmp);
9301 __ sub(Rtmp, Rdst, Rdst);
9302 %}
9303 ins_pipe(ialu_reg);
9304 %}
9305
9306 instruct countTrailingZerosI(iRegI dst, iRegI src, flagsReg cr) %{
9307 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
9308 match(Set dst (CountTrailingZerosI src));
9309 effect(TEMP dst, KILL cr);
9310
9311 // return popc(~x & (x - 1));
9312 format %{ "SUB $src,1,$dst\t! count trailing zeros (int)\n\t"
9313 "ANDN $dst,$src,$dst\n\t"
9314 "SRL $dst,R_G0,$dst\n\t"
9315 "POPC $dst,$dst" %}
9316 ins_encode %{
9317 Register Rdst = $dst$$Register;
9318 Register Rsrc = $src$$Register;
9319 __ sub(Rsrc, 1, Rdst);
9320 __ andn(Rdst, Rsrc, Rdst);
9321 __ srl(Rdst, G0, Rdst);
9322 __ popc(Rdst, Rdst);
9323 %}
9324 ins_pipe(ialu_reg);
9325 %}
9326
9327 instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{
9328 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
9329 match(Set dst (CountTrailingZerosL src));
9330 effect(TEMP dst, KILL cr);
9331
9332 // return popc(~x & (x - 1));
9333 format %{ "SUB $src,1,$dst\t! count trailing zeros (long)\n\t"
9334 "ANDN $dst,$src,$dst\n\t"
9335 "POPC $dst,$dst" %}
9336 ins_encode %{
9337 Register Rdst = $dst$$Register;
9338 Register Rsrc = $src$$Register;
9339 __ sub(Rsrc, 1, Rdst);
9340 __ andn(Rdst, Rsrc, Rdst);
9341 __ popc(Rdst, Rdst);
9342 %}
9343 ins_pipe(ialu_reg);
9344 %}
9345
9190 9346
9191 //---------- Population Count Instructions ------------------------------------- 9347 //---------- Population Count Instructions -------------------------------------
9192 9348
9193 instruct popCountI(iRegI dst, iRegI src) %{ 9349 instruct popCountI(iRegI dst, iRegI src) %{
9194 predicate(UsePopCountInstruction); 9350 predicate(UsePopCountInstruction);