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,
fnstsw
Description: Binary data
_______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
