The silicon-level implementation is another matter entirely, of course--but emulation has nothing to do with that. In fact, that's the definition of emulation--using a completely different implementation to offer a compatible interface.
The silicon-level implementation is another matter entirely, of course--but emulation has nothing to do with that. In fact, that's the definition of emulation--using a completely different implementation to offer a compatible interface.
2. The REX prefixes are a nightmare: most instructions have one and this tremendously bloats up the instruction stream size. For this reason, the i-cache efficiency is not good compared to actual compressed instruction sets such as Thumb-2 (not that Thumb-2 is wonderful either). Note that if you do extreme hand-optimization of binary size, you can get x86-64 down pretty far, but so few people do that that it doesn't matter in practice.
3. Two address code isn't necessarily a win, especially since it doubles the number of REX prefixes. In AArch64 "and x9,x10,x11" is 4 bytes; in x86-64 "mov r9,r10; and r9,r11" is 6 bytes (and clobbers the condition codes). There's a reason compilers love to emit the three-address LEA...
4. Memory operands are nice, though I think the squeeze on instruction space makes them not worth it in practice. I'd rather use that opcode space for more registers.
5. Immediate encoding on x86-64 is crazy inefficient. "mov rax,1" is a whopping 7 bytes.
It's still one byte longer than the equivalent AArch64 instruction, though.
There's no question that x86-64 could be improved on in terms of code density.
They listed these features 'strong memory ordering', '(no) branch delay slots', '(no) stack windows', 'good i-cache efficiency through the use of two-address code and memory operands'.
Every single one of those is a property of the ISA - the instruction set, its semantics and encoding - not the implementation.
Which do you think isn't part of the ISA?
i-cache efficiency: Again implementation specific. Efficiency is entirely a result of implementation, isn't it ?
no branch delay slot: Yes, this is a part of the ISA. My point though was that it is uncommon enough that I wouldn't call it a great virtue of x86 per se.
Ars Technica, as always, has the details of how that has evolved over the years. Can't remember when the article in question was written, though.
Huh? I thought the whole point of a RISC ISA is to not be bloated.
For example, Alpha AXP, one of the least blown up ISAs, did not provided non-word aligned loads and stores, providing word aligned loads and stores and a way to extract and/or combine bytes and subwords from/to the whole word. And it ended having separate instructions for loading and storing every subword type. The reason I stated above - to make program run faster and to make programs smaller.
The same is true for every RISC ISA I studied.
For example, MIPS includes an instruction to store a floating point number in the reg1+reg2*arg_size address. This can be split into two RISC instructions and fused at runtime in hardware, but still here it is!