Hm. Thumb, or the full instruction set? Do you have any data that demonstrates that? The best I'm finding is this:
You can get some comparison data from your own Mac. Most apps are "fat" binaries containing code for both architectures, typically compiled from exactly the same source code with similar compiler settings. You can use the 'otool' command in Terminal.app (requires you to have installed Xcode, or at least the Xcode command line tools) to dump info. Here's an example from my machine, leaving out many lines of output not relevant to the relative size of Arm and x86 code.
% otool -fv /Applications/Numbers.app/Contents/MacOS/Numbers
architecture x86_64
size 16513632
architecture arm64
size 15277168
Caveat aside, is this an indication that modern x86 code is using more RISC like instructions within the x86 instruction set to gain performance over code density and are out RISCing Arm at their own game? That would just be more evidence to me that modern code uses far fewer of those crufty instructions and Intel needs to wack the legacy instructions over a generation or two and produce a more svelte, less backwards compatible core to compete.
No, it's something else entirely. When AMD extended the i386 ISA to 64-bit, they took a very conservative and backwards compatible approach. They kept nearly all existing 32-bit instruction encodings, so all new "long mode" instructions which do one or more of these three things had to be encoded with an additional new prefix byte (REX):
- use 64-bit operand size in an instruction which doesn't default to 64-bit operand size
- use any extended register added by AMD64 (R8 to R15, XMM8-15, YMM8-15, CR8-15, or DR8-15)
- use one of the uniform byte registers SPL, BPL, SIL, or DIL
Thus, 64-bit x86 instructions are at best the same size as 32-bit instructions, but more often larger. If you write code to do exactly the same thing as before, just on 64-bit data values instead of 32-bit, it is likely to grow in size simply because REX instruction encodings are bigger.
This is mitigated somewhat by the availability of an additional 8 general purpose and vector/FP registers. Compilers can take advantage of these to emit fewer stack spill and fill instructions, i.e. the same job gets done in fewer (but individually larger) instructions. Nevertheless, on average, x86-64 code is less dense than i386 code.
What you suggest re: "wack the legacy instructions over a generation or two" isn't likely to happen any time soon. "Legacy" i386 instructions are still a fully legitimate part of x86-64. Compilers still emit them, software still uses them (if you don't need to do a 64-bit computation and the instruction doesn't use any of the extended registers, why use the longer REX encoding?). So you're talking about literally abandoning compatibility with Windows and all its software.
The time to do something like that would have been when AMD came up with AMD64. They could have done something a bit more like what Arm did with 64-bit, where the 64-bit Arm ISA uses a fundamentally new encoding scheme that is 100% incompatible with 32-bit Arm. (An Arm CPU in 64-bit mode cannot decode 32-bit Arm instructions, and vice versa.) But that didn't happen because at the time, AMD had no power to make anyone adopt a fundamentally new ISA, so they had to go with not rocking the boat much in hopes that Microsoft would see their design and like it as a way to bridge the entire existing 32-bit x86 ecosystem into the 64-bit era. Which Microsoft did, and that's how AMD64 got adopted.