News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Mistake in fputute by Raymond Filiatreault

Started by Mikl__, October 20, 2015, 06:22:36 PM

Previous topic - Next topic

Mikl__

There is image of tag word register in fputute by Raymond Filiatreault

15 1413 1211 1009 0807 0605 0403 0201 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(?)

jj2007

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, ...)

raymond

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).
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

qWord

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 )).
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

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 ...

raymond

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.)
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

Mikl__

Why is misinterpretation?
instructionresulttopbusy registersfree registers
finitR(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 busyNo free data registers


raymond

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.)
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

Mikl__

Hi, raymond!
Do you think that the correct table looks as this?
instructionresulttopbusy registersfree registers
finitR(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 busyNo 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 ?

raymond

Quote from: Mikl__ on October 21, 2015, 02:02:34 PM
Hi, raymond!
Do you think that the correct table looks as this?
instructionresulttopbusy registersfree registers
finitR(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 busyNo free data registers

Exactly.
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

Mikl__

dedndave, raymond, qWord, jj2007,
thank for the clarification