Since the number of registers depends on the architecture, is a generic pre-compiled binary targeted for the worst case (least number of available registers)?
There really isn't such thing as a generic pre-compiled binary. Binaries that are compiled necessarily target both a specific Instruction Set Architecture and a specific Application Binary Interface. That same binary won't run on a different ISA or different ABI, it will have to be recompiled for that.
It is the ISA that defines the available hardware register set; the ABI defines how the software is allowed to use the registers, especially when it comes to function calls.
When compiling, the ISA and ABI are selected by choosing the appropriate compiler or sometimes by compiler options.
For example, x86 is an intel 32-bit Instruction Set Architecture that specifies ~8 32-bit registers (not counting any floating point or xmm registers).
x64, on the other had has ~16 64-bit registers. And there are other processors, too.
A binary compiled for x86 will usually run in 32-bit compatibility mode as a feature of an x64 processor, however, an x64 compiled-binary won't run on an x86. (When a x64 processor runs an x86 binary that binary runs with the resources of the 32-bit instruction set architecture, which is to say it is limited to the ~8 32-bit registers and has a 4GB address space limit as well; it does not have access to the 16 64-bit registers or larger address space.)
Further, a binary compiled for windows will not run on linux and vise versa due to ABI differences, even for the same ISA.
Is the loop unrolling one of the examples of this “targeted” compilation?
All "pre" compilation is targeted to an exact ISA and ABI pair.
As in, a software compiled for a processor with more registers than the generic case will utilize ALL those registers for its loops?
Yes, to a degree. But I'd say there is no generic case, there are specific cases.
There is an area of compilation that is more dynamic, and this is Just In Time Compiling or JITing for short. Java and C# both use an intermediate binary form called byte code (different for each, of course), and then do final compilation on the target machine at runtime. Since the runtime knows more about the actual processor it is running on, it can do a better job of managing compilation not just for the specific ISA and ABI but also for the specific processor. This include the registers, and affects the use of optional processor features, like XMM registers. For example, in C# you can write code that uses the SIMD processor extensions, and if that hardware is present (i.e. it is currently running on a more expensive or more modern processor) the JIT will generate code to use them, and if that hardware is not present, it won't.
In a "pre" compiled environment, you'd have to create two separate pre-compiled binaries for that.