There is image of tag word register in fputute by Raymond Filiatreault
15 14 | 13 12 | 11 10 | 09 08 | 07 06 | 05 04 | 03 02 | 01 00 | Tag(7) | Tag(6) | Tag(5) | Tag(4) | Tag(3) | Tag(2) | Tag(1) | Tag(0) | In "Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 1: Basic Architecture" is original picture of x87 FPU Tag Word (Figure 8-7 page Vol. 1 8-13) This picture is in every manual, but in fact this is not true I wrote a simple program that initiated FPU, and then sequentially loaded into each FPU data register a number +1.0. After the instruction fninit and after each fld1 analyzed the contents of the registers tags, status and control
|
fninit
fnstenv a;cwr=037f swr=0000=00.000.00000000000 <-- R0 on top of stack
; twr swr cwr twr=ffff=11.11.11.11.11.11.11.11 <-- all registers are free
;ffffffffffff0000ffff037f
fld1
fnstenv a;cwr=037f swr=3800=00.111.00000000000 <-- R0:=1 R7 on top of stack
; 0
; twr swr cwr twr=3fff=00.11.11.11.11.11.11.11 <-- R0 is busy
;ffff3fffffff3800ffff037f
fld1
fnstenv a;cwr=037f swr=3000=00.110.00000000000
; 0 7
; twr swr cwr twr=0fff=00.00.11.11.11.11.11.11 <-- R0 and R7 are busy
;ffff0fffffff3000ffff037f
fld1
fnstenv a;cwr=037f swr=2800=00.101.00000000000
0 7 6
; twr swr cwr twr=03ff=00.00.00.11.11.11.11.11
;ffff03ffffff2800ffff037f
fld1
fnstenv a;cwr=037f swr=2000=00.100.00000000000
0 7 6 5
; twr swr cwr twr=00ff=00.00.00.00.11.11.11.11
;ffff00ffffff2000ffff037f
fld1
fnstenv a;cwr=037f swr=1800=00.011.00000000000
0 7 6 5 4
; twr swr cwr twr=003f=00.00.00.00.00.11.11.11
;ffff003fffff1800ffff037f
fld1
fnstenv a;cwr=037f swr=1000=00.010.00000000000
; 0 7 6 5 4 3
; twr swr cwr twr=000f=00.00.00.00.00.00.11.11
;ffff000fffff1000ffff037f
fld1
fnstenv a;cwr=037f swr=0800=00.001.00000000000
; 0 7 6 5 4 3 2
; twr swr cwr twr=0003=00.00.00.00.00.00.00.11
;ffff0003ffff0800ffff037f
fld1
fnstenv a;cwr=037f swr=0000=00.000.00000000000
; 0 7 6 5 4 3 2 1
; twr swr cwr twr=0000=00.00.00.00.00.00.00.00
;ffff0000ffff0000ffff037f
ret
a dd 4 dup(?)
On my Core i5, the sequence is
0 empty FPU
7 ST(0)
6 ST(0+1)
5 ...
4
3
2
1
0 full FPU
(7=3800h SAR 11, 6=3000h SAR 11, 5=2800h SAR 11, 4=2000h SAR 11, ...)
I notice that the original post has been edited, but no indication of what has been edited. Furthermore, I tried to open the attachement without success.
So, what is the conclusion of this thread (since I believe that my depiction of the tag word is still the correct one).
Mikl__,
when a value is load into the FPU, TOP is first decremented (with wraparound) and than the value is stored in corresponding register.
For example: If TOP == 0 and FLD x is executed, than x goes into register R7 ( 7 ≡ 0-1 (mod 8 )).
from what i can see, Ray's document is 100% correct
the TagWord hasn't changed much since the 8087 :P
here's a simple test program....
FFFF 3FFF 0FFF 03FF 00FF 003F 000F 0003 0000
Press any key to continue ...
It may just be a matter of misinterpretation on Miki's part. Based on HIS 'simple' program and his reported results after the first load instruction
fld1
fnstenv a;cwr=037f swr=3800=00.111.00000000000 <-- R0:=1 R7 on top of stack
; 0
; twr swr cwr twr=3fff=00.11.11.11.11.11.11.11 <-- R0 is busy
the status word (swr) shows R7 as now being "on top of the stack". Therefore, R7 contains the loaded value, which is considered as valid and is indicated as such in the tag word by the '00'; this also indicates that register as busy and thus not free. That busy register must thus be R7 and NOT R0.
(For the programmer in this case, that R7 register would need to be referred to as st(0) until some other value is loaded.)
Why is misinterpretation?
instruction | result | top | busy registers | free registers |
finit | | R(0) | | R(0)-R(7) |
fld1 | R(0):=1 | R(7) | R(0) | R(1)-R(7) |
fld1 | R(7):=1 | R(6) | R(0),R(7) | R(1)-R(6) |
fld1 | R(6):=1 | R(5) | R(0),R(7),R(6) | R(1)-R(5) |
fld1 | R(5):=1 | R(4) | R(0),R(7)-R(5) | R(1)-R(4) |
fld1 | R(4):=1 | R(3) | R(0),R(7)-R(4) | R(1)-R(3) |
fld1 | R(3):=1 | R(2) | R(0),R(7)-R(3) | R(1)-R(2) |
fld1 | R(2):=1 | R(1) | R(0),R(7)-R(2) | R(1) |
fld1 | R(1):=1 | R(0) | all registers are busy | No free data registers |
Why is misinterpretation?
Because after you initialize the FPU, your "top" register is R0 (swr=0000=00.000.00000000000 <-- R0 on top of stack) and contains nothing.
Then, when you instruct the FPU to load a valid value (which you did with the fld1 instruction), it first brings the R7 register as the "top" register BEFORE it actually loads the specified value. If you examine the STATUS word after that first load (as you did with your program = swr=3800=00.111.00000000000), you will notice that the "top" register became effectively R7, where the valid loaded data now resides.
According to the TAG word, one FPU data register then became 'busy' and contained a valid value (twr=3fff=00.11.11.11.11.11.11.11). You should agree that the subject register has already been described above as the R7 register. The R0 register still does NOT contain any data, is FREE, not busy, and could later (much later) become available to be used.
(You must remember that those register numbers are strictly for internal use and have nothing to do with assembly FPU instructions.)
Hi,
raymond!
Do you think that the correct table looks as this?
instruction | result | top | busy registers | free registers |
finit | | R(0) | | R(0)-R(7) |
fld1 | R(7):=1 | R(7) | R(7) | R(0)-R(6) |
fld1 | R(6):=1 | R(6) | R(7),R(6) | R(0)-R(5) |
fld1 | R(5):=1 | R(5) | R(7)-R(5) | R(0)-R(4) |
fld1 | R(4):=1 | R(4) | R(7)-R(4) | R(0)-R(3) |
fld1 | R(3):=1 | R(3) | R(7)-R(3) | R(0)-R(2) |
fld1 | R(2):=1 | R(2) | R(7)-R(2) | R(0)-R(1) |
fld1 | R(1):=1 | R(1) | R(7)-R(1) | R(0) |
fld1 | R(0):=1 | R(0) | all registers are busy | No free data registers |
In "Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M"
FLD1
Operation
TOP <--TOP − 1;
ST(0) <-- CONSTANT;
after finit TOP=0
(0-1)and 7=7
R(7):=1 ?
Quote from: Mikl__ on October 21, 2015, 02:02:34 PM
Hi, raymond!
Do you think that the correct table looks as this?
instruction | result | top | busy registers | free registers |
finit | | R(0) | | R(0)-R(7) |
fld1 | R(7):=1 | R(7) | R(7) | R(0)-R(6) |
fld1 | R(6):=1 | R(6) | R(7),R(6) | R(0)-R(5) |
fld1 | R(5):=1 | R(5) | R(7)-R(5) | R(0)-R(4) |
fld1 | R(4):=1 | R(4) | R(7)-R(4) | R(0)-R(3) |
fld1 | R(3):=1 | R(3) | R(7)-R(3) | R(0)-R(2) |
fld1 | R(2):=1 | R(2) | R(7)-R(2) | R(0)-R(1) |
fld1 | R(1):=1 | R(1) | R(7)-R(1) | R(0) |
fld1 | R(0):=1 | R(0) | all registers are busy | No free data registers |
Exactly.
dedndave, raymond, qWord, jj2007,
thank for the clarification