7 ms·
This article does a great job answering the question "why don't compilers use AH/AL/etc. like DOS compilers did in the good old days?" Short answer: it causes u
by pcwalton 7y ago
This article does a great job answering the question "why don't compilers use AH/AL/etc. like DOS compilers did in the good old days?" Short answer: it causes unnecessary dependencies because the other parts of the register are preserved.
It also answers the question "why don't compilers emit INC and DEC?" Short answer: they don't set the carry, so on some CPUs that means that they cause an unnecessary dependency on the previous instruction that sets EFLAGS.
The x86 ISA really is a mess!
- acqq 7y ago> The x86 ISA really is a mess! No, it's not. I've written the compilers for both x86 and x64. One should not look for too much idealistic "symmetry" but look at it as a domain specific encoding language. Behind that encoding is anyway huge machinery that significantly speeds up that what is written in the language, and it's even proven that, when there is enough silicon, it is of advantage that some optimizations are actually done during the execution. Some execution statistics are simply dependent on the information which dynamically depends on execution and can't be pre-coded by a compiler. Since long ago, even those processors that started as RISC got more and more instructions and started to worry about having them encoded with less bits. And that all doesn't mean that the compilers shouldn't be as smart as possible to use the hardware the best it can be used.
- Dylan16807 7y agoI don't know how anyone can look at the list of one-byte opcodes and conclude that x86 isn't a mess. Even ignoring all the annoying mismatches in semantics, all the awkwardly-fit expansions and prefixes do not lead to a good encoding. And it's far slower to figure out how long an instruction is than it should be.
- pcwalton 7y ago> I don't know how anyone can look at the list of one-byte opcodes and conclude that x86 isn't a mess. Or heck, even just the fact that real mode is still a thing.
- dfox 7y agoThe CPU contains essentially no hardware that is there only to support real mode, which is simply an documented combination of configurations of various protected mode relevant mechanism plus changed behavior of exactly one microarchitectural operation, which involves replacing bunch of nontrivial microcoded logic with simple 4 bit left shift.
- bonzini 7y agoThere is hardware that is there only to support v86-mode and v86 mode extensions though. V86 mode really really should go away...
- dfox 7y agoIn fact there isn't any hardware to speak of (3 bits worth of architectural registers and bunch of trivial logic related to that?) to support vm86 mode, and that is to some extent the consequence of how true real mode is implemented. The combination of paging enabled (which is not strictly necessary), protected mode enabled, 16b code segment and real mode style segment loads gets you vm86 mode (complete with weird stuff on stack of exception handler vectors), in fact when you look at vm86 entry gate descriptor, this is exactly what it does. The microarchitecture essentially does not care about that. edit: there is no documented direct way to flip the segment/selector bit, which is the reason why you need documented vm86 mode. The hardware always calculate the linear address according to whatever is in shadow descriptor of segment/selector register, difference between real/vm86 and protected mode is what happens when you store something into there.
- PopePompus 7y agoBut it's not just a matter of wasting transistors and silicon. The ancient x86 modes are like old legacy code in a software package you have to maintain. They add complexity. Intel hasn't exactly been cranking out an endless series of bug-free chips lately. It might behoove them to make a line of chips which are pure x86-64.
- 7y ago
- acqq 7y agoThe point is, it didn't matter as people wrote assembly by hand, and it doesn't matter now when everybody is using compilers. The opcode details are trivially solved by the tables, the know-how of those who programmed assembly was enough for most of the times they programmed, compilers can handle a lot, and the real problems that really have to be solved are simply not dependent on these issues at all. And diagonally, the instruction set is surely not the reason why every internet page is tracked by thousands of companies and has to download more megabytes than the total RAM the whole x86 computers had. And like I've said, all instruction sets since a while have to take care to be "compressed" in a way, which is simply a total opposite of what the critics pointed since RISC was introduced. Pure RISC was/is useful only under some very specific assumptions. The appearance of "mess" is a result of "if was successful." But the problems it solved were/are real.
- Dylan16807 7y ago"It doesn't matter" (much) that it's a mess is one thing. "It's not a mess" is quite another. But 'compression' and 'mess' are very very different things. You can have organized compression. Look at the length encoding on RISC-V, or something. No prefix bytes in sight. On x86 the balance and methodology for getting different instruction sizes is completely garbage for historical reasons. > The appearance of "mess" is a result of "if was successful." But the problems it solved were/are real. It's because it's been collecting legacy since it was 8-bit all the way to 64-bit with vector units, not as an inevitable result of being successful.
- pcwalton 7y agoIt's not my contention that RISC designs are necessarily faster/more power efficient/etc. It's just that the x86 design is, from an engineering perspective, a mess. > Since long ago, even those processors that started as RISC got more and more instructions and started to worry about having them encoded with less bits. x86-64 is not very space efficient, because of all the REX prefixes. Look at the comparative sizes of AArch64 and x86-64 binaries if you don't believe me.
- fmakunbound 7y ago> from an engineering perspective It's pretty awesome. Remember engineering doesn't happen in a void. It's influenced all sorts of shit including economics, existing investments etc.
- blattimwind 7y agoFrom an engineering perspective it is hugely impressive that a 2020 AMD or Intel chip can run an x86 app compiled in '92 at something like 100 times the speed.
- mumblemumble 7y agoFrom an engineering perspective, these two assertions that have been prefixed with the qualifier, "from an engineering perspective," are entirely compatible.
- lallysingh 7y ago28 years later, the speedup on their selected representation is 100x? That seems low for such a long time.
- bsder 7y agoThe x86 architecture is a mess and it matters. The reason it matters is because a disproportionate amount of energy is spent in the instruction decode system. And that affects your battery life.
- dbcurtis 7y agoYes. Precisely. As ex-Intel, I confirm all of your points. The “mess”, though, is just a natural artifact of longevity. Many years of decisions that made sense in the moment accumulated to appear to be a “what WERE they thinking?” situation when, in fact, they were addressing the market forces and technology constraints of the day. In the end, nobody buys your product because the elegant design means that two generations of your product later it will have good performance. Sales are driven by what you can do in the here-and-now. If you do that well enough, you can live long enough to accumulate the kind of cruft that is the X86 ISA.
- api 7y agoHow messy is AARCH64 compared to X64? I imagine it's less, but ARM's been around for a while too hasn't it?
- saagarjha 7y agoMuch less, but it’s starting to get some uglier stuff in it. Since it doesn’t need to be backwards compatible the task of keeping it reasonable is much easier.
- wtmt 7y ago> The “mess”, though, is just a natural artifact of longevity. Many years of decisions that made sense in the moment accumulated to appear to be a “what WERE they thinking?” situation when, in fact, they were addressing the market forces and technology constraints of the day. > In the end, nobody buys your product because the elegant design means that two generations of your product later it will have good performance. Sales are driven by what you can do in the here-and-now. If you do that well enough, you can live long enough to accumulate the kind of cruft that is the X86 ISA. I think Itanium, or the pursuit of making Itanium the replacement for x86, demonstrated these quite well.
- Wowfunhappy 7y agoIf no one is writing assembly code, does it matter? Seems to me that backwards compatibility is more important than simplicity at a layer that almost no one ever touches anyway.
- wrkronmiller 7y agoI'd argue complexity increases the odds of bugs. Pretty much the last place I want a bug is on my compiler (though I'm sure there are plenty out there).
- taeric 7y agoChange increases the odds of bugs.
- BeeOnRope 7y agoCompilers don't really hesitate to use AL and friends, and they do issue INC and DEC. A lot of the information there is a decade out of date.
- pcwalton 7y agoObviously compilers do use byte registers for byte operations because those are the only way to get them on x86, but they don't use the high bytes. And neither Clang nor GCC emits inc or dec: https://godbolt.org/z/47y8K3 https://godbolt.org/z/47y8K3
- BeeOnRope 7y ago> Obviously compilers do use byte registers for byte operations because those are the only way to get them on x86, ... OK, but what does it even mean that they avoid AL then, if they use them for 8-bit math? Under what other scenarios would they even want to use them? FWIW, compilers could use 32-bit arithmetic ops almost all the time even when bytes are used in the source, because excect for right shifts and division, information flows only to more significant bits, so 32-bit bit ops give you the right results in the low bits. In fact, I thought they did this more often – but when I looked into it recently they seem to prefer the low 8 bit registers. > but they don't use the high bytes. Not often, but of course the use case for the "second least significant byte" is very narrow in the first place [2]! If you just want to deal with byte values, you'll use the low bytes, after all. The high 8-bit values are reserved for special cases, e.g., extracting that particular byte, and there compilers do use them (at least gcc, clang and icc on the first try, but not msvc): https://godbolt.org/z/m5MbsM https://godbolt.org/z/m5MbsM The performance characteristics for the high bytes are quite different from the low bytes on modern, x86 too: see [1]! > And neither Clang nor GCC emits inc or dec Yes, if you don't set the march they will compile for an archaic blend of chips at least one of which may have the old inc/dec behavior. Try setting a "modern" march flag like Haswell and fixing the issue where i wasn't actually used except as the loop induction variabale (allowing loop transformations away from simple +1) and both clang and gcc use inc: https://godbolt.org/z/gtkd-v https://godbolt.org/z/gtkd-v --- [1] https://stackoverflow.com/a/45660140/149138 https://stackoverflow.com/a/45660140/149138 [2] It is possible one of the original motivations for the high bytes was to double the number of 8 byte registers in the 16 bit era. I.e., 8x byte registers was considered significantly better than 4x, and you couldn't use the low byte of di,si,sp and bp for other reasons. In 64-bit, however, we now have 8 additional registers each with a low byte variant (r8b-r15b), so there are plenty of low byte registers for most work, so the remaining use of the high byte registers mostly seems to be taking advantage of their ability to quickly access the 2nd byte of a larger value.