Apologies in advance for e-mail difficulties today - I can't reply directly to your message, so threading may be off. >I'd suggest _only_ changing the i386 version. > >For example, your asm-generic changes looks senseless, since they only >make the macros more complex, without actually changing anything. And the >other architectures may want to do other things, since right now at least >some of them use things like fixed hardware registers etc which is not >necessarily appropriate for the non-asm case... > >That way you'd also only modify the architecture that you can actually >verify.. > > Linus > Backed out everything but i386 and generic. For the generic version, I compiled and tested this code outside of the kernel. Actually, I found that at least for my tool chain, the generic version +# define do_div(n,base) ({ \ + uint32_t __rem; \ + if (__builtin_constant_p(base) && !((base) & ((base)-1))) { \ + __rem = ((uint64_t)(n)) % (base); \ + (n) = ((uint64_t)(n)) / (base); \ + } else { \ + uint32_t __base = (base); \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + } \ + __rem; Does indeed generate different code for the constant case - without it, due to the assignment to __base, the shift / mask optimization does not take place. Apparently the constant attribute and associated optimizations do not propagate through the assignment. Other gccs may behave differently. I also tried making __base const, to no avail. If one were willing to ignore the potential macro side effects of the references to (base), the code could be the same, but I'm not the best judge of whether that is a good thing to do. Zach zach@vmware.com