x86: Split apart x87's FSW and TOP, and add a missing break.
authorGabe Black <gabeblack@google.com>
Wed, 6 Dec 2017 01:49:51 +0000 (17:49 -0800)
committerGabe Black <gabeblack@google.com>
Wed, 6 Dec 2017 08:02:25 +0000 (08:02 +0000)
The FSW and TOP values are technically part of the same register, but
they have very different behaviors. One of them can be renamed and
float along without affecting global state, while the other requires
serialization. They just need to *look* like the same register when
read by the user.

Also, there was a missing break in setMiscRegNoEffect.

Change-Id: If58de0f566f65068208240f4001209fb9e1826d6
Reviewed-on: https://gem5-review.googlesource.com/6441
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/arch/x86/isa.cc
src/arch/x86/isa/insts/x87/control/save_and_restore_x87_environment.py

index eaedfbee376279739201642b248f90e0e13d7187..9dd7fbb52a0d3bcb4abe93b8e550a093dfc5edd1 100644 (file)
@@ -145,7 +145,7 @@ ISA::readMiscReg(int miscReg, ThreadContext * tc)
     if (miscReg == MISCREG_FSW) {
         MiscReg fsw = regVal[MISCREG_FSW];
         MiscReg top = regVal[MISCREG_X87_TOP];
-        return (fsw & (~(7ULL << 11))) + (top << 11);
+        return insertBits(fsw, 11, 13, top);
     }
 
     return readMiscRegNoEffect(miscReg);
@@ -159,41 +159,38 @@ ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
     // attempt to write to them directly.
     assert(isValidMiscReg(miscReg));
 
-    HandyM5Reg m5Reg = readMiscRegNoEffect(MISCREG_M5_REG);
+    HandyM5Reg m5Reg = regVal[MISCREG_M5_REG];
+    int reg_width = 64;
     switch (miscReg) {
-      case MISCREG_FSW:
-        val &= (1ULL << 16) - 1;
-        regVal[miscReg] = val;
-        miscReg = MISCREG_X87_TOP;
-        val <<= 11;
       case MISCREG_X87_TOP:
-        val &= (1ULL << 3) - 1;
+        reg_width = 3;
         break;
       case MISCREG_FTW:
-        val &= (1ULL << 8) - 1;
+        reg_width = 8;
         break;
+      case MISCREG_FSW:
       case MISCREG_FCW:
       case MISCREG_FOP:
-        val &= (1ULL << 16) - 1;
+        reg_width = 16;
         break;
       case MISCREG_MXCSR:
-        val &= (1ULL << 32) - 1;
+        reg_width = 32;
         break;
       case MISCREG_FISEG:
       case MISCREG_FOSEG:
         if (m5Reg.submode != SixtyFourBitMode)
-            val &= (1ULL << 16) - 1;
+            reg_width = 16;
         break;
       case MISCREG_FIOFF:
       case MISCREG_FOOFF:
         if (m5Reg.submode != SixtyFourBitMode)
-            val &= (1ULL << 32) - 1;
+            reg_width = 32;
         break;
       default:
         break;
     }
 
-    regVal[miscReg] = val;
+    regVal[miscReg] = val & mask(reg_width);
 }
 
 void
index 20ecff43a1f34670b1080b47efbffd786575e6d8..ffc4907152668107c84ef97eb1dd7ecf09db90f2 100644 (file)
@@ -63,6 +63,9 @@ fnstenvTemplate = """
     # FSW includes TOP when read
     rdval t1, fsw
     st t1, seg, %(mode)s, "DISPLACEMENT + 4", dataSize=2
+    srli t1, t1, 11, dataSize=2
+    andi t1, t1, 0x7, dataSize=2
+    wrval "InstRegIndex(MISCREG_X87_TOP)", t1
 
     rdval t1, ftw
     st t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=2