So I started looking into what might be needed for proper fnstsw support.  
Below is a patch.  I'm sure I've got a lot of things wrong.

The status word is a 16-bit register that holds exception bits, result 
status flags, and the x87 stack top value.  Currently m5 tracks the top 
value separately.

I merge the top value in at the decode level, but it really should 
probably be redone so this is done automatically.

Attached is a test program; with the patch it mostly works until the stack 
overflow happens.  Currently the stack code doesn't detect and report 
overflows.  That will take more changes to the code.

I just wanted to see if I was roughly on the right track here.

Vince

diff -r 16817406af29 src/arch/x86/isa/decoder/x87.isa
--- a/src/arch/x86/isa/decoder/x87.isa  Tue Nov 10 11:29:30 2009 -0500
+++ b/src/arch/x86/isa/decoder/x87.isa  Tue Nov 10 14:56:59 2009 -0500
@@ -265,7 +265,7 @@
             }
             0x7: decode MODRM_MOD {
                 0x3: Inst::UD2();
-                default: fnstsw();
+                default: Inst::FNSTSW(Mw);
             }
         }
         //0x6: esc6();
@@ -326,7 +326,7 @@
             }
             0x4: decode MODRM_MOD {
                 0x3: decode MODRM_RM {
-                    0x0: fnstsw();
+                    0x0: Inst::FNSTSW(rAw);
                     default: Inst::UD2();
                 }
                 default: fbld();
diff -r 16817406af29 src/arch/x86/isa/insts/x87/control/save_x87_status_word.py
--- a/src/arch/x86/isa/insts/x87/control/save_x87_status_word.py        Tue Nov 
10 11:29:30 2009 -0500
+++ b/src/arch/x86/isa/insts/x87/control/save_x87_status_word.py        Tue Nov 
10 14:56:59 2009 -0500
@@ -54,6 +54,44 @@
 # Authors: Gabe Black
 
 microcode = '''
-# FSTSW
-# FNSTSW
+
+# FSTSW (pseudo-op, FWAIT followed by FNSTSW)
+
+# x87 status word is 16-bits
+#   15 = busy
+#   14,10,9,8 = condition codes set by results of various instructions
+#   13,12,11  = top of stack pointer
+#   7 = exception flag
+#   6 = stack fault
+#   5 = precision
+#   4 = underflow
+#   3 = overflow
+#   2 = divide by zero
+#   1 = denormalized
+#   0 = invalid
+
+def macroop FNSTSW_R {
+    rdval t1, "InstRegIndex(MISCREG_X87_STATUS)"
+    rdval t2, "InstRegIndex(MISCREG_X87_TOP)"
+    slli t2, t2, 11
+    or t1,t1,t2
+    mov rax, rax, t1, dataSize=2
+};
+
+def macroop FNSTSW_M {
+    rdval t1, "InstRegIndex(MISCREG_X87_STATUS)"
+    rdval t2, "InstRegIndex(MISCREG_X87_TOP)"
+    slli t2, t2, 11
+    or t1,t1,t2
+    st t1, seg, sib, disp, dataSize=2
+};
+
+def macroop FNSTSW_P {
+    rdip t7
+    rdval t1, "InstRegIndex(MISCREG_X87_STATUS)"
+    rdval t2, "InstRegIndex(MISCREG_X87_TOP)"
+    slli t2, t2, 11
+    or t1,t1,t2
+    st t1, seg, riprel, disp, dataSize=2
+};
 '''
diff -r 16817406af29 src/arch/x86/isa/operands.isa
--- a/src/arch/x86/isa/operands.isa     Tue Nov 10 11:29:30 2009 -0500
+++ b/src/arch/x86/isa/operands.isa     Tue Nov 10 14:56:59 2009 -0500
@@ -150,6 +150,7 @@
         # instructions don't map their indexes with an old value.
         'nccFlagBits':   controlReg('MISCREG_RFLAGS', 61),
         'TOP':           controlReg('MISCREG_X87_TOP', 62, ctype='ub'),
+       'FPSTATUS':      controlReg('MISCREG_X87_STATUS', 63, ctype='uw'),
         # The segment base as used by memory instructions.
         'SegBase':       controlReg('MISCREG_SEG_EFF_BASE(segment)', 70),
diff -r 16817406af29 src/arch/x86/miscregs.hh
--- a/src/arch/x86/miscregs.hh  Tue Nov 10 11:29:30 2009 -0500
+++ b/src/arch/x86/miscregs.hh  Tue Nov 10 14:56:59 2009 -0500
@@ -373,6 +373,7 @@
         // Floating point control registers
         MISCREG_X87_TOP =
             MISCREG_SEG_ATTR_BASE + NUM_SEGMENTREGS,
+       MISCREG_X87_STATUS,
 
         MISCREG_MXCSR,
         MISCREG_FCW,

Attachment: fnstsw
Description: Binary data

_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to