]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Clean up machinery to do with conditionalising IRStmts:
authorJulian Seward <jseward@acm.org>
Mon, 11 Nov 2019 15:11:20 +0000 (16:11 +0100)
committerJulian Seward <jseward@acm.org>
Mon, 11 Nov 2019 15:11:20 +0000 (16:11 +0100)
* document some functions

* change naming and terminology from 'speculation' (which it isn't)
  to 'guarding' (which it is)

* add a new function |primopMightTrap| so as to avoid conditionalising
  IRExprs involving potentially trappy IROps

VEX/priv/guest_generic_bb_to_IR.c
VEX/priv/ir_defs.c
VEX/pub/libvex_ir.h

index 4cb813f2aa1f7f2f8c7bdafe20a1db6d3c5c1b13..7782bcf96f8b38373d954131666cfc9c988fa5b0 100644 (file)
@@ -388,29 +388,42 @@ static void create_self_checks_as_needed(
 
 
 /*--------------------------------------------------------------*/
-/*--- To do with speculation of IRStmts                      ---*/
+/*--- To do with guarding (conditionalisation) of IRStmts    ---*/
 /*--------------------------------------------------------------*/
 
-static Bool expr_is_speculatable ( const IRExpr* e )
+// Is it possible to guard |e|?  Meaning, is it safe (exception-free) to compute
+// |e| and ignore the result?  Since |e| is by definition otherwise
+// side-effect-free, we don't have to ask about any other effects caused by
+// first computing |e| and then ignoring the result.
+static Bool expr_is_guardable ( const IRExpr* e )
 {
    switch (e->tag) {
       case Iex_Load:
          return False;
-      case Iex_Unop: // FIXME BOGUS, since it might trap
-      case Iex_Binop: // FIXME ditto
-      case Iex_ITE: // this is OK
-         return True;
+      case Iex_Unop:
+         return !primopMightTrap(e->Iex.Unop.op);
+      case Iex_Binop:
+         return !primopMightTrap(e->Iex.Binop.op);
+      case Iex_ITE:
       case Iex_CCall:
-         return True; // This is probably correct
       case Iex_Get:
          return True;
       default:
-         vex_printf("\n"); ppIRExpr(e);
-         vpanic("expr_is_speculatable: unhandled expr");
+         vex_printf("\n"); ppIRExpr(e); vex_printf("\n");
+         vpanic("expr_is_guardable: unhandled expr");
    }
 }
 
-static Bool stmt_is_speculatable ( const IRStmt* st )
+// Is it possible to guard |st|?  Meaning, is it possible to replace |st| by
+// some other sequence of IRStmts which have the same effect on the architected
+// state when the guard is true, but when it is false, have no effect on the
+// architected state and are guaranteed not to cause any exceptions?
+//
+// Note that this isn't as aggressive as it could be: it sometimes returns False
+// in cases where |st| is actually guardable.  This routine must coordinate
+// closely with add_guarded_stmt_to_end_of below, in the sense that that routine
+// must be able to handle any |st| for which this routine returns True.
+static Bool stmt_is_guardable ( const IRStmt* st )
 {
    switch (st->tag) {
       case Ist_IMark:
@@ -421,35 +434,37 @@ static Bool stmt_is_speculatable ( const IRStmt* st )
       case Ist_Exit: // We could in fact spec this, if required
          return False;
       case Ist_WrTmp:
-         return expr_is_speculatable(st->Ist.WrTmp.data);
+         return expr_is_guardable(st->Ist.WrTmp.data);
       default:
-         vex_printf("\n"); ppIRStmt(st);
-         vpanic("stmt_is_speculatable: unhandled stmt");
+         vex_printf("\n"); ppIRStmt(st); vex_printf("\n");
+         vpanic("stmt_is_guardable: unhandled stmt");
    }
 }
 
-static Bool block_is_speculatable ( const IRSB* bb )
+// Are all stmts (but not the end dst value) in |bb| guardable, per
+// stmt_is_guardable?
+static Bool block_is_guardable ( const IRSB* bb )
 {
    Int i = bb->stmts_used;
-   vassert(i >= 2); // Must have at least: IMark, final Exit
+   vassert(i >= 2); // Must have at least: IMark, side Exit (at the end)
    i--;
    vassert(bb->stmts[i]->tag == Ist_Exit);
    i--;
    for (; i >= 0; i--) {
-      if (!stmt_is_speculatable(bb->stmts[i]))
+      if (!stmt_is_guardable(bb->stmts[i]))
          return False;
    }
    return True;
 }
 
-static void speculate_stmt_to_end_of ( /*MOD*/IRSB* bb,
-                                       /*IN*/ IRStmt* st, IRTemp guard )
+// Guard |st| with |guard| and add it to |bb|.  This must be able to handle any
+// |st| for which stmt_is_guardable returns True.
+static void add_guarded_stmt_to_end_of ( /*MOD*/IRSB* bb,
+                                         /*IN*/ IRStmt* st, IRTemp guard )
 {
-   // We assume all stmts we're presented with here have previously been OK'd by
-   // stmt_is_speculatable above.
    switch (st->tag) {
       case Ist_IMark:
-      case Ist_WrTmp: // FIXME is this ok?
+      case Ist_WrTmp:
          addStmtToIRSB(bb, st);
          break;
       case Ist_Put: {
@@ -472,7 +487,7 @@ static void speculate_stmt_to_end_of ( /*MOD*/IRSB* bb,
       case Ist_Exit: {
          // Exit(xguard, dst, jk, offsIP)
          // ==> t1 = And1(xguard, guard)
-         //     Exit(And1(xguard, guard), dst, jk, offsIP)
+         //     Exit(t1, dst, jk, offsIP)
          IRExpr* xguard = st->Ist.Exit.guard;
          IRTemp t1 = newIRTemp(bb->tyenv, Ity_I1);
          addStmtToIRSB(bb, IRStmt_WrTmp(t1, IRExpr_Binop(Iop_And1, xguard,
@@ -482,8 +497,8 @@ static void speculate_stmt_to_end_of ( /*MOD*/IRSB* bb,
          break;
       }
       default:
-         vex_printf("\n"); ppIRStmt(st);
-         vpanic("speculate_stmt_to_end_of: unhandled stmt");
+         vex_printf("\n"); ppIRStmt(st); vex_printf("\n");
+         vpanic("add_guarded_stmt_to_end_of: unhandled stmt");
    }
 }
 
@@ -1435,10 +1450,10 @@ IRSB* bb_to_IR (
                ppBlockEnd(&sx_be);
                vex_printf("\n");
             }
-            // Finally, check the sx block actually is speculatable.
-            ok = block_is_speculatable(sx_bb);
+            // Finally, check the sx block actually is guardable.
+            ok = block_is_guardable(sx_bb);
             if (!ok && debug_print) {
-               vex_printf("\n-+-+ SX not speculatable, giving up. -+-+\n\n");
+               vex_printf("\n-+-+ SX not guardable, giving up. -+-+\n\n");
             }
          }
 
@@ -1450,10 +1465,10 @@ IRSB* bb_to_IR (
             // 0. remove the last Exit on irsb.
             // 1. Add irsb->tyenv->types_used to all the tmps in sx_bb,
             //    by calling deltaIRStmt on all stmts.
-            // 2. Speculate all stmts in sx_bb on irsb_be.Be.Cond.condSX,
+            // 2. Guard all stmts in sx_bb on irsb_be.Be.Cond.condSX,
             //    **including** the last stmt (which must be an Exit).  It's
             //    here that the And1 is generated.
-            // 3. Copy all speculated stmts to the end of irsb.
+            // 3. Copy all guarded stmts to the end of irsb.
             vassert(irsb->stmts_used >= 2);
             irsb->stmts_used--;
             Int delta = irsb->tyenv->types_used;
@@ -1466,7 +1481,7 @@ IRSB* bb_to_IR (
             for (Int i = 0; i < sx_bb->stmts_used; i++) {
                IRStmt* st = deepCopyIRStmt(sx_bb->stmts[i]);
                deltaIRStmt(st, delta);
-               speculate_stmt_to_end_of(irsb, st, irsb_be.Be.Cond.condSX);
+               add_guarded_stmt_to_end_of(irsb, st, irsb_be.Be.Cond.condSX);
             }
 
             if (debug_print) {
index 603557466309bcf9240176ffefc786d58371db39..d687d8f0a4629f4bafdd66fdc4dc82d7b0e2c3a2 100644 (file)
@@ -1345,6 +1345,432 @@ void ppIROp ( IROp op )
    }
 }
 
+// A very few primops might trap (eg, divide by zero).  We need to be able to
+// identify them.
+Bool primopMightTrap ( IROp op )
+{
+   switch (op) {
+
+   // The few potentially trapping ones
+   case Iop_DivU32: case Iop_DivS32: case Iop_DivU64: case Iop_DivS64:
+   case Iop_DivU64E: case Iop_DivS64E: case Iop_DivU32E: case Iop_DivS32E:
+   case Iop_DivModU64to32: case Iop_DivModS64to32: case Iop_DivModU128to64:
+   case Iop_DivModS128to64: case Iop_DivModS64to64: case Iop_DivModU64to64:
+   case Iop_DivModS32to32: case Iop_DivModU32to32:
+      return True;
+
+   // All the rest are non-trapping
+   case Iop_Add8: case Iop_Add16: case Iop_Add32: case Iop_Add64:
+   case Iop_Sub8: case Iop_Sub16: case Iop_Sub32: case Iop_Sub64:
+   case Iop_Mul8: case Iop_Mul16: case Iop_Mul32: case Iop_Mul64:
+   case Iop_Or8: case Iop_Or16: case Iop_Or32: case Iop_Or64:
+   case Iop_And8: case Iop_And16: case Iop_And32: case Iop_And64:
+   case Iop_Xor8: case Iop_Xor16: case Iop_Xor32: case Iop_Xor64:
+   case Iop_Shl8: case Iop_Shl16: case Iop_Shl32: case Iop_Shl64:
+   case Iop_Shr8: case Iop_Shr16: case Iop_Shr32: case Iop_Shr64:
+   case Iop_Sar8: case Iop_Sar16: case Iop_Sar32: case Iop_Sar64:
+   case Iop_CmpEQ8: case Iop_CmpEQ16: case Iop_CmpEQ32: case Iop_CmpEQ64:
+   case Iop_CmpNE8: case Iop_CmpNE16: case Iop_CmpNE32: case Iop_CmpNE64:
+   case Iop_Not8: case Iop_Not16: case Iop_Not32: case Iop_Not64:
+   case Iop_CasCmpEQ8: case Iop_CasCmpEQ16: case Iop_CasCmpEQ32:
+   case Iop_CasCmpEQ64: case Iop_CasCmpNE8: case Iop_CasCmpNE16:
+   case Iop_CasCmpNE32: case Iop_CasCmpNE64: case Iop_ExpCmpNE8:
+   case Iop_ExpCmpNE16: case Iop_ExpCmpNE32: case Iop_ExpCmpNE64:
+   case Iop_MullS8: case Iop_MullS16: case Iop_MullS32: case Iop_MullS64:
+   case Iop_MullU8: case Iop_MullU16: case Iop_MullU32: case Iop_MullU64:
+   case Iop_Clz64: case Iop_Clz32: case Iop_Ctz64: case Iop_Ctz32:
+   case Iop_ClzNat64: case Iop_ClzNat32: case Iop_CtzNat64: case Iop_CtzNat32:
+   case Iop_PopCount64: case Iop_PopCount32:
+   case Iop_CmpLT32S: case Iop_CmpLT64S: case Iop_CmpLE32S: case Iop_CmpLE64S:
+   case Iop_CmpLT32U: case Iop_CmpLT64U: case Iop_CmpLE32U: case Iop_CmpLE64U:
+   case Iop_CmpNEZ8: case Iop_CmpNEZ16: case Iop_CmpNEZ32: case Iop_CmpNEZ64:
+   case Iop_CmpwNEZ32: case Iop_CmpwNEZ64:
+   case Iop_Left8: case Iop_Left16: case Iop_Left32: case Iop_Left64:
+   case Iop_Max32U: case Iop_CmpORD32U: case Iop_CmpORD64U:
+   case Iop_CmpORD32S: case Iop_CmpORD64S:
+   case Iop_8Uto16: case Iop_8Uto32: case Iop_8Uto64:
+   case Iop_16Uto32: case Iop_16Uto64: case Iop_32Uto64:
+   case Iop_8Sto16: case Iop_8Sto32: case Iop_8Sto64:
+   case Iop_16Sto32: case Iop_16Sto64: case Iop_32Sto64:
+   case Iop_64to8: case Iop_32to8: case Iop_64to16:
+   case Iop_16to8: case Iop_16HIto8: case Iop_8HLto16: case Iop_32to16:
+   case Iop_32HIto16: case Iop_16HLto32: case Iop_64to32: case Iop_64HIto32:
+   case Iop_32HLto64: case Iop_128to64: case Iop_128HIto64: case Iop_64HLto128:
+   case Iop_Not1: case Iop_And1: case Iop_Or1: case Iop_32to1: case Iop_64to1:
+   case Iop_1Uto8: case Iop_1Uto32: case Iop_1Uto64: case Iop_1Sto8:
+   case Iop_1Sto16: case Iop_1Sto32: case Iop_1Sto64:
+   case Iop_AddF64: case Iop_SubF64: case Iop_MulF64: case Iop_DivF64:
+   case Iop_AddF32: case Iop_SubF32: case Iop_MulF32: case Iop_DivF32:
+   case Iop_AddF64r32: case Iop_SubF64r32: case Iop_MulF64r32:
+   case Iop_DivF64r32: case Iop_NegF64: case Iop_AbsF64:
+   case Iop_NegF32: case Iop_AbsF32: case Iop_SqrtF64: case Iop_SqrtF32:
+   case Iop_CmpF64: case Iop_CmpF32: case Iop_CmpF128: case Iop_F64toI16S:
+   case Iop_F64toI32S: case Iop_F64toI64S: case Iop_F64toI64U:
+   case Iop_F64toI32U: case Iop_I32StoF64: case Iop_I64StoF64:
+   case Iop_I64UtoF64: case Iop_I64UtoF32: case Iop_I32UtoF32:
+   case Iop_I32UtoF64: case Iop_F32toI32S: case Iop_F32toI64S:
+   case Iop_F32toI32U: case Iop_F32toI64U: case Iop_I32StoF32:
+   case Iop_I64StoF32: case Iop_F32toF64: case Iop_F64toF32:
+   case Iop_ReinterpF64asI64: case Iop_ReinterpI64asF64:
+   case Iop_ReinterpF32asI32: case Iop_ReinterpI32asF32:
+   case Iop_F64HLtoF128: case Iop_F128HItoF64: case Iop_F128LOtoF64:
+   case Iop_AddF128: case Iop_SubF128: case Iop_MulF128: case Iop_DivF128:
+   case Iop_MAddF128: case Iop_MSubF128: case Iop_NegMAddF128:
+   case Iop_NegMSubF128: case Iop_NegF128: case Iop_AbsF128:
+   case Iop_SqrtF128: case Iop_I32StoF128: case Iop_I64StoF128:
+   case Iop_I32UtoF128: case Iop_I64UtoF128: case Iop_F32toF128:
+   case Iop_F64toF128: case Iop_F128toI32S: case Iop_F128toI64S:
+   case Iop_F128toI32U: case Iop_F128toI64U: case Iop_F128toI128S:
+   case Iop_F128toF64: case Iop_F128toF32: case Iop_RndF128:
+   case Iop_TruncF128toI32S: case Iop_TruncF128toI32U: case Iop_TruncF128toI64U:
+   case Iop_TruncF128toI64S: case Iop_AtanF64: case Iop_Yl2xF64:
+   case Iop_Yl2xp1F64: case Iop_PRemF64: case Iop_PRemC3210F64:
+   case Iop_PRem1F64: case Iop_PRem1C3210F64: case Iop_ScaleF64:
+   case Iop_SinF64: case Iop_CosF64: case Iop_TanF64:
+   case Iop_2xm1F64: case Iop_RoundF128toInt: case Iop_RoundF64toInt:
+   case Iop_RoundF32toInt: case Iop_MAddF32: case Iop_MSubF32:
+   case Iop_MAddF64: case Iop_MSubF64:
+   case Iop_MAddF64r32: case Iop_MSubF64r32:
+   case Iop_RSqrtEst5GoodF64: case Iop_RoundF64toF64_NEAREST:
+   case Iop_RoundF64toF64_NegINF: case Iop_RoundF64toF64_PosINF:
+   case Iop_RoundF64toF64_ZERO: case Iop_TruncF64asF32: case Iop_RoundF64toF32:
+   case Iop_RecpExpF64: case Iop_RecpExpF32: case Iop_MaxNumF64:
+   case Iop_MinNumF64: case Iop_MaxNumF32: case Iop_MinNumF32:
+   case Iop_F16toF64: case Iop_F64toF16: case Iop_F16toF32:
+   case Iop_F32toF16: case Iop_QAdd32S: case Iop_QSub32S:
+   case Iop_Add16x2: case Iop_Sub16x2:
+   case Iop_QAdd16Sx2: case Iop_QAdd16Ux2:
+   case Iop_QSub16Sx2: case Iop_QSub16Ux2:
+   case Iop_HAdd16Ux2: case Iop_HAdd16Sx2:
+   case Iop_HSub16Ux2: case Iop_HSub16Sx2:
+   case Iop_Add8x4: case Iop_Sub8x4:
+   case Iop_QAdd8Sx4: case Iop_QAdd8Ux4:
+   case Iop_QSub8Sx4: case Iop_QSub8Ux4:
+   case Iop_HAdd8Ux4: case Iop_HAdd8Sx4:
+   case Iop_HSub8Ux4: case Iop_HSub8Sx4: case Iop_Sad8Ux4:
+   case Iop_CmpNEZ16x2: case Iop_CmpNEZ8x4: case Iop_Reverse8sIn32_x1:
+   case Iop_I32UtoF32x2_DEP: case Iop_I32StoF32x2_DEP:
+   case Iop_F32toI32Ux2_RZ: case Iop_F32toI32Sx2_RZ:
+   case Iop_F32ToFixed32Ux2_RZ: case Iop_F32ToFixed32Sx2_RZ:
+   case Iop_Fixed32UToF32x2_RN: case Iop_Fixed32SToF32x2_RN:
+   case Iop_Max32Fx2:  case Iop_Min32Fx2:
+   case Iop_PwMax32Fx2: case Iop_PwMin32Fx2:
+   case Iop_CmpEQ32Fx2: case Iop_CmpGT32Fx2: case Iop_CmpGE32Fx2:
+   case Iop_RecipEst32Fx2: case Iop_RecipStep32Fx2: case Iop_RSqrtEst32Fx2:
+   case Iop_RSqrtStep32Fx2: case Iop_Neg32Fx2: case Iop_Abs32Fx2:
+   case Iop_CmpNEZ8x8: case Iop_CmpNEZ16x4: case Iop_CmpNEZ32x2:
+   case Iop_Add8x8: case Iop_Add16x4: case Iop_Add32x2:
+   case Iop_QAdd8Ux8: case Iop_QAdd16Ux4: case Iop_QAdd32Ux2: case Iop_QAdd64Ux1:
+   case Iop_QAdd8Sx8: case Iop_QAdd16Sx4: case Iop_QAdd32Sx2: case Iop_QAdd64Sx1:
+   case Iop_PwAdd8x8: case Iop_PwAdd16x4: case Iop_PwAdd32x2:
+   case Iop_PwMax8Sx8: case Iop_PwMax16Sx4: case Iop_PwMax32Sx2:
+   case Iop_PwMax8Ux8: case Iop_PwMax16Ux4: case Iop_PwMax32Ux2:
+   case Iop_PwMin8Sx8: case Iop_PwMin16Sx4: case Iop_PwMin32Sx2:
+   case Iop_PwMin8Ux8: case Iop_PwMin16Ux4: case Iop_PwMin32Ux2:
+   case Iop_PwAddL8Ux8: case Iop_PwAddL16Ux4: case Iop_PwAddL32Ux2:
+   case Iop_PwAddL8Sx8: case Iop_PwAddL16Sx4: case Iop_PwAddL32Sx2:
+   case Iop_Sub8x8: case Iop_Sub16x4: case Iop_Sub32x2:
+   case Iop_QSub8Ux8: case Iop_QSub16Ux4: case Iop_QSub32Ux2: case Iop_QSub64Ux1:
+   case Iop_QSub8Sx8: case Iop_QSub16Sx4: case Iop_QSub32Sx2: case Iop_QSub64Sx1:
+   case Iop_Abs8x8: case Iop_Abs16x4: case Iop_Abs32x2:
+   case Iop_Mul8x8: case Iop_Mul16x4: case Iop_Mul32x2:
+   case Iop_Mul32Fx2: case Iop_MulHi16Ux4: case Iop_MulHi16Sx4:
+   case Iop_PolynomialMul8x8: case Iop_QDMulHi16Sx4: case Iop_QDMulHi32Sx2:
+   case Iop_QRDMulHi16Sx4: case Iop_QRDMulHi32Sx2: case Iop_Avg8Ux8:
+   case Iop_Avg16Ux4: case Iop_Max8Sx8: case Iop_Max16Sx4: case Iop_Max32Sx2:
+   case Iop_Max8Ux8: case Iop_Max16Ux4: case Iop_Max32Ux2:
+   case Iop_Min8Sx8: case Iop_Min16Sx4: case Iop_Min32Sx2:
+   case Iop_Min8Ux8: case Iop_Min16Ux4: case Iop_Min32Ux2:
+   case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2:
+   case Iop_CmpGT8Ux8: case Iop_CmpGT16Ux4: case Iop_CmpGT32Ux2:
+   case Iop_CmpGT8Sx8: case Iop_CmpGT16Sx4: case Iop_CmpGT32Sx2:
+   case Iop_Cnt8x8: case Iop_Clz8x8: case Iop_Clz16x4: case Iop_Clz32x2:
+   case Iop_Cls8x8: case Iop_Cls16x4: case Iop_Cls32x2: case Iop_Clz64x2:
+   case Iop_Ctz8x16: case Iop_Ctz16x8: case Iop_Ctz32x4: case Iop_Ctz64x2:
+   case Iop_Shl8x8: case Iop_Shl16x4: case Iop_Shl32x2:
+   case Iop_Shr8x8: case Iop_Shr16x4: case Iop_Shr32x2:
+   case Iop_Sar8x8: case Iop_Sar16x4: case Iop_Sar32x2:
+   case Iop_Sal8x8: case Iop_Sal16x4: case Iop_Sal32x2: case Iop_Sal64x1:
+   case Iop_ShlN8x8: case Iop_ShlN16x4: case Iop_ShlN32x2:
+   case Iop_ShrN8x8: case Iop_ShrN16x4: case Iop_ShrN32x2:
+   case Iop_SarN8x8: case Iop_SarN16x4: case Iop_SarN32x2:
+   case Iop_QShl8x8: case Iop_QShl16x4: case Iop_QShl32x2: case Iop_QShl64x1:
+   case Iop_QSal8x8: case Iop_QSal16x4: case Iop_QSal32x2: case Iop_QSal64x1:
+   case Iop_QShlNsatSU8x8: case Iop_QShlNsatSU16x4:
+   case Iop_QShlNsatSU32x2: case Iop_QShlNsatSU64x1:
+   case Iop_QShlNsatUU8x8: case Iop_QShlNsatUU16x4:
+   case Iop_QShlNsatUU32x2: case Iop_QShlNsatUU64x1:
+   case Iop_QShlNsatSS8x8: case Iop_QShlNsatSS16x4:
+   case Iop_QShlNsatSS32x2: case Iop_QShlNsatSS64x1:
+   case Iop_QNarrowBin16Sto8Ux8:
+   case Iop_QNarrowBin16Sto8Sx8: case Iop_QNarrowBin32Sto16Sx4:
+   case Iop_NarrowBin16to8x8: case Iop_NarrowBin32to16x4:
+   case Iop_InterleaveHI8x8: case Iop_InterleaveHI16x4:
+   case Iop_InterleaveHI32x2:
+   case Iop_InterleaveLO8x8: case Iop_InterleaveLO16x4:
+   case Iop_InterleaveLO32x2:
+   case Iop_InterleaveOddLanes8x8: case Iop_InterleaveEvenLanes8x8:
+   case Iop_InterleaveOddLanes16x4: case Iop_InterleaveEvenLanes16x4:
+   case Iop_CatOddLanes8x8: case Iop_CatOddLanes16x4:
+   case Iop_CatEvenLanes8x8: case Iop_CatEvenLanes16x4:
+   case Iop_GetElem8x8: case Iop_GetElem16x4: case Iop_GetElem32x2:
+   case Iop_SetElem8x8: case Iop_SetElem16x4: case Iop_SetElem32x2:
+   case Iop_Dup8x8: case Iop_Dup16x4: case Iop_Dup32x2:
+   case Iop_Slice64: case Iop_Reverse8sIn16_x4:
+   case Iop_Reverse8sIn32_x2: case Iop_Reverse16sIn32_x2:
+   case Iop_Reverse8sIn64_x1: case Iop_Reverse16sIn64_x1:
+   case Iop_Reverse32sIn64_x1: case Iop_Perm8x8: case Iop_PermOrZero8x8:
+   case Iop_GetMSBs8x8: case Iop_RecipEst32Ux2: case Iop_RSqrtEst32Ux2:
+   case Iop_AddD64: case Iop_SubD64: case Iop_MulD64: case Iop_DivD64:
+   case Iop_AddD128: case Iop_SubD128: case Iop_MulD128: case Iop_DivD128:
+   case Iop_ShlD64: case Iop_ShrD64:
+   case Iop_ShlD128: case Iop_ShrD128:
+   case Iop_D32toD64: case Iop_D64toD128: case Iop_I32StoD128:
+   case Iop_I32UtoD128: case Iop_I64StoD128: case Iop_I64UtoD128:
+   case Iop_D64toD32: case Iop_D128toD64: case Iop_I32StoD64:
+   case Iop_I32UtoD64: case Iop_I64StoD64: case Iop_I64UtoD64:
+   case Iop_D64toI32S: case Iop_D64toI32U: case Iop_D64toI64S:
+   case Iop_D64toI64U: case Iop_D128toI32S: case Iop_D128toI32U:
+   case Iop_D128toI64S: case Iop_D128toI64U: case Iop_F32toD32:
+   case Iop_F32toD64: case Iop_F32toD128: case Iop_F64toD32:
+   case Iop_F64toD64: case Iop_F64toD128: case Iop_F128toD32:
+   case Iop_F128toD64: case Iop_F128toD128: case Iop_D32toF32:
+   case Iop_D32toF64: case Iop_D32toF128: case Iop_D64toF32: case Iop_D64toF64:
+   case Iop_D64toF128: case Iop_D128toF32: case Iop_D128toF64:
+   case Iop_D128toF128: case Iop_RoundD64toInt: case Iop_RoundD128toInt:
+   case Iop_CmpD64: case Iop_CmpD128: case Iop_CmpExpD64:
+   case Iop_CmpExpD128: case Iop_QuantizeD64: case Iop_QuantizeD128:
+   case Iop_SignificanceRoundD64: case Iop_SignificanceRoundD128:
+   case Iop_ExtractExpD64: case Iop_ExtractExpD128: case Iop_ExtractSigD64:
+   case Iop_ExtractSigD128: case Iop_InsertExpD64: case Iop_InsertExpD128:
+   case Iop_D64HLtoD128: case Iop_D128HItoD64: case Iop_D128LOtoD64:
+   case Iop_DPBtoBCD: case Iop_BCDtoDPB: case Iop_BCDAdd: case Iop_BCDSub:
+   case Iop_I128StoBCD128: case Iop_BCD128toI128S: case Iop_ReinterpI64asD64:
+   case Iop_ReinterpD64asI64:
+   case Iop_Add32Fx4: case Iop_Sub32Fx4: case Iop_Mul32Fx4: case Iop_Div32Fx4:
+   case Iop_Max32Fx4: case Iop_Min32Fx4:
+   case Iop_Add32Fx2: case Iop_Sub32Fx2:
+   case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4:
+   case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4:
+   case Iop_CmpGT32Fx4: case Iop_CmpGE32Fx4:
+   case Iop_PwMax32Fx4: case Iop_PwMin32Fx4:
+   case Iop_Abs32Fx4: case Iop_Neg32Fx4: case Iop_Sqrt32Fx4:
+   case Iop_RecipEst32Fx4: case Iop_RecipStep32Fx4: case Iop_RSqrtEst32Fx4:
+   case Iop_Scale2_32Fx4: case Iop_Log2_32Fx4: case Iop_Exp2_32Fx4:
+   case Iop_RSqrtStep32Fx4:
+   case Iop_I32UtoF32x4_DEP: case Iop_I32StoF32x4_DEP: case Iop_I32StoF32x4: 
+   case Iop_F32toI32Sx4: case Iop_F32toI32Ux4_RZ: case Iop_F32toI32Sx4_RZ:
+   case Iop_QF32toI32Ux4_RZ: case Iop_QF32toI32Sx4_RZ:
+   case Iop_RoundF32x4_RM: case Iop_RoundF32x4_RP:
+   case Iop_RoundF32x4_RN: case Iop_RoundF32x4_RZ:
+   case Iop_F32ToFixed32Ux4_RZ: case Iop_F32ToFixed32Sx4_RZ:
+   case Iop_Fixed32UToF32x4_RN: case Iop_Fixed32SToF32x4_RN:
+   case Iop_F32toF16x4_DEP: case Iop_F32toF16x4: case Iop_F16toF32x4:
+   case Iop_F64toF16x2_DEP: case Iop_F16toF64x2: case Iop_F32x4_2toQ16x8:
+   case Iop_Add32F0x4: case Iop_Sub32F0x4: case Iop_Mul32F0x4:
+   case Iop_Div32F0x4: case Iop_Max32F0x4: case Iop_Min32F0x4:
+   case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4: case Iop_CmpLE32F0x4:
+   case Iop_CmpUN32F0x4:
+   case Iop_RecipEst32F0x4: case Iop_Sqrt32F0x4: case Iop_RSqrtEst32F0x4:
+   case Iop_Add64Fx2: case Iop_Sub64Fx2: case Iop_Mul64Fx2: case Iop_Div64Fx2:
+   case Iop_Max64Fx2: case Iop_Min64Fx2:
+   case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2: case Iop_CmpLE64Fx2:
+   case Iop_CmpUN64Fx2: case Iop_Abs64Fx2: case Iop_Neg64Fx2:
+   case Iop_Sqrt64Fx2: case Iop_Scale2_64Fx2: case Iop_Log2_64Fx2:
+   case Iop_RecipEst64Fx2: case Iop_RecipStep64Fx2: case Iop_RSqrtEst64Fx2:
+   case Iop_RSqrtStep64Fx2: case Iop_F64x2_2toQ32x4:
+   case Iop_Add64F0x2: case Iop_Sub64F0x2: case Iop_Mul64F0x2:
+   case Iop_Div64F0x2: case Iop_Max64F0x2: case Iop_Min64F0x2:
+   case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2: case Iop_CmpLE64F0x2:
+   case Iop_CmpUN64F0x2: case Iop_Sqrt64F0x2: case Iop_V128to64:
+   case Iop_V128HIto64: case Iop_64HLtoV128: case Iop_64UtoV128:
+   case Iop_SetV128lo64: case Iop_ZeroHI64ofV128: case Iop_ZeroHI96ofV128:
+   case Iop_ZeroHI112ofV128: case Iop_ZeroHI120ofV128: case Iop_32UtoV128:
+   case Iop_V128to32: case Iop_SetV128lo32: case Iop_NotV128:
+   case Iop_AndV128: case Iop_OrV128: case Iop_XorV128:
+   case Iop_ShlV128: case Iop_ShrV128: case Iop_SarV128:
+   case Iop_CmpNEZ8x16: case Iop_CmpNEZ16x8: case Iop_CmpNEZ32x4:
+   case Iop_CmpNEZ64x2: case Iop_CmpNEZ128x1:
+   case Iop_Add8x16: case Iop_Add16x8: case Iop_Add32x4:
+   case Iop_Add64x2: case Iop_Add128x1:
+   case Iop_QAdd8Ux16: case Iop_QAdd16Ux8: case Iop_QAdd32Ux4:
+   case Iop_QAdd64Ux2:
+   case Iop_QAdd8Sx16: case Iop_QAdd16Sx8: case Iop_QAdd32Sx4:
+   case Iop_QAdd64Sx2:
+   case Iop_QAddExtUSsatSS8x16: case Iop_QAddExtUSsatSS16x8:
+   case Iop_QAddExtUSsatSS32x4: case Iop_QAddExtUSsatSS64x2:
+   case Iop_QAddExtSUsatUU8x16: case Iop_QAddExtSUsatUU16x8:
+   case Iop_QAddExtSUsatUU32x4: case Iop_QAddExtSUsatUU64x2:
+   case Iop_Sub8x16: case Iop_Sub16x8: case Iop_Sub32x4:
+   case Iop_Sub64x2: case Iop_Sub128x1:
+   case Iop_QSub8Ux16: case Iop_QSub16Ux8: case Iop_QSub32Ux4:
+   case Iop_QSub64Ux2:
+   case Iop_QSub8Sx16: case Iop_QSub16Sx8: case Iop_QSub32Sx4:
+   case Iop_QSub64Sx2:
+   case Iop_Mul8x16: case Iop_Mul16x8: case Iop_Mul32x4:
+   case Iop_MulHi8Ux16: case Iop_MulHi16Ux8: case Iop_MulHi32Ux4:
+   case Iop_MulHi8Sx16: case Iop_MulHi16Sx8: case Iop_MulHi32Sx4:
+   case Iop_MullEven8Ux16: case Iop_MullEven16Ux8: case Iop_MullEven32Ux4:
+   case Iop_MullEven8Sx16: case Iop_MullEven16Sx8: case Iop_MullEven32Sx4:
+   case Iop_Mull8Ux8: case Iop_Mull8Sx8:
+   case Iop_Mull16Ux4: case Iop_Mull16Sx4:
+   case Iop_Mull32Ux2: case Iop_Mull32Sx2:
+   case Iop_QDMull16Sx4: case Iop_QDMull32Sx2:
+   case Iop_QDMulHi16Sx8: case Iop_QDMulHi32Sx4:
+   case Iop_QRDMulHi16Sx8: case Iop_QRDMulHi32Sx4:
+   case Iop_PolynomialMul8x16: case Iop_PolynomialMull8x8:
+   case Iop_PolynomialMulAdd8x16: case Iop_PolynomialMulAdd16x8:
+   case Iop_PolynomialMulAdd32x4: case Iop_PolynomialMulAdd64x2:
+   case Iop_PwAdd8x16: case Iop_PwAdd16x8: case Iop_PwAdd32x4:
+   case Iop_PwAdd32Fx2: case Iop_PwAddL8Ux16: case Iop_PwAddL16Ux8:
+   case Iop_PwAddL32Ux4: case Iop_PwAddL64Ux2:
+   case Iop_PwAddL8Sx16: case Iop_PwAddL16Sx8: case Iop_PwAddL32Sx4:
+   case Iop_PwExtUSMulQAdd8x16:
+   case Iop_PwBitMtxXpose64x2:
+   case Iop_Abs8x16: case Iop_Abs16x8: case Iop_Abs32x4: case Iop_Abs64x2:
+   case Iop_Avg8Ux16: case Iop_Avg16Ux8: case Iop_Avg32Ux4: case Iop_Avg64Ux2:
+   case Iop_Avg8Sx16: case Iop_Avg16Sx8: case Iop_Avg32Sx4: case Iop_Avg64Sx2:
+   case Iop_Max8Sx16: case Iop_Max16Sx8: case Iop_Max32Sx4: case Iop_Max64Sx2:
+   case Iop_Max8Ux16: case Iop_Max16Ux8: case Iop_Max32Ux4: case Iop_Max64Ux2:
+   case Iop_Min8Sx16: case Iop_Min16Sx8: case Iop_Min32Sx4: case Iop_Min64Sx2:
+   case Iop_Min8Ux16: case Iop_Min16Ux8: case Iop_Min32Ux4: case Iop_Min64Ux2:
+   case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4:
+   case Iop_CmpEQ64x2:
+   case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4:
+   case Iop_CmpGT64Sx2:
+   case Iop_CmpGT8Ux16: case Iop_CmpGT16Ux8: case Iop_CmpGT32Ux4:
+   case Iop_CmpGT64Ux2:
+   case Iop_Cnt8x16:
+   case Iop_Clz8x16: case Iop_Clz16x8: case Iop_Clz32x4:
+   case Iop_Cls8x16: case Iop_Cls16x8: case Iop_Cls32x4:
+   case Iop_ShlN8x16: case Iop_ShlN16x8: case Iop_ShlN32x4: case Iop_ShlN64x2:
+   case Iop_ShrN8x16: case Iop_ShrN16x8: case Iop_ShrN32x4: case Iop_ShrN64x2:
+   case Iop_SarN8x16: case Iop_SarN16x8: case Iop_SarN32x4: case Iop_SarN64x2:
+   case Iop_Shl8x16: case Iop_Shl16x8: case Iop_Shl32x4: case Iop_Shl64x2:
+   case Iop_Shr8x16: case Iop_Shr16x8: case Iop_Shr32x4: case Iop_Shr64x2:
+   case Iop_Sar8x16: case Iop_Sar16x8: case Iop_Sar32x4: case Iop_Sar64x2:
+   case Iop_Sal8x16: case Iop_Sal16x8: case Iop_Sal32x4: case Iop_Sal64x2:
+   case Iop_Rol8x16: case Iop_Rol16x8: case Iop_Rol32x4: case Iop_Rol64x2:
+   case Iop_QShl8x16: case Iop_QShl16x8: case Iop_QShl32x4: case Iop_QShl64x2:
+   case Iop_QSal8x16: case Iop_QSal16x8: case Iop_QSal32x4: case Iop_QSal64x2:
+   case Iop_QShlNsatSU8x16: case Iop_QShlNsatSU16x8:
+   case Iop_QShlNsatSU32x4: case Iop_QShlNsatSU64x2:
+   case Iop_QShlNsatUU8x16: case Iop_QShlNsatUU16x8:
+   case Iop_QShlNsatUU32x4: case Iop_QShlNsatUU64x2:
+   case Iop_QShlNsatSS8x16: case Iop_QShlNsatSS16x8:
+   case Iop_QShlNsatSS32x4: case Iop_QShlNsatSS64x2:
+   case Iop_QandUQsh8x16: case Iop_QandUQsh16x8:
+   case Iop_QandUQsh32x4: case Iop_QandUQsh64x2:
+   case Iop_QandSQsh8x16: case Iop_QandSQsh16x8:
+   case Iop_QandSQsh32x4: case Iop_QandSQsh64x2:
+   case Iop_QandUQRsh8x16: case Iop_QandUQRsh16x8:
+   case Iop_QandUQRsh32x4: case Iop_QandUQRsh64x2:
+   case Iop_QandSQRsh8x16: case Iop_QandSQRsh16x8:
+   case Iop_QandSQRsh32x4: case Iop_QandSQRsh64x2:
+   case Iop_Sh8Sx16: case Iop_Sh16Sx8: case Iop_Sh32Sx4: case Iop_Sh64Sx2:
+   case Iop_Sh8Ux16: case Iop_Sh16Ux8: case Iop_Sh32Ux4: case Iop_Sh64Ux2:
+   case Iop_Rsh8Sx16: case Iop_Rsh16Sx8: case Iop_Rsh32Sx4: case Iop_Rsh64Sx2:
+   case Iop_Rsh8Ux16: case Iop_Rsh16Ux8: case Iop_Rsh32Ux4: case Iop_Rsh64Ux2:
+   case Iop_QandQShrNnarrow16Uto8Ux8:
+   case Iop_QandQShrNnarrow32Uto16Ux4: case Iop_QandQShrNnarrow64Uto32Ux2:
+   case Iop_QandQSarNnarrow16Sto8Sx8:
+   case Iop_QandQSarNnarrow32Sto16Sx4: case Iop_QandQSarNnarrow64Sto32Sx2:
+   case Iop_QandQSarNnarrow16Sto8Ux8:
+   case Iop_QandQSarNnarrow32Sto16Ux4: case Iop_QandQSarNnarrow64Sto32Ux2:
+   case Iop_QandQRShrNnarrow16Uto8Ux8:
+   case Iop_QandQRShrNnarrow32Uto16Ux4: case Iop_QandQRShrNnarrow64Uto32Ux2:
+   case Iop_QandQRSarNnarrow16Sto8Sx8:
+   case Iop_QandQRSarNnarrow32Sto16Sx4: case Iop_QandQRSarNnarrow64Sto32Sx2:
+   case Iop_QandQRSarNnarrow16Sto8Ux8:
+   case Iop_QandQRSarNnarrow32Sto16Ux4: case Iop_QandQRSarNnarrow64Sto32Ux2:
+   case Iop_QNarrowBin16Sto8Ux16: case Iop_QNarrowBin32Sto16Ux8:
+   case Iop_QNarrowBin16Sto8Sx16: case Iop_QNarrowBin32Sto16Sx8:
+   case Iop_QNarrowBin16Uto8Ux16: case Iop_QNarrowBin32Uto16Ux8:
+   case Iop_NarrowBin16to8x16: case Iop_NarrowBin32to16x8:
+   case Iop_QNarrowBin64Sto32Sx4: case Iop_QNarrowBin64Uto32Ux4:
+   case Iop_NarrowBin64to32x4:
+   case Iop_NarrowUn16to8x8: case Iop_NarrowUn32to16x4:
+   case Iop_NarrowUn64to32x2:
+   case Iop_QNarrowUn16Sto8Sx8: case Iop_QNarrowUn32Sto16Sx4:
+   case Iop_QNarrowUn64Sto32Sx2:
+   case Iop_QNarrowUn16Sto8Ux8: case Iop_QNarrowUn32Sto16Ux4:
+   case Iop_QNarrowUn64Sto32Ux2:
+   case Iop_QNarrowUn16Uto8Ux8: case Iop_QNarrowUn32Uto16Ux4:
+   case Iop_QNarrowUn64Uto32Ux2:
+   case Iop_Widen8Uto16x8: case Iop_Widen16Uto32x4: case Iop_Widen32Uto64x2:
+   case Iop_Widen8Sto16x8: case Iop_Widen16Sto32x4: case Iop_Widen32Sto64x2:
+   case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8:
+   case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
+   case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8:
+   case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
+   case Iop_InterleaveOddLanes8x16: case Iop_InterleaveEvenLanes8x16:
+   case Iop_InterleaveOddLanes16x8: case Iop_InterleaveEvenLanes16x8:
+   case Iop_InterleaveOddLanes32x4: case Iop_InterleaveEvenLanes32x4:
+   case Iop_PackOddLanes8x16: case Iop_PackEvenLanes8x16:
+   case Iop_PackOddLanes16x8: case Iop_PackEvenLanes16x8:
+   case Iop_PackOddLanes32x4: case Iop_PackEvenLanes32x4:
+   case Iop_CatOddLanes8x16: case Iop_CatOddLanes16x8: case Iop_CatOddLanes32x4:
+   case Iop_CatEvenLanes8x16: case Iop_CatEvenLanes16x8:
+   case Iop_CatEvenLanes32x4:
+   case Iop_GetElem8x16: case Iop_GetElem16x8: case Iop_GetElem32x4:
+   case Iop_GetElem64x2:
+   case Iop_SetElem8x16: case Iop_SetElem16x8: case Iop_SetElem32x4:
+   case Iop_SetElem64x2:
+   case Iop_Dup8x16: case Iop_Dup16x8: case Iop_Dup32x4:
+   case Iop_SliceV128: case Iop_Reverse8sIn16_x8:
+   case Iop_Reverse8sIn32_x4: case Iop_Reverse16sIn32_x4:
+   case Iop_Reverse8sIn64_x2: case Iop_Reverse16sIn64_x2:
+   case Iop_Reverse32sIn64_x2: case Iop_Reverse1sIn8_x16: case Iop_Perm8x16:
+   case Iop_Perm32x4: case Iop_PermOrZero8x16: case Iop_Perm8x16x2:
+   case Iop_GetMSBs8x16: case Iop_RecipEst32Ux4: case Iop_RSqrtEst32Ux4:
+   case Iop_MulI128by10: case Iop_MulI128by10Carry: case Iop_MulI128by10E:
+   case Iop_MulI128by10ECarry: case Iop_V256to64_0: case Iop_V256to64_1:
+   case Iop_V256to64_2: case Iop_V256to64_3: case Iop_64x4toV256:
+   case Iop_V256toV128_0: case Iop_V256toV128_1: case Iop_V128HLtoV256:
+   case Iop_AndV256: case Iop_OrV256: case Iop_XorV256:
+   case Iop_NotV256:
+   case Iop_CmpNEZ8x32: case Iop_CmpNEZ16x16: case Iop_CmpNEZ32x8:
+   case Iop_CmpNEZ64x4:
+   case Iop_Add8x32: case Iop_Add16x16: case Iop_Add32x8: case Iop_Add64x4:
+   case Iop_Sub8x32: case Iop_Sub16x16: case Iop_Sub32x8: case Iop_Sub64x4:
+   case Iop_CmpEQ8x32: case Iop_CmpEQ16x16: case Iop_CmpEQ32x8:
+   case Iop_CmpEQ64x4:
+   case Iop_CmpGT8Sx32: case Iop_CmpGT16Sx16: case Iop_CmpGT32Sx8:
+   case Iop_CmpGT64Sx4:
+   case Iop_ShlN16x16: case Iop_ShlN32x8: case Iop_ShlN64x4:
+   case Iop_ShrN16x16: case Iop_ShrN32x8: case Iop_ShrN64x4:
+   case Iop_SarN16x16: case Iop_SarN32x8:
+   case Iop_Max8Sx32: case Iop_Max16Sx16: case Iop_Max32Sx8:
+   case Iop_Max8Ux32: case Iop_Max16Ux16: case Iop_Max32Ux8:
+   case Iop_Min8Sx32: case Iop_Min16Sx16: case Iop_Min32Sx8:
+   case Iop_Min8Ux32: case Iop_Min16Ux16: case Iop_Min32Ux8:
+   case Iop_Mul16x16: case Iop_Mul32x8:
+   case Iop_MulHi16Ux16: case Iop_MulHi16Sx16:
+   case Iop_QAdd8Ux32: case Iop_QAdd16Ux16:
+   case Iop_QAdd8Sx32: case Iop_QAdd16Sx16:
+   case Iop_QSub8Ux32: case Iop_QSub16Ux16:
+   case Iop_QSub8Sx32: case Iop_QSub16Sx16:
+   case Iop_Avg8Ux32: case Iop_Avg16Ux16:
+   case Iop_Perm32x8:
+   case Iop_CipherV128: case Iop_CipherLV128: case Iop_CipherSV128:
+   case Iop_NCipherV128: case Iop_NCipherLV128:
+   case Iop_SHA512: case Iop_SHA256:
+   case Iop_Add64Fx4: case Iop_Sub64Fx4: case Iop_Mul64Fx4: case Iop_Div64Fx4:
+   case Iop_Add32Fx8: case Iop_Sub32Fx8: case Iop_Mul32Fx8: case Iop_Div32Fx8:
+   case Iop_I32StoF32x8: case Iop_F32toI32Sx8: case Iop_F32toF16x8:
+   case Iop_F16toF32x8: case Iop_Sqrt32Fx8: case Iop_Sqrt64Fx4:
+   case Iop_RSqrtEst32Fx8: case Iop_RecipEst32Fx8:
+   case Iop_Max32Fx8: case Iop_Min32Fx8:
+   case Iop_Max64Fx4: case Iop_Min64Fx4:
+   case Iop_Rotx32: case Iop_Rotx64:
+      return False;
+
+   default:
+      vpanic("primopMightTrap");
+
+   }
+}
+
 void ppIRExpr ( const IRExpr* e )
 {
   Int i;
index 087a414573b77127d5307468c7a586d2a8809f30..9120a49fc422658bb69c06a8b6774f25a6f58e0e 100644 (file)
@@ -2013,6 +2013,11 @@ extern void typeOfPrimop ( IROp op,
                            /*OUTs*/ IRType* t_dst, IRType* t_arg1,
                            IRType* t_arg2, IRType* t_arg3, IRType* t_arg4 );
 
+/* Might the given primop trap (eg, attempt integer division by zero)?  If in
+   doubt returns True.  However, the vast majority of primops will never
+   trap. */
+extern Bool primopMightTrap ( IROp op );
+
 /* Encoding of IEEE754-specified rounding modes.
    Note, various front and back ends rely on the actual numerical
    values of these, so do not change them. */