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