]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
In the past, the implementation of STFLE returned the facilities of the host
authorFlorian Krohm <florian@eich-krohm.de>
Tue, 4 Dec 2012 04:45:32 +0000 (04:45 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Tue, 4 Dec 2012 04:45:32 +0000 (04:45 +0000)
machine. This was not consistent in the following sense: Suppose the host
has a facility F installed and this facility implies the availability of an
insn X. Suppose further, that insn X is not supported in valgrind.
An application progrm that tests the availability of insn X by checking
for its associated facility F will fail under valgrind when using X because
valgrind will SIGILL. Not so good.

This patch changes the STFLE behaviour to adjust the facilities of the
virtual machine according to what the set of insns that is actually
supported. It's an approximation, because for some facilities we only
support a subset of the insns enabled by that facility.

Fixes BZ 310931.

git-svn-id: svn://svn.valgrind.org/vex/trunk@2579

VEX/priv/guest_s390_helpers.c
VEX/priv/guest_s390_toIR.c

index 8169916ec7ce239422770e6378bf8715b89b916c..b0c0225519ccdf9b62f6b8e1e72c97900854ece7 100644 (file)
@@ -292,6 +292,22 @@ ULong s390x_dirtyhelper_STCKE(ULong *addr) {return 3;}
 /*--- Dirty helper for Store Facility instruction          ---*/
 /*------------------------------------------------------------*/
 #if defined(VGA_s390x)
+static void
+s390_set_facility_bit(ULong *addr, UInt bitno, UInt value)
+{
+   addr  += bitno / 64;
+   bitno  = bitno % 64;
+
+   ULong mask = 1;
+   mask <<= (63 - bitno);
+
+   if (value == 1) {
+      *addr |= mask;   // set
+   } else {
+      *addr &= ~mask;  // clear
+   }
+}
+
 ULong
 s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
 {
@@ -313,9 +329,56 @@ s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
    /* Update guest register 0  with what STFLE set r0 to */
    guest_state->guest_r0 = reg0;
 
+   /* Set default: VM facilities = host facilities */
    for (i = 0; i < num_dw; ++i)
       addr[i] = hoststfle[i];
 
+   /* Enumerators for interesting facilities. The value of the enumerator
+      is the number of the facility bit as per POP. */
+   enum {
+      S390_FAC_MSA    = 17,  // message-security-assist
+      S390_FAC_LDISP  = 18,  // long displacement
+      S390_FAC_HFPMAS = 20,  // HFP multiply-and-add-subtract
+      S390_FAC_EIMM   = 21,  // extended immediate
+      S390_FAC_HFPUNX = 23,  // HFP unnormalized extension
+      S390_FAC_ETF2   = 24,  // ETF2-enhancement
+      S390_FAC_PENH   = 26,  // parsing-enhancement
+      S390_FAC_ETF3   = 30,  // ETF3-enhancement
+      S390_FAC_XCPUT  = 31,  // extract-CPU-time
+      S390_FAC_GIE    = 34,  // general insn extension
+      S390_FAC_EXEXT  = 35,  // execute extension
+      S390_FAC_DFP    = 42,  // decimal floating point
+      S390_FAC_PFPO   = 44,  // perform floating point operation insn
+      S390_FAC_HIGHW  = 45,  // high-word extension
+      S390_FAC_DFPZC  = 48,  // DFP zoned-conversion
+      S390_FAC_MISC   = 49,  // miscellaneous insn
+      S390_FAC_CTREXE = 50,  // constrained transactional execution
+      S390_FAC_TREXE  = 73,  // transactional execution
+      S390_FAC_MSA4   = 77   // message-security-assist 4
+   };
+
+   /* Now adjust the VM facilities according to what the VM supports */
+   s390_set_facility_bit(addr, S390_FAC_LDISP,  1);
+   s390_set_facility_bit(addr, S390_FAC_EIMM,   1);
+   s390_set_facility_bit(addr, S390_FAC_ETF2,   1);
+   s390_set_facility_bit(addr, S390_FAC_ETF3,   1);
+   s390_set_facility_bit(addr, S390_FAC_GIE,    1);
+   s390_set_facility_bit(addr, S390_FAC_EXEXT,  1);
+   s390_set_facility_bit(addr, S390_FAC_HIGHW,  1);
+
+   s390_set_facility_bit(addr, S390_FAC_HFPMAS, 0);
+   s390_set_facility_bit(addr, S390_FAC_HFPUNX, 0);
+   s390_set_facility_bit(addr, S390_FAC_XCPUT,  0);
+   s390_set_facility_bit(addr, S390_FAC_MSA,    0);
+   s390_set_facility_bit(addr, S390_FAC_PENH,   0);
+   s390_set_facility_bit(addr, S390_FAC_DFP,    0);
+   s390_set_facility_bit(addr, S390_FAC_PFPO,   0);
+   s390_set_facility_bit(addr, S390_FAC_DFPZC,  0);
+   s390_set_facility_bit(addr, S390_FAC_MISC,   0);
+   s390_set_facility_bit(addr, S390_FAC_CTREXE, 0);
+   s390_set_facility_bit(addr, S390_FAC_TREXE,  0);
+   s390_set_facility_bit(addr, S390_FAC_MSA4,   0);
+
    return cc;
 }
 
index 68b108f4a6f3add8d26b4dc586ae327226d73e10..5a1b364072829685c0f7e368e3668c77afbb4aa6 100644 (file)
@@ -12482,6 +12482,11 @@ s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
 }
 
 
+/* New insns are added here.
+   If an insn is contingent on a facility being installed also
+   check whether the list of supported facilities in function
+   s390x_dirtyhelper_STFLE needs updating */
+
 /*------------------------------------------------------------*/
 /*--- Build IR for special instructions                    ---*/
 /*------------------------------------------------------------*/