Eliminate IRExprP__VECRET and IRExprP__BBPTR and introduce two new
IRExpr kinds instead: Iex_VECRET and Iex_BBPTR. Add constructor 
functions and adjust ppIRExpr, typeOfIRxpr and deepCopyExpr. The
rest is mechanics.


git-svn-id: svn://svn.valgrind.org/vex/trunk@2742 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_amd64_toIR.c b/priv/guest_amd64_toIR.c
index cea4c00..38c2556 100644
--- a/priv/guest_amd64_toIR.c
+++ b/priv/guest_amd64_toIR.c
@@ -5356,7 +5356,7 @@
                                  0/*regparms*/, 
                                  "amd64g_dirtyhelper_FLDENV", 
                                  &amd64g_dirtyhelper_FLDENV,
-                                 mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                                 mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                               );
                d->tmp       = w64;
                /* declare we're reading memory */
@@ -5453,7 +5453,7 @@
                                0/*regparms*/, 
                                "amd64g_dirtyhelper_FSTENV", 
                                &amd64g_dirtyhelper_FSTENV,
-                               mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                               mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                             );
                /* declare we're writing memory */
                d->mFx   = Ifx_Write;
@@ -6106,7 +6106,7 @@
                                 0/*regparms*/, 
                                 "amd64g_dirtyhelper_FINIT", 
                                 &amd64g_dirtyhelper_FINIT,
-                                mkIRExprVec_1( IRExprP__BBPTR )
+                                mkIRExprVec_1( IRExpr_BBPTR() )
                              );
 
                /* declare we're writing guest state */
@@ -6321,7 +6321,7 @@
                          0/*regparms*/, 
                          "amd64g_dirtyhelper_FRSTOR",
                          &amd64g_dirtyhelper_FRSTOR,
-                         mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                         mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                       );
                   d->mSize = 108;
                }
@@ -6402,7 +6402,7 @@
                          0/*regparms*/, 
                          "amd64g_dirtyhelper_FNSAVE",
                          &amd64g_dirtyhelper_FNSAVE,
-                         mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                         mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                       );
                   d->mSize = 108;
                }
@@ -13292,7 +13292,7 @@
                 0/*regparms*/, 
                 "amd64g_dirtyhelper_FXSAVE", 
                 &amd64g_dirtyhelper_FXSAVE,
-                mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
              );
 
          /* declare we're writing memory */
@@ -13370,7 +13370,7 @@
                 0/*regparms*/, 
                 "amd64g_dirtyhelper_FXRSTOR", 
                 &amd64g_dirtyhelper_FXRSTOR,
-                mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
              );
 
          /* declare we're reading memory */
@@ -16917,7 +16917,7 @@
    IRExpr*  gstOffLe     = mkU64(gstOffL);
    IRExpr*  gstOffRe     = mkU64(gstOffR);
    IRExpr** args
-      = mkIRExprVec_5( IRExprP__BBPTR, opc4, gstOffDe, gstOffLe, gstOffRe );
+      = mkIRExprVec_5( IRExpr_BBPTR(), opc4, gstOffDe, gstOffLe, gstOffRe );
 
    IRDirty* d    = unsafeIRDirty_0_N( 0/*regparms*/, nm, fn, args );
    /* It's not really a dirty call, but we can't use the clean helper
@@ -17007,7 +17007,7 @@
    IRExpr*  gstOffLe     = mkU64(gstOffL);
    IRExpr*  gstOffRe     = mkU64(gstOffR);
    IRExpr** args
-      = mkIRExprVec_4( IRExprP__BBPTR, imme, gstOffLe, gstOffRe );
+      = mkIRExprVec_4( IRExpr_BBPTR(), imme, gstOffLe, gstOffRe );
 
    IRDirty* d    = unsafeIRDirty_0_N( 0/*regparms*/, nm, fn, args );
    /* It's not really a dirty call, but we can't use the clean helper
@@ -17936,7 +17936,7 @@
    IRExpr*  edxIN        = isISTRx ? mkU64(0) : getIRegRDX(8);
    IRExpr*  eaxIN        = isISTRx ? mkU64(0) : getIRegRAX(8);
    IRExpr** args
-      = mkIRExprVec_6( IRExprP__BBPTR,
+      = mkIRExprVec_6( IRExpr_BBPTR(),
                        opc4_and_imm, gstOffLe, gstOffRe, edxIN, eaxIN );
 
    IRTemp   resT = newTemp(Ity_I64);
@@ -20711,7 +20711,7 @@
          void*        fAddr = &amd64g_dirtyhelper_RDTSCP;
          IRDirty* d
             = unsafeIRDirty_0_N ( 0/*regparms*/, 
-                                  fName, fAddr, mkIRExprVec_1(IRExprP__BBPTR) );
+                                  fName, fAddr, mkIRExprVec_1(IRExpr_BBPTR()) );
          /* declare guest state effects */
          d->nFxState = 3;
          vex_bzero(&d->fxState, sizeof(d->fxState));
@@ -20959,7 +20959,7 @@
 
       vassert(fName); vassert(fAddr);
       d = unsafeIRDirty_0_N ( 0/*regparms*/, 
-                              fName, fAddr, mkIRExprVec_1(IRExprP__BBPTR) );
+                              fName, fAddr, mkIRExprVec_1(IRExpr_BBPTR()) );
       /* declare guest state effects */
       d->nFxState = 4;
       vex_bzero(&d->fxState, sizeof(d->fxState));
diff --git a/priv/guest_mips_toIR.c b/priv/guest_mips_toIR.c
index c3709e3..926874e 100644
--- a/priv/guest_mips_toIR.c
+++ b/priv/guest_mips_toIR.c
@@ -12488,7 +12488,7 @@
       if (rs == 0) {  /* MFC0 */
          DIP("mfc0 r%d, r%d, %d", rt, rd, sel);
          IRTemp   val  = newTemp(Ity_I32);
-         IRExpr** args = mkIRExprVec_3 (IRExprP__BBPTR, mkU32(rd), mkU32(sel));
+         IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU32(rd), mkU32(sel));
          IRDirty *d = unsafeIRDirty_1_N(val,
                                         0,
                                         "mips32_dirtyhelper_mfc0",
@@ -12500,7 +12500,7 @@
          /* Doubleword Move from Coprocessor 0 - DMFC0; MIPS64 */
          DIP("dmfc0 r%d, r%d, %d", rt, rd, sel);
          IRTemp   val  = newTemp(Ity_I64);
-         IRExpr** args = mkIRExprVec_3 (IRExprP__BBPTR, mkU64(rd), mkU64(sel));
+         IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(), mkU64(rd), mkU64(sel));
          IRDirty *d = unsafeIRDirty_1_N(val,
                                         0,
                                         "mips64_dirtyhelper_dmfc0",
@@ -14166,7 +14166,7 @@
 #if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
             } else if (rd == 1) {
                IRTemp   val  = newTemp(Ity_I64);
-               IRExpr** args = mkIRExprVec_3 (IRExprP__BBPTR,
+               IRExpr** args = mkIRExprVec_3 (IRExpr_BBPTR(),
                                               mkU64(rt), mkU64(rd));
                IRDirty *d = unsafeIRDirty_1_N(val,
                                               0,
diff --git a/priv/guest_ppc_toIR.c b/priv/guest_ppc_toIR.c
index a4d6945..5e350e7 100644
--- a/priv/guest_ppc_toIR.c
+++ b/priv/guest_ppc_toIR.c
@@ -14482,7 +14482,7 @@
       IRDirty* d;
       UInt vD_off = vectorGuestRegOffset(vD_addr);
       IRExpr** args = mkIRExprVec_4(
-                         IRExprP__BBPTR,
+                         IRExpr_BBPTR(),
                          mkU32(vD_off), 
                          binop(Iop_And32, mkNarrowTo32(ty, mkexpr(EA)),
                                           mkU32(0xF)),
@@ -14516,7 +14516,7 @@
       IRDirty* d;
       UInt vD_off = vectorGuestRegOffset(vD_addr);
       IRExpr** args = mkIRExprVec_4(
-                         IRExprP__BBPTR,
+                         IRExpr_BBPTR(),
                          mkU32(vD_off), 
                          binop(Iop_And32, mkNarrowTo32(ty, mkexpr(EA)),
                                           mkU32(0xF)),
diff --git a/priv/guest_s390_toIR.c b/priv/guest_s390_toIR.c
index 6ed1897..85af405 100644
--- a/priv/guest_s390_toIR.c
+++ b/priv/guest_s390_toIR.c
@@ -12874,10 +12874,10 @@
    IRDirty *d;
    IRTemp cc = newTemp(Ity_I64);
 
-   /* IRExprP__BBPTR => Need to pass pointer to guest state to helper */
+   /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
                          &s390x_dirtyhelper_STFLE,
-                         mkIRExprVec_2(IRExprP__BBPTR, mkexpr(op2addr)));
+                         mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
 
    d->nFxState = 1;
    vex_bzero(&d->fxState, sizeof(d->fxState));
diff --git a/priv/guest_x86_toIR.c b/priv/guest_x86_toIR.c
index 11e0423..90499b0 100644
--- a/priv/guest_x86_toIR.c
+++ b/priv/guest_x86_toIR.c
@@ -3953,7 +3953,7 @@
                                 0/*regparms*/, 
                                 "x86g_dirtyhelper_FLDENV", 
                                 &x86g_dirtyhelper_FLDENV,
-                                mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                                mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                              );
                d->tmp   = ew;
                /* declare we're reading memory */
@@ -4049,7 +4049,7 @@
                                0/*regparms*/, 
                                "x86g_dirtyhelper_FSTENV", 
                                &x86g_dirtyhelper_FSTENV,
-                               mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                               mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                             );
                /* declare we're writing memory */
                d->mFx   = Ifx_Write;
@@ -4734,7 +4734,7 @@
                                 0/*regparms*/, 
                                 "x86g_dirtyhelper_FINIT", 
                                 &x86g_dirtyhelper_FINIT,
-                                mkIRExprVec_1(IRExprP__BBPTR)
+                                mkIRExprVec_1(IRExpr_BBPTR())
                              );
 
                /* declare we're writing guest state */
@@ -4933,7 +4933,7 @@
                                 0/*regparms*/, 
                                 "x86g_dirtyhelper_FRSTOR", 
                                 &x86g_dirtyhelper_FRSTOR,
-                                mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                                mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                              );
                d->tmp   = ew;
                /* declare we're reading memory */
@@ -4992,7 +4992,7 @@
                                0/*regparms*/, 
                                "x86g_dirtyhelper_FSAVE", 
                                &x86g_dirtyhelper_FSAVE,
-                               mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+                               mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
                             );
                /* declare we're writing memory */
                d->mFx   = Ifx_Write;
@@ -8187,7 +8187,7 @@
              0/*regparms*/, 
              "x86g_dirtyhelper_FXSAVE", 
              &x86g_dirtyhelper_FXSAVE,
-             mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+             mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
           );
 
       /* declare we're writing memory */
@@ -8261,7 +8261,7 @@
              0/*regparms*/, 
              "x86g_dirtyhelper_FXRSTOR", 
              &x86g_dirtyhelper_FXRSTOR,
-             mkIRExprVec_2( IRExprP__BBPTR, mkexpr(addr) )
+             mkIRExprVec_2( IRExpr_BBPTR(), mkexpr(addr) )
           );
 
       /* declare we're reading memory */
@@ -14682,7 +14682,7 @@
 
          vassert(fName); vassert(fAddr);
          d = unsafeIRDirty_0_N ( 0/*regparms*/, 
-                                 fName, fAddr, mkIRExprVec_1(IRExprP__BBPTR) );
+                                 fName, fAddr, mkIRExprVec_1(IRExpr_BBPTR()) );
          /* declare guest state effects */
          d->nFxState = 4;
          vex_bzero(&d->fxState, sizeof(d->fxState));
diff --git a/priv/host_amd64_isel.c b/priv/host_amd64_isel.c
index 2ea7721..b85146b 100644
--- a/priv/host_amd64_isel.c
+++ b/priv/host_amd64_isel.c
@@ -367,11 +367,11 @@
                                                     IRExpr*  e )
 {
    /* Per comments in doHelperCall below, appearance of
-      IRExprP__VECRET implies ill-formed IR. */
-   vassert(e != IRExprP__VECRET);
+      Iex_VECRET implies ill-formed IR. */
+   vassert(e->tag != Iex_VECRET);
 
    /* In this case we give out a copy of the BaseBlock pointer. */
-   if (UNLIKELY(e == IRExprP__BBPTR)) {
+   if (UNLIKELY(e->tag == Iex_BBPTR)) {
       return mk_iMOVsd_RR( hregAMD64_RBP(), dst );
    }
 
@@ -443,7 +443,7 @@
    *retloc               = mk_RetLoc_INVALID();
 
    /* These are used for cross-checking that IR-level constraints on
-      the use of IRExprP__VECRET and IRExprP__BBPTR are observed. */
+      the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */
    UInt nVECRETs = 0;
    UInt nBBPTRs  = 0;
 
@@ -457,13 +457,13 @@
 
       The return type can be I{64,32,16,8} or V{128,256}.  In the
       latter two cases, it is expected that |args| will contain the
-      special value IRExprP__VECRET, in which case this routine
+      special node IRExpr_VECRET(), in which case this routine
       generates code to allocate space on the stack for the vector
       return value.  Since we are not passing any scalars on the
       stack, it is enough to preallocate the return space before
       marshalling any arguments, in this case.
 
-      |args| may also contain IRExprP__BBPTR, in which case the
+      |args| may also contain IRExpr_BBPTR(), in which case the
       value in %rbp is passed as the corresponding argument.
 
       Generating code which is both efficient and correct when
@@ -492,7 +492,7 @@
       unconditional calls may use the fast scheme, since having to
       compute a condition expression could itself trash real
       registers.  Note that for simplicity, in the case where
-      IRExprP__VECRET is present, we use the slow scheme.  This is
+      IRExpr_VECRET() is present, we use the slow scheme.  This is
       motivated by the desire to avoid any possible complexity
       w.r.t. nested calls.
 
@@ -557,15 +557,15 @@
    /* FAST SCHEME */
    /* In this loop, we process args that can be computed into the
       destination (real) register with a single instruction, without
-      using any fixed regs.  That also includes IRExprP__BBPTR, but
-      not IRExprP__VECRET.  Indeed, if the IR is well-formed, we can
-      never see IRExprP__VECRET at this point, since the return-type
+      using any fixed regs.  That also includes IRExpr_BBPTR(), but
+      not IRExpr_VECRET().  Indeed, if the IR is well-formed, we can
+      never see IRExpr_VECRET() at this point, since the return-type
       check above should ensure all those cases use the slow scheme
       instead. */
    vassert(n_args >= 0 && n_args <= 6);
    for (i = 0; i < n_args; i++) {
       IRExpr* arg = args[i];
-      if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg))) {
+      if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg))) {
          vassert(typeOfIRExpr(env->type_env, args[i]) == Ity_I64);
       }
       fastinstrs[i] 
@@ -612,12 +612,12 @@
    vassert(n_args >= 0 && n_args <= 6);
    for (i = 0; i < n_args; i++) {
       IRExpr* arg = args[i];
-      if (UNLIKELY(arg == IRExprP__BBPTR)) {
+      if (UNLIKELY(arg->tag == Iex_BBPTR)) {
          tmpregs[i] = newVRegI(env);
          addInstr(env, mk_iMOVsd_RR( hregAMD64_RBP(), tmpregs[i]));
          nBBPTRs++;
       }
-      else if (UNLIKELY(arg == IRExprP__VECRET)) {
+      else if (UNLIKELY(arg->tag == Iex_VECRET)) {
          /* We stashed the address of the return slot earlier, so just
             retrieve it now. */
          vassert(!hregIsInvalid(r_vecRetAddr));
diff --git a/priv/host_arm_isel.c b/priv/host_arm_isel.c
index 18c6122..2b1a9e1 100644
--- a/priv/host_arm_isel.c
+++ b/priv/host_arm_isel.c
@@ -361,7 +361,7 @@
 static
 Bool mightRequireFixedRegs ( IRExpr* e )
 {
-   if (UNLIKELY(is_IRExprP__VECRET_or_BBPTR(e))) {
+   if (UNLIKELY(is_IRExpr_VECRET_or_BBPTR(e))) {
       // These are always "safe" -- either a copy of r13(sp) in some
       // arbitrary vreg, or a copy of r8, respectively.
       return False;
@@ -405,7 +405,7 @@
    *retloc               = mk_RetLoc_INVALID();
 
    /* These are used for cross-checking that IR-level constraints on
-      the use of IRExprP__VECRET and IRExprP__BBPTR are observed. */
+      the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */
    UInt nVECRETs = 0;
    UInt nBBPTRs  = 0;
 
@@ -418,14 +418,14 @@
       supported arg types are I32 and I64.
 
       The return type can be I{64,32} or V128.  In the V128 case, it
-      is expected that |args| will contain the special value
-      IRExprP__VECRET, in which case this routine generates code to
+      is expected that |args| will contain the special node
+      IRExpr_VECRET(), in which case this routine generates code to
       allocate space on the stack for the vector return value.  Since
       we are not passing any scalars on the stack, it is enough to
       preallocate the return space before marshalling any arguments,
       in this case.
 
-      |args| may also contain IRExprP__BBPTR, in which case the
+      |args| may also contain IRExpr_BBPTR(), in which case the
       value in r8 is passed as the corresponding argument.
 
       Generating code which is both efficient and correct when
@@ -470,9 +470,9 @@
    n_args = 0;
    for (i = 0; args[i]; i++) {
       IRExpr* arg = args[i];
-      if (UNLIKELY(arg == IRExprP__VECRET)) {
+      if (UNLIKELY(arg->tag == Iex_VECRET)) {
          nVECRETs++;
-      } else if (UNLIKELY(arg == IRExprP__BBPTR)) {
+      } else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
          nBBPTRs++;
       }
       n_args++;
@@ -530,7 +530,7 @@
          IRExpr* arg = args[i];
 
          IRType  aTy = Ity_INVALID;
-         if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+         if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
             aTy = typeOfIRExpr(env->type_env, arg);
 
          if (nextArgReg >= ARM_N_ARGREGS)
@@ -561,13 +561,13 @@
             addInstr(env, mk_iMOVds_RR( argregs[nextArgReg], raHi ));
             nextArgReg++;
          }
-         else if (arg == IRExprP__BBPTR) {
+         else if (arg->tag == Iex_BBPTR) {
             vassert(0); //ATC
             addInstr(env, mk_iMOVds_RR( argregs[nextArgReg],
                                         hregARM_R8() ));
             nextArgReg++;
          }
-         else if (arg == IRExprP__VECRET) {
+         else if (arg->tag == Iex_VECRET) {
             // If this happens, it denotes ill-formed IR
             vassert(0);
          }
@@ -587,7 +587,7 @@
          IRExpr* arg = args[i];
 
          IRType  aTy = Ity_INVALID;
-         if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+         if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
             aTy  = typeOfIRExpr(env->type_env, arg);
 
          if (nextArgReg >= ARM_N_ARGREGS)
@@ -610,12 +610,12 @@
             tmpregs[nextArgReg] = raHi;
             nextArgReg++;
          }
-         else if (arg == IRExprP__BBPTR) {
+         else if (arg->tag == Iex_BBPTR) {
             vassert(0); //ATC
             tmpregs[nextArgReg] = hregARM_R8();
             nextArgReg++;
          }
-         else if (arg == IRExprP__VECRET) {
+         else if (arg->tag == Iex_VECRET) {
             // If this happens, it denotes ill-formed IR
             vassert(0);
          }
diff --git a/priv/host_mips_isel.c b/priv/host_mips_isel.c
index 42cb2a6..59a3a0c 100644
--- a/priv/host_mips_isel.c
+++ b/priv/host_mips_isel.c
@@ -405,7 +405,7 @@
    *retloc               = mk_RetLoc_INVALID();
 
    /* These are used for cross-checking that IR-level constraints on
-      the use of IRExprP__VECRET and IRExprP__BBPTR are observed. */
+      the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */
    UInt nVECRETs = 0;
    UInt nBBPTRs  = 0;
 
@@ -423,22 +423,22 @@
 
    /* The return type can be I{64,32,16,8} or V{128,256}.  In the
       latter two cases, it is expected that |args| will contain the
-      special value IRExprP__VECRET, in which case this routine
+      special node IRExpr_VECRET(), in which case this routine
       generates code to allocate space on the stack for the vector
       return value.  Since we are not passing any scalars on the
       stack, it is enough to preallocate the return space before
       marshalling any arguments, in this case.
 
-      |args| may also contain IRExprP__BBPTR, in which case the value
+      |args| may also contain IRExpr_BBPTR(), in which case the value
       in the guest state pointer register is passed as the
       corresponding argument. */
 
    n_args = 0;
    for (i = 0; args[i]; i++) {
       IRExpr* arg = args[i];
-      if (UNLIKELY(arg == IRExprP__VECRET)) {
+      if (UNLIKELY(arg->tag == Iex_VECRET)) {
          nVECRETs++;
-      } else if (UNLIKELY(arg == IRExprP__BBPTR)) {
+      } else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
          nBBPTRs++;
       }
       n_args++;
@@ -510,7 +510,7 @@
          vassert(argreg < MIPS_N_REGPARMS);
 
          IRType  aTy = Ity_INVALID;
-         if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+         if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
             aTy = typeOfIRExpr(env->type_env, arg);
 
          if (aTy == Ity_I32 || mode64) {
@@ -530,12 +530,12 @@
             argiregs |= (1 << (argreg + 4));
             addInstr(env, mk_iMOVds_RR( argregs[argreg], rLo));
             argreg++;
-         } else if (arg == IRExprP__BBPTR) {
+         } else if (arg->tag == Iex_BBPTR) {
             vassert(0);  // ATC
             addInstr(env, mk_iMOVds_RR(argregs[argreg],
                                        GuestStatePointer(mode64)));
             argreg++;
-         } else if (arg == IRExprP__VECRET) {
+         } else if (arg->tag == Iex_VECRET) {
             // If this happens, it denotes ill-formed IR.
             vassert(0);
          }
@@ -551,7 +551,7 @@
          IRExpr* arg = args[i];
 
          IRType  aTy = Ity_INVALID;
-         if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+         if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
             aTy  = typeOfIRExpr(env->type_env, arg);
 
          if (aTy == Ity_I32 || mode64) {
@@ -568,12 +568,12 @@
             argreg++;
             tmpregs[argreg] = raHi;
             argreg++;
-         } else if (arg == IRExprP__BBPTR) {
+         } else if (arg->tag == Iex_BBPTR) {
             vassert(0);  // ATC
             tmpregs[argreg] = GuestStatePointer(mode64);
             argreg++;
          }
-         else if (arg == IRExprP__VECRET) {
+         else if (arg->tag == Iex_VECRET) {
             // If this happens, it denotes ill-formed IR
             vassert(0);
          }
diff --git a/priv/host_ppc_isel.c b/priv/host_ppc_isel.c
index 0969944..3684e42 100644
--- a/priv/host_ppc_isel.c
+++ b/priv/host_ppc_isel.c
@@ -700,7 +700,7 @@
    *retloc               = mk_RetLoc_INVALID();
 
    /* These are used for cross-checking that IR-level constraints on
-      the use of IRExprP__VECRET and IRExprP__BBPTR are observed. */
+      the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */
    UInt nVECRETs = 0;
    UInt nBBPTRs  = 0;
 
@@ -720,13 +720,13 @@
 
       The return type can be I{64,32,16,8} or V{128,256}.  In the
       latter two cases, it is expected that |args| will contain the
-      special value IRExprP__VECRET, in which case this routine
+      special node IRExpr_VECRET(), in which case this routine
       generates code to allocate space on the stack for the vector
       return value.  Since we are not passing any scalars on the
       stack, it is enough to preallocate the return space before
       marshalling any arguments, in this case.
 
-      |args| may also contain IRExprP__BBPTR, in which case the value
+      |args| may also contain IRExpr_BBPTR(), in which case the value
       in the guest state pointer register is passed as the
       corresponding argument.
 
@@ -822,10 +822,10 @@
    if (go_fast) {
       for (i = 0; i < n_args; i++) {
          IRExpr* arg = args[i];
-         if (UNLIKELY(arg == IRExprP__BBPTR)) {
+         if (UNLIKELY(arg->tag == Iex_BBPTR)) {
             /* that's OK */
          } 
-         else if (UNLIKELY(arg == IRExprP__VECRET)) {
+         else if (UNLIKELY(arg->tag == Iex_VECRET)) {
             /* This implies ill-formed IR, since if the IR was
                well-formed, the return-type test above would have
                filtered it out. */
@@ -850,13 +850,13 @@
          IRExpr* arg = args[i];
          vassert(argreg < PPC_N_REGPARMS);
 
-         if (arg == IRExprP__BBPTR) {
+         if (arg->tag == Iex_BBPTR) {
             argiregs |= (1 << (argreg+3));
             addInstr(env, mk_iMOVds_RR( argregs[argreg],
                                         GuestStatePtr(mode64) ));
             argreg++;
          } else {
-            vassert(arg != IRExprP__VECRET);
+            vassert(arg->tag != Iex_VECRET);
             IRType ty = typeOfIRExpr(env->type_env, arg);
             vassert(ty == Ity_I32 || ty == Ity_I64);
             if (!mode64) {
@@ -922,13 +922,13 @@
       for (i = 0; i < n_args; i++) {
          IRExpr* arg = args[i];
          vassert(argreg < PPC_N_REGPARMS);
-         if (UNLIKELY(arg == IRExprP__BBPTR)) {
+         if (UNLIKELY(arg->tag == Iex_BBPTR)) {
             tmpregs[argreg] = newVRegI(env);
             addInstr(env, mk_iMOVds_RR( tmpregs[argreg],
                                         GuestStatePtr(mode64) ));
             nBBPTRs++;
          }
-         else if (UNLIKELY(arg == IRExprP__VECRET)) {
+         else if (UNLIKELY(arg->tag == Iex_VECRET)) {
             /* We stashed the address of the return slot earlier, so just
                retrieve it now. */
             vassert(!hregIsInvalid(r_vecRetAddr));
diff --git a/priv/host_s390_isel.c b/priv/host_s390_isel.c
index e8c260e..0816e42 100644
--- a/priv/host_s390_isel.c
+++ b/priv/host_s390_isel.c
@@ -486,18 +486,18 @@
 
    /* The return type can be I{64,32,16,8} or V{128,256}.  In the
       latter two cases, it is expected that |args| will contain the
-      special value IRExprP__VECRET, in which case this routine
+      special node IRExpr_VECRET(), in which case this routine
       generates code to allocate space on the stack for the vector
       return value.  Since we are not passing any scalars on the
       stack, it is enough to preallocate the return space before
       marshalling any arguments, in this case.
 
-      |args| may also contain IRExprP__BBPTR, in which case the value
+      |args| may also contain IRExpr_BBPTR(), in which case the value
       in the guest state pointer register is passed as the
       corresponding argument.
 
       These are used for cross-checking that IR-level constraints on
-      the use of IRExprP__VECRET and IRExprP__BBPTR are observed. */
+      the use of IRExpr_VECRET() and IRExpr_BBPTR() are observed. */
    UInt nVECRETs = 0;
    UInt nBBPTRs  = 0;
 
@@ -516,9 +516,9 @@
    */
    Int arg_errors = 0;
    for (i = 0; i < n_args; ++i) {
-      if (UNLIKELY(args[i] == IRExprP__VECRET)) {
+      if (UNLIKELY(args[i]->tag == Iex_VECRET)) {
          nVECRETs++;
-      } else if (UNLIKELY(args[i] == IRExprP__BBPTR)) {
+      } else if (UNLIKELY(args[i]->tag == Iex_BBPTR)) {
          nBBPTRs++;
       } else {
          IRType type = typeOfIRExpr(env->type_env, args[i]);
@@ -561,12 +561,12 @@
    /* Compute the function arguments into a temporary register each */
    for (i = 0; i < n_args; i++) {
       IRExpr *arg = args[i];
-      if(UNLIKELY(arg == IRExprP__VECRET)) {
+      if(UNLIKELY(arg->tag == Iex_VECRET)) {
          /* we do not handle vector types yet */
          vassert(0);
          addInstr(env, s390_insn_move(sizeof(ULong), tmpregs[argreg],
                                       r_vecRetAddr));
-      } else if (UNLIKELY(arg == IRExprP__BBPTR)) {
+      } else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
          /* If we need the guest state pointer put it in a temporary arg reg */
          tmpregs[argreg] = newVRegI(env);
          addInstr(env, s390_insn_move(sizeof(ULong), tmpregs[argreg],
diff --git a/priv/host_x86_isel.c b/priv/host_x86_isel.c
index 9ffba19..086aefc 100644
--- a/priv/host_x86_isel.c
+++ b/priv/host_x86_isel.c
@@ -340,19 +340,19 @@
 
 /* Push an arg onto the host stack, in preparation for a call to a
    helper function of some kind.  Returns the number of 32-bit words
-   pushed.  If we encounter an IRExprP__VECRET then we expect that
+   pushed.  If we encounter an IRExpr_VECRET() then we expect that
    r_vecRetAddr will be a valid register, that holds the relevant
    address. 
 */
 static Int pushArg ( ISelEnv* env, IRExpr* arg, HReg r_vecRetAddr )
 {
-   if (UNLIKELY(arg == IRExprP__VECRET)) {
+   if (UNLIKELY(arg->tag == Iex_VECRET)) {
       vassert(0); //ATC
       vassert(!hregIsInvalid(r_vecRetAddr));
       addInstr(env, X86Instr_Push(X86RMI_Reg(r_vecRetAddr)));
       return 1;
    }
-   if (UNLIKELY(arg == IRExprP__BBPTR)) {
+   if (UNLIKELY(arg->tag == Iex_BBPTR)) {
       addInstr(env, X86Instr_Push(X86RMI_Reg(hregX86_EBP())));
       return 1;
    }
@@ -402,7 +402,7 @@
 static
 Bool mightRequireFixedRegs ( IRExpr* e )
 {
-   if (UNLIKELY(is_IRExprP__VECRET_or_BBPTR(e))) {
+   if (UNLIKELY(is_IRExpr_VECRET_or_BBPTR(e))) {
       // These are always "safe" -- either a copy of %esp in some
       // arbitrary vreg, or a copy of %ebp, respectively.
       return False;
@@ -443,7 +443,7 @@
    *retloc               = mk_RetLoc_INVALID();
 
    /* These are used for cross-checking that IR-level constraints on
-      the use of IRExprP__VECRET and IRExprP__BBPTR are observed. */
+      the use of Iex_VECRET and Iex_BBPTR are observed. */
    UInt nVECRETs = 0;
    UInt nBBPTRs  = 0;
 
@@ -452,13 +452,13 @@
 
       * The return type can be I{64,32,16,8} or V128.  In the V128
         case, it is expected that |args| will contain the special
-        value IRExprP__VECRET, in which case this routine generates
+        node IRExpr_VECRET(), in which case this routine generates
         code to allocate space on the stack for the vector return
         value.  Since we are not passing any scalars on the stack, it
         is enough to preallocate the return space before marshalling
         any arguments, in this case.
 
-        |args| may also contain IRExprP__BBPTR, in which case the
+        |args| may also contain IRExpr_BBPTR(), in which case the
         value in %ebp is passed as the corresponding argument.
 
       * If the callee claims regparmness of 1, 2 or 3, we must pass the
@@ -508,9 +508,9 @@
    while (args[n_args]) {
       IRExpr* arg = args[n_args];
       n_args++;
-      if (UNLIKELY(arg == IRExprP__VECRET)) {
+      if (UNLIKELY(arg->tag == Iex_VECRET)) {
          nVECRETs++;
-      } else if (UNLIKELY(arg == IRExprP__BBPTR)) {
+      } else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
          nBBPTRs++;
       }
    }
@@ -585,10 +585,10 @@
             IRExpr* arg = args[i];
             argreg--;
             vassert(argreg >= 0);
-            if (UNLIKELY(arg == IRExprP__VECRET)) {
+            if (UNLIKELY(arg->tag == Iex_VECRET)) {
                vassert(0); //ATC
             }
-            else if (UNLIKELY(arg == IRExprP__BBPTR)) {
+            else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
                vassert(0); //ATC
             } else {
                vassert(typeOfIRExpr(env->type_env, arg) == Ity_I32);
@@ -609,13 +609,13 @@
             IRExpr* arg = args[i];
             argreg--;
             vassert(argreg >= 0);
-            if (UNLIKELY(arg == IRExprP__VECRET)) {
+            if (UNLIKELY(arg->tag == Iex_VECRET)) {
                vassert(!hregIsInvalid(r_vecRetAddr));
                addInstr(env, X86Instr_Alu32R(Xalu_MOV,
                                              X86RMI_Reg(r_vecRetAddr),
                                              argregs[argreg]));
             }
-            else if (UNLIKELY(arg == IRExprP__BBPTR)) {
+            else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
                vassert(0); //ATC
             } else {
                vassert(typeOfIRExpr(env->type_env, arg) == Ity_I32);
diff --git a/priv/ir_defs.c b/priv/ir_defs.c
index f6b57ae..8c4dc10 100644
--- a/priv/ir_defs.c
+++ b/priv/ir_defs.c
@@ -1207,17 +1207,8 @@
       vex_printf("(");
       for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
         IRExpr* arg = e->Iex.CCall.args[i];
-        /* We don't actually expect VECRET or BBPTR here -- BBPTR is
-           never allowable; VECRET is in principle allowable but at
-           present isn't supported.  But they are handled for
-           completeness anyway. */
-        if (arg == IRExprP__VECRET) {
-          vex_printf("VECRET");
-        } else if (arg == IRExprP__BBPTR) {
-          vex_printf("BBPTR");
-        } else {
-          ppIRExpr(arg);
-        }
+        ppIRExpr(arg);
+
         if (e->Iex.CCall.args[i+1] != NULL) {
           vex_printf(",");
         }
@@ -1234,6 +1225,12 @@
       ppIRExpr(e->Iex.ITE.iffalse);
       vex_printf(")");
       break;
+    case Iex_VECRET:
+      vex_printf("VECRET");
+      break;
+    case Iex_BBPTR:
+      vex_printf("BBPTR");
+      break;
     default:
       vpanic("ppIRExpr");
   }
@@ -1282,13 +1279,8 @@
    vex_printf("(");
    for (i = 0; d->args[i] != NULL; i++) {
       IRExpr* arg = d->args[i];
-      if (arg == IRExprP__VECRET) {
-         vex_printf("VECRET");
-      } else if (arg == IRExprP__BBPTR) {
-         vex_printf("BBPTR");
-      } else {
-         ppIRExpr(arg);
-      }
+      ppIRExpr(arg);
+
       if (d->args[i+1] != NULL) {
          vex_printf(",");
       }
@@ -1750,6 +1742,16 @@
    e->Iex.ITE.iffalse = iffalse;
    return e;
 }
+IRExpr* IRExpr_VECRET ( void ) {
+   IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
+   e->tag    = Iex_VECRET;
+   return e;
+}
+IRExpr* IRExpr_BBPTR ( void ) {
+   IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
+   e->tag    = Iex_BBPTR;
+   return e;
+}
 
 
 /* Constructors for NULL-terminated IRExpr expression vectors,
@@ -2175,6 +2177,12 @@
          return IRExpr_ITE(deepCopyIRExpr(e->Iex.ITE.cond),
                            deepCopyIRExpr(e->Iex.ITE.iftrue),
                            deepCopyIRExpr(e->Iex.ITE.iffalse));
+      case Iex_VECRET:
+         return IRExpr_VECRET();
+
+      case Iex_BBPTR:
+         return IRExpr_BBPTR();
+
       default:
          vpanic("deepCopyIRExpr");
    }
@@ -3341,6 +3349,10 @@
          /* return typeOfIRExpr(tyenv, e->Iex.ITE.iffalse); */
       case Iex_Binder:
          vpanic("typeOfIRExpr: Binder is not a valid expression");
+      case Iex_VECRET:
+         vpanic("typeOfIRExpr: VECRET is not a valid expression");
+      case Iex_BBPTR:
+         vpanic("typeOfIRExpr: BBPTR is not a valid expression");
       default:
          ppIRExpr(e);
          vpanic("typeOfIRExpr");
@@ -3379,14 +3391,11 @@
 */
 
 static inline Bool isIRAtom_or_VECRET_or_BBPTR ( IRExpr* e ) {
-   /* Use this rather roundabout scheme so as to try and have the
-      number of additional conditional branches be 1 in the common
-      (non-VECRET, non-BBPTR) case, rather than 2. */
-   if (UNLIKELY(((HWord)e) & 1)) {
-      return e == IRExprP__VECRET || e == IRExprP__BBPTR;
-   } else {
-      return isIRAtom(e);
-   }
+  if (isIRAtom(e)) {
+    return True;
+  }
+
+  return UNLIKELY(is_IRExpr_VECRET_or_BBPTR(e));
 }
 
 Bool isFlatIRStmt ( IRStmt* st )
@@ -3619,7 +3628,7 @@
       case Iex_CCall:
          for (i = 0; expr->Iex.CCall.args[i]; i++) {
             IRExpr* arg = expr->Iex.CCall.args[i];
-            if (UNLIKELY(((HWord)arg) & 1)) {
+            if (UNLIKELY(is_IRExpr_VECRET_or_BBPTR(arg))) {
                /* These aren't allowed in CCall lists.  Let's detect
                   and throw them out here, though, rather than
                   segfaulting a bit later on. */
@@ -3701,9 +3710,9 @@
          d = stmt->Ist.Dirty.details;
          for (i = 0; d->args[i] != NULL; i++) {
             IRExpr* arg = d->args[i];
-            if (UNLIKELY(((HWord)arg) & 1)) {
+            if (UNLIKELY(is_IRExpr_VECRET_or_BBPTR(arg))) {
                /* This is ensured by isFlatIRStmt */
-               vassert(arg == IRExprP__VECRET || arg == IRExprP__BBPTR);
+              ;
             } else {
                useBeforeDef_Expr(bb,stmt,arg,def_counts);
             }
@@ -3900,7 +3909,7 @@
             if (i >= 32)
                sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args");
             IRExpr* arg = expr->Iex.CCall.args[i];
-            if (UNLIKELY(is_IRExprP__VECRET_or_BBPTR(arg)))
+            if (UNLIKELY(is_IRExpr_VECRET_or_BBPTR(arg)))
                sanityCheckFail(bb,stmt,"Iex.CCall.args: is VECRET/BBPTR");
             tcExpr(bb,stmt, arg, gWordTy);
          }
@@ -4146,17 +4155,10 @@
             if (i >= 32)
                sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
             IRExpr* arg = d->args[i];
-            if (UNLIKELY(((HWord)arg) & 1)) {
-               if (arg == IRExprP__VECRET) {
-                  nVECRETs++;
-               } else
-               if (arg == IRExprP__BBPTR) {
-                  nBBPTRs++;
-               } else {
-                  /* The impossibility of failure is ensured by
-                     isFlatIRStmt */
-                  vassert(0);
-               }
+            if (UNLIKELY(arg->tag == Iex_VECRET)) {
+               nVECRETs++;
+            } else if (UNLIKELY(arg->tag == Iex_BBPTR)) {
+               nBBPTRs++;
             } else {
                if (typeOfIRExpr(tyenv, arg) == Ity_I1)
                   sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1");
diff --git a/priv/ir_opt.c b/priv/ir_opt.c
index ebe24f7..ebf9149 100644
--- a/priv/ir_opt.c
+++ b/priv/ir_opt.c
@@ -488,7 +488,7 @@
          d2->guard = flatten_Expr(bb, d2->guard);
          for (i = 0; d2->args[i]; i++) {
             IRExpr* arg = d2->args[i];
-            if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+            if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
                d2->args[i] = flatten_Expr(bb, arg);
          }
          addStmtToIRSB(bb, IRStmt_Dirty(d2));
@@ -2564,7 +2564,7 @@
          d2->guard = fold_Expr(env, subst_Expr(env, d2->guard));
          for (i = 0; d2->args[i]; i++) {
             IRExpr* arg = d2->args[i];
-            if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg))) {
+            if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg))) {
                vassert(isIRAtom(arg));
                d2->args[i] = fold_Expr(env, subst_Expr(env, arg));
             }
@@ -2905,7 +2905,7 @@
          addUses_Expr(set, d->guard);
          for (i = 0; d->args[i] != NULL; i++) {
             IRExpr* arg = d->args[i];
-            if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+            if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
                addUses_Expr(set, arg);
          }
          return;
@@ -4952,7 +4952,7 @@
          aoccCount_Expr(uses, d->guard);
          for (i = 0; d->args[i]; i++) {
             IRExpr* arg = d->args[i];
-            if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+            if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
                aoccCount_Expr(uses, arg);
          }
          return;
@@ -5324,7 +5324,7 @@
          d2->guard = atbSubst_Expr(env, d2->guard);
          for (i = 0; d2->args[i]; i++) {
             IRExpr* arg = d2->args[i];
-            if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+            if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
                d2->args[i] = atbSubst_Expr(env, arg);
          }
          return IRStmt_Dirty(d2);
@@ -5351,7 +5351,7 @@
       guest state under the covers.  It's not allowed, but let's be
       extra conservative and assume the worst. */
    for (i = 0; d->args[i]; i++) {
-      if (UNLIKELY(d->args[i] == IRExprP__BBPTR)) {
+      if (UNLIKELY(d->args[i]->tag == Iex_BBPTR)) {
          *requiresPreciseMemExns = True;
          return True;
       }
@@ -5799,7 +5799,7 @@
             vassert(isIRAtom(d->guard));
             for (j = 0; d->args[j]; j++) {
                IRExpr* arg = d->args[j];
-               if (LIKELY(!is_IRExprP__VECRET_or_BBPTR(arg)))
+               if (LIKELY(!is_IRExpr_VECRET_or_BBPTR(arg)))
                   vassert(isIRAtom(arg));
             }
             if (d->mFx != Ifx_None)