https://groups.google.com/g/comp.os.msdos.programmer/c/Lds3MJAgSl0/m/y8zfPt-bMskJ I assume that the 287/387 math coprocessors do not have the same illegal opcode exception that the 286/386 processors had, right?
2 Answers
TL;DR: There are no undefined operations, just reserved ones.
What happens if an invalid opcode is executed on a 287/387 math coprocessor?
There are none, only executable ones :))
The issue contains a bit more fine print and reading thereof than the question assumes, as multiple design goals and components are at work:
It's in the Parts
The FPU is an I/O device about providing IEEE 754 math, while the CPU is managing seamless integration of that device into a x86 system, making it look like a part of the CPU's ISA.
Viewed From the CPU's Siege Tower
For the 286/386 there are no invalid FPU opcodes. Any ESC-instruction (0D8h..0DFh) is a valid one. When the presence of an ESC-Instruction is detected it will be forwarded to the FPU via Port 0F8h followed by all operands via port 0FCh (see here for more details).
The behaviour of not interpreting any FPU opcode (past parameter addressing) is essential to allow future extensions. Thus each and every ESC is considered a valid operation that will be executed.
View From the FPU's Stronghold
A 287/387 FPU does not know any invalid opcodes either. Where 286/386 documentation label all undefined opcodes 'invalid' and executes an INT 06h, 287/387 documentation defines codes with no official function assigned them as 'reserved'. A classic hint about not expecting any behaviour.
All of them will execute, may it be a NOP, some duplicate or additional function. What is is is not publicly available ...
This sound a bit like the infamous 'illegal' 6502 opcodes, but it's rather a case akin to the unpublished 8085 additions. This becomes obvious when noting that the Intel own FORTRAN compiler produces faulty results when run with a Cyrix co-processor as this DoA report describes (Section 2.1.4.5. Cyrix Coprocessor on p.17).
According to that report the Intel FORTRAN compiler issued some of the reserved instruction encodings instead of their documented version. This shows that their functionality must have been documented to the compiler creators and guaranteed by implementation. Cyrix in contrast implemented them as straight NOP, the most clean way to handle them (*1).
Further Points
https://groups.google.com/g/comp.os.msdos.programmer/c/Lds3MJAgSl0/m/y8zfPt-bMskJ
This sounds more of a very 287XL specific issue.
I assume that the 287/387 math coprocessors do not have the same illegal opcode exception that the 286/386 processors had, right?
They don't have any exceptions at all - or better, they do not do any Interrupt like the CPUs do. A FPU may return one of several exceptions as part of an ESC/WAIT instruction (*2), which will result in an INT 10h Processor Extension Error, but 'illegal opcode' is none of them (*3). Also, turning an FPU exception into an INT is again the job of the CPU.
*1 - At that point one may speculate if this was simply due the compiler department using some very low level preliminary documentation from a point before it wasn't decided upon which encodings were to be published (*4), while for getting to correct this when the final decisions were made, or some kind of purposeful anti-competitive measure by inserting this usage, or at least forgetting to make corrections before release. Being the positive chap I am, I of course go for the first :))
*2 - The FPU signals all non masked exceptions by activating the /ERROR pin.
*3 - All FPU exceptions are not related to (hardware) implementation but strictly related to logical FPU operation, as defined by the IEEE 754 standard.
*4 - This is normal. In-house compiler developers usually start with extrem early and only half way done documentation, as they are expected to deliver code even before the first silicone is done.
-
Indeed, unmasked FPU exceptions will cause /ERROR to be asserted on the FPU. This will only cause an INT10 to be triggered on the CPU if the FPU interface is realized as recommended by Intel (connecting /ERROR of the FPU to /ERROR of the CPU). It's worth at least a foot note that the most mainstream 286/287 system deviated at this point: The IBM AT routes FPU /ERROR via the PIC as IRQ13 to the CPU (because INT10 is used as video BIOS entry point on PC compatible systems). Commented Nov 25, 2023 at 17:27
-
@MichaelKarcher you mean beside that FPU exceptions are not part of the question :)) INT 16 is what the CPU does when detecting ERROR (Either when a WAIT is issued or another FPU instruction). THE PC rerouting this is due the way it was handled at the original PC. Another one of those dreaded compatibility quirks noone asked for and noone ever would have missed (and modern systems no longer need either)– RaffzahnCommented Nov 25, 2023 at 17:45
-
The problem is not the 287XL here. The problem is IIT's FPUs. Commented Nov 25, 2023 at 18:05
-
@YuhongBao you may want to elaborate this to have it make sense - so far noone mentioned IIT in this context.– RaffzahnCommented Nov 25, 2023 at 18:45
-
1Some processor instruction sets, especially historically, were documented with "don't-care" bits in some of the instructions; in the 1970s and 1980s it wasn't clear that the ability to have later CPUs extend an instruction set would be useful, so there wasn't any reason not to mark as "don't care" bits that the hardware would ignore.– supercatCommented Nov 25, 2023 at 20:04
TL, DR; There is a difference between "valid" and "supported" opcodes. CPU knows which opcodes are valid and if a valid opcode is found, it is executed, and if it happens to be an ESCAPE opcode for FPU, it is sent to FPU for execution. What the FPU does with the opcode is another thing, it may or may not support all valid opcodes. It cannot tell the CPU if it supports the opcode or not. The FPU either does something with the opcode or not. If it is an unsuported opcode the FPU may do anything, like nothing, someting, or get stuck or destroy itself.
I think you are mixing two different contexts.
The instruction opcodes are fetched, decoded and executed by the CPU, and only the ESCAPE extension opcodes are sent to the FPU for execution.
So the CPU knows from the code stream that there are just instruction opcodes with certain addressing properties, such as if the opcode is valid and which CPU register or which memory address the CPU must use as data source or data target for an instruction.
And the formats of the all the instructions are known by the CPU and the FPU instructions don't differ from the CPU opcode formats. So if the opcode or the format of the opcode is invalid and cannot be executed, then decoding it will fail and invalid opcode exception is raised.
So it should not be possible to encounter an instruction that is not illegal, but the next thing is, the CPU does not know if the specific instruction is supported by the FPU or not. For example, you might not even have a FPU, so there is an option to trap all FPU instructions and run them in software on the CPU.
Of course third parties may make incompatible FPUs that do not implement all instructions. In these cases the CPU will work as usual and it tries to send the instruction and parameters to the FPU, and the FPU has no mechanism to signal that it did not understand or implement the instruction.
In the scenario you link to, the user has a 386 CPU with software that is intended to use with 387 FPU, but has installed a 287XL FPU, which is a 387SX with 287 pinout. As 387 was only later available and you only had 287XL for the early 386s, new programs may simply assume you have a 387, not a 387XL.
The 386 CPU knows what are valid 387 opcodes so you can execute any valid 387 opcodes. The FPU just does not implement all 387 opcodes because it is an 287XL with 16-bit interface.
It is up to the programmer, to run tests on the FPU to be able to determine if it is even present and which FPU it is to know which opcodes it is known to implement. In this case it could be detected as 287XL from the opcodes it supports, and from then on, only run instructions it implements.
This is not much different from detecting which CPU you have. Try to run an opcode and see if it executed properly or failed. The problem always is, when new CPUs/FPUs come to the market, even if it implements one instruction from a newer set, it does not mean it implements all instructions from a newer set, so an old test program may incorrectly and accidentally use that one insteuction and classify the chip incorretly as newer model and try running all features of newer model.
-
2This may give the question some context, but does not answer it. Commented Nov 25, 2023 at 12:48
-
@user3840170 I've edited my answer. The CPU will detect "invalid" opcodes and won't send any commands to FPU that were "invalid" so you can't execute "invalid" instructions with the FPU. Now, the FPU does not need to implement all non-invalid commands, so if you manage to send an non-invalid opcode to FPU which it does not implement or support, there is no guarantee what happens. It might do something, nothing, halt the system, etc. Just like on any other system where you try to execute opcodes that are not specified.– JustmeCommented Nov 26, 2023 at 3:12
-
So what does actually happen when a 287/387 encounters
DA FF
? Commented Apr 25 at 16:59