]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Generate an emulation failure if an insn is encountered that
authorFlorian Krohm <florian@eich-krohm.de>
Sat, 1 Sep 2012 17:54:09 +0000 (17:54 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Sat, 1 Sep 2012 17:54:09 +0000 (17:54 +0000)
requires the floating point extension facility but the host does not
have it. Factored out function emulation_failure.

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

VEX/priv/guest_s390_toIR.c
VEX/priv/main_main.c
VEX/pub/libvex_emnote.h

index 0aece5b282188561d4363c35a7287bbd6c5d6ebb..e1c82e114372f97a831c737737f875dec43842d5 100644 (file)
@@ -464,6 +464,15 @@ put_fpr_pair(UInt archreg, IRExpr *expr)
    put_fpr_dw0(archreg + 2, low);
 }
 
+/* Terminate the current IRSB with an emulation failure. */
+static void
+emulation_failure(VexEmNote fail_kind)
+{
+   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
+   put_IA(mkaddr_expr(guest_IA_next_instr));
+   dis_res->whatNext = Dis_StopHere;
+   dis_res->jk_StopHere = Ijk_EmFail;
+}
 
 /*------------------------------------------------------------*/
 /*--- IR Debugging aids.                                   ---*/
@@ -8275,12 +8284,15 @@ static HChar *
 s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I32);
-
-   assign(op2, get_gpr_w1(r2));
-   put_fpr_w0(r1, binop(Iop_I32UtoF32, mkU32(encode_rounding_mode(m3)),
-                                       mkexpr(op2)));
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op2 = newTemp(Ity_I32);
 
+      assign(op2, get_gpr_w1(r2));
+      put_fpr_w0(r1, binop(Iop_I32UtoF32, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op2)));
+   }
    return "celfbr";
 }
 
@@ -8288,11 +8300,14 @@ static HChar *
 s390_irgen_CDLFBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I32);
-
-   assign(op2, get_gpr_w1(r2));
-   put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op2 = newTemp(Ity_I32);
 
+      assign(op2, get_gpr_w1(r2));
+      put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
+   }
    return "cdlfbr";
 }
 
@@ -8300,12 +8315,15 @@ static HChar *
 s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I64);
-
-   assign(op2, get_gpr_dw0(r2));
-   put_fpr_w0(r1, binop(Iop_I64UtoF32, mkU32(encode_rounding_mode(m3)),
-                                       mkexpr(op2)));
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op2 = newTemp(Ity_I64);
 
+      assign(op2, get_gpr_dw0(r2));
+      put_fpr_w0(r1, binop(Iop_I64UtoF32, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op2)));
+   }
    return "celgbr";
 }
 
@@ -8313,12 +8331,15 @@ static HChar *
 s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I64);
-
-   assign(op2, get_gpr_dw0(r2));
-   put_fpr_dw0(r1, binop(Iop_I64UtoF64, mkU32(encode_rounding_mode(m3)),
-                                        mkexpr(op2)));
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op2 = newTemp(Ity_I64);
 
+      assign(op2, get_gpr_dw0(r2));
+      put_fpr_dw0(r1, binop(Iop_I64UtoF64, mkU32(encode_rounding_mode(m3)),
+                            mkexpr(op2)));
+   }
    return "cdlgbr";
 }
 
@@ -8326,15 +8347,18 @@ static HChar *
 s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_F32);
-   IRTemp result = newTemp(Ity_I32);
-
-   assign(op, get_fpr_w0(r2));
-   assign(result, binop(Iop_F32toI32U, mkU32(encode_rounding_mode(m3)),
-          mkexpr(op)));
-   put_gpr_w1(r1, mkexpr(result));
-   s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_32, op);
-
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op = newTemp(Ity_F32);
+      IRTemp result = newTemp(Ity_I32);
+
+      assign(op, get_fpr_w0(r2));
+      assign(result, binop(Iop_F32toI32U, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op)));
+      put_gpr_w1(r1, mkexpr(result));
+      s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_32, op);
+   }
    return "clfebr";
 }
 
@@ -8342,15 +8366,18 @@ static HChar *
 s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_F64);
-   IRTemp result = newTemp(Ity_I32);
-
-   assign(op, get_fpr_dw0(r2));
-   assign(result, binop(Iop_F64toI32U, mkU32(encode_rounding_mode(m3)),
-          mkexpr(op)));
-   put_gpr_w1(r1, mkexpr(result));
-   s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_32, op);
-
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op = newTemp(Ity_F64);
+      IRTemp result = newTemp(Ity_I32);
+
+      assign(op, get_fpr_dw0(r2));
+      assign(result, binop(Iop_F64toI32U, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op)));
+      put_gpr_w1(r1, mkexpr(result));
+      s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_32, op);
+   }
    return "clfdbr";
 }
 
@@ -8358,15 +8385,18 @@ static HChar *
 s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_F32);
-   IRTemp result = newTemp(Ity_I64);
-
-   assign(op, get_fpr_w0(r2));
-   assign(result, binop(Iop_F32toI64U, mkU32(encode_rounding_mode(m3)),
-          mkexpr(op)));
-   put_gpr_dw0(r1, mkexpr(result));
-   s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_64, op);
-
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op = newTemp(Ity_F32);
+      IRTemp result = newTemp(Ity_I64);
+
+      assign(op, get_fpr_w0(r2));
+      assign(result, binop(Iop_F32toI64U, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op)));
+      put_gpr_dw0(r1, mkexpr(result));
+      s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_64, op);
+   }
    return "clgebr";
 }
 
@@ -8374,15 +8404,18 @@ static HChar *
 s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_F64);
-   IRTemp result = newTemp(Ity_I64);
-
-   assign(op, get_fpr_dw0(r2));
-   assign(result, binop(Iop_F64toI64U, mkU32(encode_rounding_mode(m3)),
-          mkexpr(op)));
-   put_gpr_dw0(r1, mkexpr(result));
-   s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_64, op);
-
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op = newTemp(Ity_F64);
+      IRTemp result = newTemp(Ity_I64);
+
+      assign(op, get_fpr_dw0(r2));
+      assign(result, binop(Iop_F64toI64U, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op)));
+      put_gpr_dw0(r1, mkexpr(result));
+      s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_64, op);
+   }
    return "clgdbr";
 }
 
@@ -10285,11 +10318,14 @@ static HChar *
 s390_irgen_CXLFBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I32);
-
-   assign(op2, get_gpr_w1(r2));
-   put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op2 = newTemp(Ity_I32);
 
+      assign(op2, get_gpr_w1(r2));
+      put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
+   }
    return "cxlfbr";
 }
 
@@ -10309,11 +10345,14 @@ static HChar *
 s390_irgen_CXLGBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I64);
-
-   assign(op2, get_gpr_dw0(r2));
-   put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op2 = newTemp(Ity_I64);
 
+      assign(op2, get_gpr_dw0(r2));
+      put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
+   }
    return "cxlgbr";
 }
 
@@ -10336,15 +10375,18 @@ static HChar *
 s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_F128);
-   IRTemp result = newTemp(Ity_I32);
-
-   assign(op, get_fpr_pair(r2));
-   assign(result, binop(Iop_F128toI32U, mkU32(encode_rounding_mode(m3)),
-                        mkexpr(op)));
-   put_gpr_w1(r1, mkexpr(result));
-   s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_32, op);
-
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op = newTemp(Ity_F128);
+      IRTemp result = newTemp(Ity_I32);
+
+      assign(op, get_fpr_pair(r2));
+      assign(result, binop(Iop_F128toI32U, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op)));
+      put_gpr_w1(r1, mkexpr(result));
+      s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_32, op);
+   }
    return "clfxbr";
 }
 
@@ -10368,15 +10410,18 @@ static HChar *
 s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_F128);
-   IRTemp result = newTemp(Ity_I64);
-
-   assign(op, get_fpr_pair(r2));
-   assign(result, binop(Iop_F128toI64U, mkU32(encode_rounding_mode(m3)),
-                        mkexpr(op)));
-   put_gpr_dw0(r1, mkexpr(result));
-   s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_64, op);
-
+   if (! s390_host_has_fpext) {
+      emulation_failure(EmFail_S390X_fpext);
+   } else {
+      IRTemp op = newTemp(Ity_F128);
+      IRTemp result = newTemp(Ity_I64);
+
+      assign(op, get_fpr_pair(r2));
+      assign(result, binop(Iop_F128toI64U, mkU32(encode_rounding_mode(m3)),
+                           mkexpr(op)));
+      put_gpr_dw0(r1, mkexpr(result));
+      s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_64, op);
+   }
    return "clgxbr";
 }
 
@@ -10969,11 +11014,7 @@ static HChar *
 s390_irgen_STCKF(IRTemp op2addr)
 {
    if (! s390_host_has_stckf) {
-      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
-           mkU32(EmFail_S390X_stckf)));
-      put_IA(mkaddr_expr(guest_IA_next_instr));
-      dis_res->whatNext = Dis_StopHere;
-      dis_res->jk_StopHere = Ijk_EmFail;
+      emulation_failure(EmFail_S390X_stckf);
    } else {
       IRTemp cc = newTemp(Ity_I64);
 
@@ -11012,11 +11053,7 @@ static HChar *
 s390_irgen_STFLE(IRTemp op2addr)
 {
    if (! s390_host_has_stfle) {
-      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
-           mkU32(EmFail_S390X_stfle)));
-      put_IA(mkaddr_expr(guest_IA_next_instr));
-      dis_res->whatNext = Dis_StopHere;
-      dis_res->jk_StopHere = Ijk_EmFail;
+      emulation_failure(EmFail_S390X_stfle);
       return "stfle";
    }
 
@@ -11979,11 +12016,7 @@ static HChar *
 s390_irgen_ECAG(UChar r1, UChar r3, IRTemp op2addr)
 {
    if (! s390_host_has_gie) {
-      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
-           mkU32(EmFail_S390X_ecag)));
-      put_IA(mkaddr_expr(guest_IA_next_instr));
-      dis_res->whatNext = Dis_StopHere;
-      dis_res->jk_StopHere = Ijk_EmFail;
+      emulation_failure(EmFail_S390X_ecag);
    } else {
       put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
    }
index ef2c121c67367509a48537b53d1834a9df2a7a27..29b971d5e52cfd18bc8de365baf09aadb9b3d0a7 100644 (file)
@@ -1026,12 +1026,16 @@ HChar* LibVEX_EmNote_string ( VexEmNote ew )
         return "PPC64 function redirection stack overflow";
      case EmWarn_PPC64_redir_underflow:
         return "PPC64 function redirection stack underflow";
-   case EmFail_S390X_stfle:
+     case EmFail_S390X_stfle:
         return "Instruction stfle is not supported on this host";
-   case EmFail_S390X_stckf:
+     case EmFail_S390X_stckf:
         return "Instruction stckf is not supported on this host";
-   case EmFail_S390X_ecag:
+     case EmFail_S390X_ecag:
         return "Instruction ecag is not supported on this host";
+     case EmFail_S390X_fpext:
+        return "Encountered an instruction that requires the floating "
+               "point extension facility.\n"
+               "  That facility is not available on this host";
      default: 
         vpanic("LibVEX_EmNote_string: unknown warning");
    }
index f5cf943918fe8e2551b0a28374bcd3f5cfc400ad..bb9cab776af52222feedd3d40cf408251d859473 100644 (file)
@@ -94,6 +94,10 @@ typedef
       /* ecag insn is not supported on this host */
       EmFail_S390X_ecag,
 
+      /* insn needs floating point extension facility which is not
+         available on this host */
+      EmFail_S390X_fpext,
+
       EmNote_NUMBER
    }
    VexEmNote;