I understand that all x86 (i386) binaries compiled today, with the latest compilers (GCC, Intel CC, VC, etc) will run on an Intel 386 machine (allowing for external dependencies, like OS functions, etc) which explains why there are videos on YouTube of people getting Windows 7 to install and run on a 20 year-old computer.
Not really. Intel 386 did not have cmpxchg8b
that is required for Windows Vista or Windows 7. After a certain update, Windows 7 requires SSE2.
But I don't understand how ISA extensions work, such as MMX and SSE. If a program's code has an extension instruction but the instruction is not supported by the processor then surely the program must crash (presumably a processor interrupt into the OS). The only solution I can think of is that the program's binary checks to see if an instruction is supported, and if not then it executes lowest-common-denominator code that is guaranteed to be supported by every platform, but surely that can make binaries very large, and what about instructions that were extensions but are now practically standard, like floating-point operations?
Runtime feature dispatch is a thing, and it is used in some programs and libraries, but often the code is compiled to require certain instructions.
Even if there is runtime feature dispatch, it is often used to detect relatively new extensions, while old extensions are mandatory.
/arch:SSE2
is default in Visual Studio 2012 and later, so normally programs will not use legacy floating point operations.
An example of runtime dispatch is vector_algorithms.cpp from MSVC STL where AVX2 and SSE2 are checked for availability at runtime. In x86 mode they fall back to plain C++ code which is complied not to emit vectored instructions, in x64 mode the use of SSE2 is unconditional, as SSE2 is the baseline for x64.
I can't find any settings or options in my VC project settings for the compiler or linker for controlling instruction emission. There are a few about optimization but nothing that gives the control I expect.
/arch
switch. From IDE, "Enable Enhanced Instruction Set" in C/C++ compiler options.
And what about AMD's "3DNow!" extension? 3DNow is meant to be an extension on top of MMX, so it has some unique instructions and aspects of its own, but I can't find any references to it in my VC compiler or linker settings, so if I'm writing code how can I get my compiler to use the 3DNow! instructions (rather than MMX)?
Visual Studio is not able to use them during auto-vectorizing (never auto-vectorized using them). As for intrinsic form, surprisingly you can still use them in x86 mode (but not x64 mode).
Also, the Wikipedia article on 3DNow states that AMD removed a few 3DNow instructions from their processors - if there exists code that assumes these instructions are present will it no-longer work?
To clarify, instructions are removed in a sense that new processors don't have them. They are not removed by a microcode update from old processor.
Instructions removed to complete non-existence, attempts to use them may raise #UD exceptions, or their encoding may be re-purposed for other instructions.