On 06/16/2011 06:25 PM, Richard Henderson wrote: > On 06/16/2011 05:44 AM, Bernd Schmidt wrote: >> +@deftypefn {Built-in Function} int __builtin_clrsb (unsigned int x) >> +Returns the number of leading redundant sign bits in @var{x}, starting >> +at the most significant bit position. >> +@end deftypefn > > Do we want a signed argument, since we're talking about signs? Err, yes. It's signed everywhere else (builtins.def etc.). > It would seem that unlike clz, this function is not undefined for zero. > What about INT_MIN? Do all cpus handle those edge cases the same way? -1 and zero should both produce the same value, 31 (for a 32 bit integer). I don't see why INT_MIN should be special - the return value is zero. This is true for C6X and Blackfin; ARM documentation suggests it's also true for their VCLS instruction. I've not found proper picochip documentation but some other documents that suggest it's also implemented this way. > Do you get smaller code in general from > > if (x < 0) > x = ~x; > if (x == 0) > return W_TYPE_SIZE - 1; > count_leading_zeros(ret, x); > return ret - 1; Probably. >> -(define_insn "signbitssi2" >> +(define_insn "clrsbsi2" >> [(set (match_operand:HI 0 "register_operand" "=d") >> (if_then_else:HI >> (lt (match_operand:SI 1 "register_operand" "d") (const_int 0)) > > No use of the new rtx code? D'oh. Blackfin has a (clrsb:HI (operand:SI)) instruction, so adding this showed a problem with some of the existing simplify_const_unop cases: for ffs/clz/ctz/clrsb/parity/popcount, we should look at the mode of the operand, rather than the mode of the operation. This limits what we can do in that function, since op_mode is sometimes VOIDmode - we really should add builtin folders for these at some point. New patch below. Retested on i686 and bfin. Bernd