Enhance IR so as to distinguish between little- and big-endian loads and
stores, so that PPC can be properly handled. Until now it's been hardwired
to assume little-endian.
As a result, IRStmt_STle is renamed IRStmt_Store and IRExpr_LDle is
renamed IRExpr_Load.
git-svn-id: svn://svn.valgrind.org/vex/trunk@1239 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest-amd64/toIR.c b/priv/guest-amd64/toIR.c
index 0c2adb4..d5a2e10 100644
--- a/priv/guest-amd64/toIR.c
+++ b/priv/guest-amd64/toIR.c
@@ -221,12 +221,12 @@
static void storeLE ( IRExpr* addr, IRExpr* data )
{
- stmt( IRStmt_STle(addr,data) );
+ stmt( IRStmt_Store(Iend_LE,addr,data) );
}
static IRExpr* loadLE ( IRType ty, IRExpr* data )
{
- return IRExpr_LDle(ty,data);
+ return IRExpr_Load(Iend_LE,ty,data);
}
static IROp mkSizedOp ( IRType ty, IROp op8 )
@@ -5420,7 +5420,7 @@
case 0: /* FLD double-real */
DIP("fldl %s\n", dis_buf);
fp_push();
- put_ST(0, IRExpr_LDle(Ity_F64, mkexpr(addr)));
+ put_ST(0, loadLE(Ity_F64, mkexpr(addr)));
break;
case 2: /* FST double-real */
diff --git a/priv/guest-arm/toIR.c b/priv/guest-arm/toIR.c
index 14071a8..6801f88 100644
--- a/priv/guest-arm/toIR.c
+++ b/priv/guest-arm/toIR.c
@@ -484,7 +484,7 @@
static void storeLE ( IRExpr* addr, IRExpr* data )
{
- stmt( IRStmt_STle(addr,data) );
+ stmt( IRStmt_Store(Iend_LE,addr,data) );
}
static IRExpr* unop ( IROp op, IRExpr* a )
@@ -534,7 +534,7 @@
static IRExpr* loadLE ( IRType ty, IRExpr* data )
{
- return IRExpr_LDle(ty,data);
+ return IRExpr_Load(Iend_LE,ty,data);
}
#if 0
diff --git a/priv/guest-ppc32/toIR.c b/priv/guest-ppc32/toIR.c
index 830ddec6..91f58d9 100644
--- a/priv/guest-ppc32/toIR.c
+++ b/priv/guest-ppc32/toIR.c
@@ -653,14 +653,16 @@
return IRExpr_Get( vectorGuestRegOffset(archreg), Ity_V128 );
}
+#if 0
/* Ditto, but write to a reg instead. */
+/* apparently unused, jrs 2005-06-30 */
static void putVReg ( UInt archreg, IRExpr* e )
{
vassert(archreg < 32);
vassert(typeOfIRExpr(irbb->tyenv, e) == Ity_V128);
stmt( IRStmt_Put(vectorGuestRegOffset(archreg), e) );
}
-
+#endif
static void assign ( IRTemp dst, IRExpr* e )
{
@@ -669,7 +671,7 @@
static void storeBE ( IRExpr* addr, IRExpr* data )
{
- stmt( IRStmt_STle(addr,data) );
+ stmt( IRStmt_Store(Iend_BE,addr,data) );
}
static IRExpr* unop ( IROp op, IRExpr* a )
@@ -712,7 +714,7 @@
static IRExpr* loadBE ( IRType ty, IRExpr* data )
{
- return IRExpr_LDle(ty,data);
+ return IRExpr_Load(Iend_BE,ty,data);
}
// ROTL(src32, rot_amt5)
diff --git a/priv/guest-x86/toIR.c b/priv/guest-x86/toIR.c
index 7eec4af..b6199d7 100644
--- a/priv/guest-x86/toIR.c
+++ b/priv/guest-x86/toIR.c
@@ -777,7 +777,7 @@
static void storeLE ( IRExpr* addr, IRExpr* data )
{
- stmt( IRStmt_STle(addr,data) );
+ stmt( IRStmt_Store(Iend_LE,addr,data) );
}
static IRExpr* unop ( IROp op, IRExpr* a )
@@ -834,7 +834,7 @@
static IRExpr* loadLE ( IRType ty, IRExpr* data )
{
- return IRExpr_LDle(ty,data);
+ return IRExpr_Load(Iend_LE,ty,data);
}
static IROp mkSizedOp ( IRType ty, IROp op8 )
@@ -4551,7 +4551,7 @@
case 0: /* FLD double-real */
DIP("fldl %s\n", dis_buf);
fp_push();
- put_ST(0, IRExpr_LDle(Ity_F64, mkexpr(addr)));
+ put_ST(0, loadLE(Ity_F64, mkexpr(addr)));
break;
case 2: /* FST double-real */
diff --git a/priv/host-amd64/isel.c b/priv/host-amd64/isel.c
index 9c4ff45..bff3c21 100644
--- a/priv/host-amd64/isel.c
+++ b/priv/host-amd64/isel.c
@@ -797,9 +797,13 @@
}
/* --------- LOAD --------- */
- case Iex_LDle: {
+ case Iex_Load: {
HReg dst = newVRegI(env);
- AMD64AMode* amode = iselIntExpr_AMode ( env, e->Iex.LDle.addr );
+ AMD64AMode* amode = iselIntExpr_AMode ( env, e->Iex.Load.addr );
+
+ if (e->Iex.Load.end != Iend_LE)
+ goto irreducible;
+
if (ty == Ity_I64) {
addInstr(env, AMD64Instr_Alu64R(Aalu_MOV,
AMD64RMI_Mem(amode), dst) );
@@ -1777,8 +1781,8 @@
}
/* special case: 64-bit load from memory */
- if (e->tag == Iex_LDle && ty == Ity_I64) {
- AMD64AMode* am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ if (e->tag == Iex_Load && ty == Ity_I64 && e->Iex.Load.end == Iend_LE) {
+ AMD64AMode* am = iselIntExpr_AMode(env, e->Iex.Load.addr);
return AMD64RMI_Mem(am);
}
@@ -2629,11 +2633,11 @@
return lookupIRTemp(env, e->Iex.Tmp.tmp);
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
AMD64AMode* am;
HReg res = newVRegV(env);
- vassert(e->Iex.LDle.ty == Ity_F32);
- am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ vassert(e->Iex.Load.ty == Ity_F32);
+ am = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, AMD64Instr_SseLdSt(True/*load*/, 4, res, am));
return res;
}
@@ -2753,11 +2757,11 @@
return res;
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
AMD64AMode* am;
HReg res = newVRegV(env);
- vassert(e->Iex.LDle.ty == Ity_F64);
- am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ vassert(e->Iex.Load.ty == Ity_F64);
+ am = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, AMD64Instr_SseLdSt( True/*load*/, 8, res, am ));
return res;
}
@@ -3071,9 +3075,9 @@
return dst;
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
HReg dst = newVRegV(env);
- AMD64AMode* am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ AMD64AMode* am = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, AMD64Instr_SseLdSt( True/*load*/, 16, dst, am ));
return dst;
}
@@ -3488,38 +3492,42 @@
switch (stmt->tag) {
/* --------- STORE --------- */
- case Ist_STle: {
+ case Ist_Store: {
AMD64AMode* am;
- IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.STle.addr);
- IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.STle.data);
- vassert(tya == Ity_I64);
- am = iselIntExpr_AMode(env, stmt->Ist.STle.addr);
+ IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
+ IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
+ IREndness end = stmt->Ist.Store.end;
+
+ if (tya != Ity_I64 || end != Iend_LE)
+ goto stmt_fail;
+
+ am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
if (tyd == Ity_I64) {
- AMD64RI* ri = iselIntExpr_RI(env, stmt->Ist.STle.data);
+ AMD64RI* ri = iselIntExpr_RI(env, stmt->Ist.Store.data);
addInstr(env, AMD64Instr_Alu64M(Aalu_MOV,ri,am));
return;
}
if (tyd == Ity_I8 || tyd == Ity_I16 || tyd == Ity_I32) {
- HReg r = iselIntExpr_R(env, stmt->Ist.STle.data);
+ HReg r = iselIntExpr_R(env, stmt->Ist.Store.data);
addInstr(env, AMD64Instr_Store(
toUChar(tyd==Ity_I8 ? 1 : (tyd==Ity_I16 ? 2 : 4)),
r,am));
return;
}
if (tyd == Ity_F64) {
- HReg r = iselDblExpr(env, stmt->Ist.STle.data);
+ HReg r = iselDblExpr(env, stmt->Ist.Store.data);
addInstr(env, AMD64Instr_SseLdSt(False/*store*/, 8, r, am));
return;
}
if (tyd == Ity_F32) {
- HReg r = iselFltExpr(env, stmt->Ist.STle.data);
+ HReg r = iselFltExpr(env, stmt->Ist.Store.data);
addInstr(env, AMD64Instr_SseLdSt(False/*store*/, 4, r, am));
return;
}
//.. if (tyd == Ity_I64) {
//.. HReg vHi, vLo, rA;
-//.. iselInt64Expr(&vHi, &vLo, env, stmt->Ist.STle.data);
-//.. rA = iselIntExpr_R(env, stmt->Ist.STle.addr);
+//.. iselInt64Expr(&vHi, &vLo, env, stmt->Ist.Store.data);
+//.. rA = iselIntExpr_R(env, stmt->Ist.Store.addr);
//.. addInstr(env, X86Instr_Alu32M(
//.. Xalu_MOV, X86RI_Reg(vLo), X86AMode_IR(0, rA)));
//.. addInstr(env, X86Instr_Alu32M(
@@ -3527,7 +3535,7 @@
//.. return;
//.. }
if (tyd == Ity_V128) {
- HReg r = iselVecExpr(env, stmt->Ist.STle.data);
+ HReg r = iselVecExpr(env, stmt->Ist.Store.data);
addInstr(env, AMD64Instr_SseLdSt(False/*store*/, 16, r, am));
return;
}
@@ -3720,6 +3728,7 @@
default: break;
}
+ stmt_fail:
ppIRStmt(stmt);
vpanic("iselStmt(amd64)");
}
diff --git a/priv/host-arm/isel.c b/priv/host-arm/isel.c
index 3c56dd5..94d47e4 100644
--- a/priv/host-arm/isel.c
+++ b/priv/host-arm/isel.c
@@ -738,25 +738,29 @@
/* --------- STORE --------- */
/* little-endian write to memory */
- case Ist_STle: {
+ case Ist_Store: {
HReg reg;
- IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.STle.addr);
- IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.STle.data);
- vassert(tya == Ity_I32);
- reg = iselIntExpr_R(env, stmt->Ist.STle.data);
+ IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
+ IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
+ IREndness end = stmt->Ist.Store.end;
+
+ if (tya != Ity_I32 || end != Iend_LE)
+ goto stmt_fail;
+
+ reg = iselIntExpr_R(env, stmt->Ist.Store.data);
if (tyd == Ity_I8) {
- ARMAMode2* am2 = iselIntExpr_AMode2(env, stmt->Ist.STle.addr);
+ ARMAMode2* am2 = iselIntExpr_AMode2(env, stmt->Ist.Store.addr);
addInstr(env, ARMInstr_StoreB(reg,am2));
return;
}
if (tyd == Ity_I16) {
- ARMAMode3* am3 = iselIntExpr_AMode3(env, stmt->Ist.STle.addr);
+ ARMAMode3* am3 = iselIntExpr_AMode3(env, stmt->Ist.Store.addr);
addInstr(env, ARMInstr_StoreH(reg,am3));
return;
}
if (tyd == Ity_I32) {
- ARMAMode2* am2 = iselIntExpr_AMode2(env, stmt->Ist.STle.addr);
+ ARMAMode2* am2 = iselIntExpr_AMode2(env, stmt->Ist.Store.addr);
addInstr(env, ARMInstr_StoreW(reg,am2));
return;
}
@@ -880,6 +884,7 @@
default: break;
}
+ stmt_fail:
ppIRStmt(stmt);
vpanic("iselStmt");
}
diff --git a/priv/host-ppc32/isel.c b/priv/host-ppc32/isel.c
index 8123a16..5507c15 100644
--- a/priv/host-ppc32/isel.c
+++ b/priv/host-ppc32/isel.c
@@ -909,11 +909,14 @@
return lookupIRTemp(env, e->Iex.Tmp.tmp);
/* --------- LOAD --------- */
- case Iex_LDle: {
- HReg r_dst = newVRegI(env);
- PPC32AMode* am_addr = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ case Iex_Load: {
+ HReg r_dst = newVRegI(env);
+ PPC32AMode* am_addr = iselIntExpr_AMode(env, e->Iex.Load.addr);
+ if (e->Iex.Load.end != Iend_BE)
+ goto irreducible;
if (ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32) {
- addInstr(env, PPC32Instr_Load( sizeofIRType(ty), False, r_dst, am_addr ));
+ addInstr(env, PPC32Instr_Load(
+ sizeofIRType(ty), False, r_dst, am_addr ));
return r_dst;
}
break;
@@ -1216,12 +1219,13 @@
return r_dst;
}
- /* 16Uto32(LDle(expr32)) */
+ /* 16Uto32(LDbe:I16(expr32)) */
{
- DECLARE_PATTERN(p_LDle16_then_16Uto32);
- DEFINE_PATTERN(p_LDle16_then_16Uto32,
- unop(Iop_16Uto32,IRExpr_LDle(Ity_I16,bind(0))) );
- if (matchIRExpr(&mi,p_LDle16_then_16Uto32,e)) {
+ DECLARE_PATTERN(p_LDbe16_then_16Uto32);
+ DEFINE_PATTERN(p_LDbe16_then_16Uto32,
+ unop(Iop_16Uto32,
+ IRExpr_Load(Iend_BE,Ity_I16,bind(0))) );
+ if (matchIRExpr(&mi,p_LDbe16_then_16Uto32,e)) {
HReg r_dst = newVRegI(env);
PPC32AMode* amode = iselIntExpr_AMode ( env, mi.bindee[0] );
addInstr(env, PPC32Instr_Load(2,False,r_dst,amode));
@@ -2489,11 +2493,11 @@
return lookupIRTemp(env, e->Iex.Tmp.tmp);
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_BE) {
PPC32AMode* am_addr;
HReg r_dst = newVRegF(env);
- vassert(e->Iex.LDle.ty == Ity_F32);
- am_addr = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ vassert(e->Iex.Load.ty == Ity_F32);
+ am_addr = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, PPC32Instr_FpLdSt(True/*load*/, 4, r_dst, am_addr));
return r_dst;
}
@@ -2612,11 +2616,11 @@
return mk_LoadRRtoFPR( env, r_srcHi, r_srcLo );
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_BE) {
HReg r_dst = newVRegF(env);
PPC32AMode* am_addr;
- vassert(e->Iex.LDle.ty == Ity_F64);
- am_addr = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ vassert(e->Iex.Load.ty == Ity_F64);
+ am_addr = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, PPC32Instr_FpLdSt(True/*load*/, 8, r_dst, am_addr));
return r_dst;
}
@@ -2795,7 +2799,7 @@
static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
{
//.. Bool arg1isEReg = False;
- PPC32AvOp op = Pav_INVALID;
+ // unused: PPC32AvOp op = Pav_INVALID;
IRType ty = typeOfIRExpr(env->type_env,e);
vassert(e);
vassert(ty == Ity_V128);
@@ -3251,7 +3255,7 @@
//.. return dst;
//.. }
- vec_fail:
+ // unused: vec_fail:
vex_printf("iselVecExpr(ppc32) (subarch = %s): can't reduce\n",
LibVEX_ppVexSubArch(env->subarch));
ppIRExpr(e);
@@ -3274,32 +3278,35 @@
switch (stmt->tag) {
/* --------- STORE --------- */
- case Ist_STle: {
+ case Ist_Store: {
PPC32AMode* am_addr;
- IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.STle.addr);
- IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.STle.data);
- vassert(tya == Ity_I32);
+ IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
+ IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
+ IREndness end = stmt->Ist.Store.end;
- am_addr = iselIntExpr_AMode(env, stmt->Ist.STle.addr);
+ if (tya != Ity_I32 || end != Iend_BE)
+ goto stmt_fail;
+
+ am_addr = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
if (tyd == Ity_I8 || tyd == Ity_I16 || tyd == Ity_I32) {
- HReg r_src = iselIntExpr_R(env, stmt->Ist.STle.data);
+ HReg r_src = iselIntExpr_R(env, stmt->Ist.Store.data);
addInstr(env, PPC32Instr_Store(sizeofIRType(tyd), am_addr, r_src));
return;
}
if (tyd == Ity_F64) {
- HReg fr_src = iselDblExpr(env, stmt->Ist.STle.data);
+ HReg fr_src = iselDblExpr(env, stmt->Ist.Store.data);
addInstr(env, PPC32Instr_FpLdSt(False/*store*/, 8, fr_src, am_addr));
return;
}
if (tyd == Ity_F32) {
- HReg fr_src = iselFltExpr(env, stmt->Ist.STle.data);
+ HReg fr_src = iselFltExpr(env, stmt->Ist.Store.data);
addInstr(env, PPC32Instr_FpLdSt(False/*store*/, 4, fr_src, am_addr));
return;
}
//.. if (tyd == Ity_I64) {
//.. HReg vHi, vLo, rA;
-//.. iselInt64Expr(&vHi, &vLo, env, stmt->Ist.STle.data);
-//.. rA = iselIntExpr_R(env, stmt->Ist.STle.addr);
+//.. iselInt64Expr(&vHi, &vLo, env, stmt->Ist.Store.data);
+//.. rA = iselIntExpr_R(env, stmt->Ist.Store.addr);
//.. addInstr(env, X86Instr_Alu32M(
//.. Xalu_MOV, X86RI_Reg(vLo), X86AMode_IR(0, rA)));
//.. addInstr(env, X86Instr_Alu32M(
@@ -3307,7 +3314,7 @@
//.. return;
//.. }
if (tyd == Ity_V128) {
- HReg v_src = iselVecExpr(env, stmt->Ist.STle.data);
+ HReg v_src = iselVecExpr(env, stmt->Ist.Store.data);
addInstr(env, PPC32Instr_AvLdSt(False/*store*/, 16, v_src, am_addr));
return;
}
@@ -3496,6 +3503,7 @@
default: break;
}
+ stmt_fail:
ppIRStmt(stmt);
vpanic("iselStmt(ppc32)");
}
diff --git a/priv/host-x86/isel.c b/priv/host-x86/isel.c
index 0c07662..f6fe7f6 100644
--- a/priv/host-x86/isel.c
+++ b/priv/host-x86/isel.c
@@ -726,9 +726,13 @@
}
/* --------- LOAD --------- */
- case Iex_LDle: {
+ case Iex_Load: {
HReg dst = newVRegI(env);
- X86AMode* amode = iselIntExpr_AMode ( env, e->Iex.LDle.addr );
+ X86AMode* amode = iselIntExpr_AMode ( env, e->Iex.Load.addr );
+
+ if (e->Iex.Load.end != Iend_LE)
+ goto irreducible;
+
if (ty == Ity_I32) {
addInstr(env, X86Instr_Alu32R(Xalu_MOV,
X86RMI_Mem(amode), dst) );
@@ -1000,7 +1004,8 @@
{
DECLARE_PATTERN(p_LDle16_then_16Uto32);
DEFINE_PATTERN(p_LDle16_then_16Uto32,
- unop(Iop_16Uto32,IRExpr_LDle(Ity_I16,bind(0))) );
+ unop(Iop_16Uto32,
+ IRExpr_Load(Iend_LE,Ity_I16,bind(0))) );
if (matchIRExpr(&mi,p_LDle16_then_16Uto32,e)) {
HReg dst = newVRegI(env);
X86AMode* amode = iselIntExpr_AMode ( env, mi.bindee[0] );
@@ -1351,8 +1356,8 @@
}
/* special case: 32-bit load from memory */
- if (e->tag == Iex_LDle && ty == Ity_I32) {
- X86AMode* am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ if (e->tag == Iex_Load && ty == Ity_I32 && e->Iex.Load.end == Iend_LE) {
+ X86AMode* am = iselIntExpr_AMode(env, e->Iex.Load.addr);
return X86RMI_Mem(am);
}
@@ -1782,13 +1787,13 @@
}
/* 64-bit load */
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
HReg tLo, tHi;
X86AMode *am0, *am4;
- vassert(e->Iex.LDle.ty == Ity_I64);
+ vassert(e->Iex.Load.ty == Ity_I64);
tLo = newVRegI(env);
tHi = newVRegI(env);
- am0 = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ am0 = iselIntExpr_AMode(env, e->Iex.Load.addr);
am4 = advance4(am0);
addInstr(env, X86Instr_Alu32R( Xalu_MOV, X86RMI_Mem(am0), tLo ));
addInstr(env, X86Instr_Alu32R( Xalu_MOV, X86RMI_Mem(am4), tHi ));
@@ -2433,11 +2438,11 @@
return lookupIRTemp(env, e->Iex.Tmp.tmp);
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
X86AMode* am;
HReg res = newVRegF(env);
- vassert(e->Iex.LDle.ty == Ity_F32);
- am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ vassert(e->Iex.Load.ty == Ity_F32);
+ am = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, X86Instr_FpLdSt(True/*load*/, 4, res, am));
return res;
}
@@ -2557,11 +2562,11 @@
return freg;
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
X86AMode* am;
HReg res = newVRegF(env);
- vassert(e->Iex.LDle.ty == Ity_F64);
- am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ vassert(e->Iex.Load.ty == Ity_F64);
+ am = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, X86Instr_FpLdSt(True/*load*/, 8, res, am));
return res;
}
@@ -2792,9 +2797,9 @@
return dst;
}
- if (e->tag == Iex_LDle) {
+ if (e->tag == Iex_Load && e->Iex.Load.end == Iend_LE) {
HReg dst = newVRegV(env);
- X86AMode* am = iselIntExpr_AMode(env, e->Iex.LDle.addr);
+ X86AMode* am = iselIntExpr_AMode(env, e->Iex.Load.addr);
addInstr(env, X86Instr_SseLdSt( True/*load*/, dst, am ));
return dst;
}
@@ -2812,7 +2817,8 @@
/* 64UtoV128(LDle:I64(addr)) */
DECLARE_PATTERN(p_zwiden_load64);
DEFINE_PATTERN(p_zwiden_load64,
- unop(Iop_64UtoV128, IRExpr_LDle(Ity_I64,bind(0))));
+ unop(Iop_64UtoV128,
+ IRExpr_Load(Iend_LE,Ity_I64,bind(0))));
if (matchIRExpr(&mi, p_zwiden_load64, e)) {
X86AMode* am = iselIntExpr_AMode(env, mi.bindee[0]);
HReg dst = newVRegV(env);
@@ -3272,37 +3278,41 @@
switch (stmt->tag) {
/* --------- STORE --------- */
- case Ist_STle: {
+ case Ist_Store: {
X86AMode* am;
- IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.STle.addr);
- IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.STle.data);
- vassert(tya == Ity_I32);
- am = iselIntExpr_AMode(env, stmt->Ist.STle.addr);
+ IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);
+ IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);
+ IREndness end = stmt->Ist.Store.end;
+
+ if (tya != Ity_I32 || end != Iend_LE)
+ goto stmt_fail;
+
+ am = iselIntExpr_AMode(env, stmt->Ist.Store.addr);
if (tyd == Ity_I32) {
- X86RI* ri = iselIntExpr_RI(env, stmt->Ist.STle.data);
+ X86RI* ri = iselIntExpr_RI(env, stmt->Ist.Store.data);
addInstr(env, X86Instr_Alu32M(Xalu_MOV,ri,am));
return;
}
if (tyd == Ity_I8 || tyd == Ity_I16) {
- HReg r = iselIntExpr_R(env, stmt->Ist.STle.data);
+ HReg r = iselIntExpr_R(env, stmt->Ist.Store.data);
addInstr(env, X86Instr_Store( toUChar(tyd==Ity_I8 ? 1 : 2),
r,am ));
return;
}
if (tyd == Ity_F64) {
- HReg r = iselDblExpr(env, stmt->Ist.STle.data);
+ HReg r = iselDblExpr(env, stmt->Ist.Store.data);
addInstr(env, X86Instr_FpLdSt(False/*store*/, 8, r, am));
return;
}
if (tyd == Ity_F32) {
- HReg r = iselFltExpr(env, stmt->Ist.STle.data);
+ HReg r = iselFltExpr(env, stmt->Ist.Store.data);
addInstr(env, X86Instr_FpLdSt(False/*store*/, 4, r, am));
return;
}
if (tyd == Ity_I64) {
HReg vHi, vLo, rA;
- iselInt64Expr(&vHi, &vLo, env, stmt->Ist.STle.data);
- rA = iselIntExpr_R(env, stmt->Ist.STle.addr);
+ iselInt64Expr(&vHi, &vLo, env, stmt->Ist.Store.data);
+ rA = iselIntExpr_R(env, stmt->Ist.Store.addr);
addInstr(env, X86Instr_Alu32M(
Xalu_MOV, X86RI_Reg(vLo), X86AMode_IR(0, rA)));
addInstr(env, X86Instr_Alu32M(
@@ -3310,7 +3320,7 @@
return;
}
if (tyd == Ity_V128) {
- HReg r = iselVecExpr(env, stmt->Ist.STle.data);
+ HReg r = iselVecExpr(env, stmt->Ist.Store.data);
addInstr(env, X86Instr_SseLdSt(False/*store*/, r, am));
return;
}
@@ -3520,6 +3530,7 @@
default: break;
}
+ stmt_fail:
ppIRStmt(stmt);
vpanic("iselStmt");
}
diff --git a/priv/ir/irdefs.c b/priv/ir/irdefs.c
index 89ad73a..d079f75 100644
--- a/priv/ir/irdefs.c
+++ b/priv/ir/irdefs.c
@@ -501,11 +501,11 @@
ppIRExpr(e->Iex.Unop.arg);
vex_printf( ")" );
break;
- case Iex_LDle:
- vex_printf( "LDle:" );
- ppIRType(e->Iex.LDle.ty);
+ case Iex_Load:
+ vex_printf( "LD%s:", e->Iex.Load.end==Iend_LE ? "le" : "be" );
+ ppIRType(e->Iex.Load.ty);
vex_printf( "(" );
- ppIRExpr(e->Iex.LDle.addr);
+ ppIRExpr(e->Iex.Load.addr);
vex_printf( ")" );
break;
case Iex_Const:
@@ -635,11 +635,11 @@
vex_printf( " = " );
ppIRExpr(s->Ist.Tmp.data);
break;
- case Ist_STle:
- vex_printf( "STle(");
- ppIRExpr(s->Ist.STle.addr);
+ case Ist_Store:
+ vex_printf( "ST%s(", s->Ist.Store.end==Iend_LE ? "le" : "be" );
+ ppIRExpr(s->Ist.Store.addr);
vex_printf( ") = ");
- ppIRExpr(s->Ist.STle.data);
+ ppIRExpr(s->Ist.Store.data);
break;
case Ist_Dirty:
ppIRDirty(s->Ist.Dirty.details);
@@ -837,11 +837,13 @@
e->Iex.Unop.arg = arg;
return e;
}
-IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ) {
+IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ) {
IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
- e->tag = Iex_LDle;
- e->Iex.LDle.ty = ty;
- e->Iex.LDle.addr = addr;
+ e->tag = Iex_Load;
+ e->Iex.Load.end = end;
+ e->Iex.Load.ty = ty;
+ e->Iex.Load.addr = addr;
+ vassert(end == Iend_LE || end == Iend_BE);
return e;
}
IRExpr* IRExpr_Const ( IRConst* con ) {
@@ -984,11 +986,13 @@
s->Ist.Tmp.data = data;
return s;
}
-IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data ) {
- IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
- s->tag = Ist_STle;
- s->Ist.STle.addr = addr;
- s->Ist.STle.data = data;
+IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ) {
+ IRStmt* s = LibVEX_Alloc(sizeof(IRStmt));
+ s->tag = Ist_Store;
+ s->Ist.Store.end = end;
+ s->Ist.Store.addr = addr;
+ s->Ist.Store.data = data;
+ vassert(end == Iend_LE || end == Iend_BE);
return s;
}
IRStmt* IRStmt_Dirty ( IRDirty* d )
@@ -1123,9 +1127,10 @@
case Iex_Unop:
return IRExpr_Unop(e->Iex.Unop.op,
dopyIRExpr(e->Iex.Unop.arg));
- case Iex_LDle:
- return IRExpr_LDle(e->Iex.LDle.ty,
- dopyIRExpr(e->Iex.LDle.addr));
+ case Iex_Load:
+ return IRExpr_Load(e->Iex.Load.end,
+ e->Iex.Load.ty,
+ dopyIRExpr(e->Iex.Load.addr));
case Iex_Const:
return IRExpr_Const(dopyIRConst(e->Iex.Const.con));
case Iex_CCall:
@@ -1181,9 +1186,10 @@
case Ist_Tmp:
return IRStmt_Tmp(s->Ist.Tmp.tmp,
dopyIRExpr(s->Ist.Tmp.data));
- case Ist_STle:
- return IRStmt_STle(dopyIRExpr(s->Ist.STle.addr),
- dopyIRExpr(s->Ist.STle.data));
+ case Ist_Store:
+ return IRStmt_Store(s->Ist.Store.end,
+ dopyIRExpr(s->Ist.Store.addr),
+ dopyIRExpr(s->Ist.Store.data));
case Ist_Dirty:
return IRStmt_Dirty(dopyIRDirty(s->Ist.Dirty.details));
case Ist_MFence:
@@ -1596,8 +1602,8 @@
IRType t_dst, t_arg1, t_arg2;
start:
switch (e->tag) {
- case Iex_LDle:
- return e->Iex.LDle.ty;
+ case Iex_Load:
+ return e->Iex.Load.ty;
case Iex_Get:
return e->Iex.Get.ty;
case Iex_GetI:
@@ -1684,7 +1690,7 @@
isIRAtom(e->Iex.Binop.arg1)
&& isIRAtom(e->Iex.Binop.arg2));
case Iex_Unop: return isIRAtom(e->Iex.Unop.arg);
- case Iex_LDle: return isIRAtom(e->Iex.LDle.addr);
+ case Iex_Load: return isIRAtom(e->Iex.Load.addr);
case Iex_Const: return True;
case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++)
if (!isIRAtom(e->Iex.CCall.args[i]))
@@ -1698,9 +1704,9 @@
}
/*notreached*/
vassert(0);
- case Ist_STle:
- return toBool( isIRAtom(st->Ist.STle.addr)
- && isIRAtom(st->Ist.STle.data) );
+ case Ist_Store:
+ return toBool( isIRAtom(st->Ist.Store.addr)
+ && isIRAtom(st->Ist.Store.data) );
case Ist_Dirty:
di = st->Ist.Dirty.details;
if (!isIRAtom(di->guard))
@@ -1825,8 +1831,8 @@
case Iex_Unop:
useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
break;
- case Iex_LDle:
- useBeforeDef_Expr(bb,stmt,expr->Iex.LDle.addr,def_counts);
+ case Iex_Load:
+ useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);
break;
case Iex_Const:
break;
@@ -1865,9 +1871,9 @@
case Ist_Tmp:
useBeforeDef_Expr(bb,stmt,stmt->Ist.Tmp.data,def_counts);
break;
- case Ist_STle:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.addr,def_counts);
- useBeforeDef_Expr(bb,stmt,stmt->Ist.STle.data,def_counts);
+ case Ist_Store:
+ useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);
+ useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);
break;
case Ist_Dirty:
d = stmt->Ist.Dirty.details;
@@ -1948,10 +1954,12 @@
if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg))
sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
break;
- case Iex_LDle:
- tcExpr(bb,stmt, expr->Iex.LDle.addr, gWordTy);
- if (typeOfIRExpr(tyenv, expr->Iex.LDle.addr) != gWordTy)
- sanityCheckFail(bb,stmt,"Iex.LDle.addr: not :: guest word type");
+ case Iex_Load:
+ tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy);
+ if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
+ sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
+ if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
+ sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness");
break;
case Iex_CCall:
if (!saneIRCallee(expr->Iex.CCall.cee))
@@ -2031,13 +2039,15 @@
!= typeOfIRExpr(tyenv, stmt->Ist.Tmp.data))
sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
break;
- case Ist_STle:
- tcExpr( bb, stmt, stmt->Ist.STle.addr, gWordTy );
- tcExpr( bb, stmt, stmt->Ist.STle.data, gWordTy );
- if (typeOfIRExpr(tyenv, stmt->Ist.STle.addr) != gWordTy)
- sanityCheckFail(bb,stmt,"IRStmt.STle.addr: not :: guest word type");
- if (typeOfIRExpr(tyenv, stmt->Ist.STle.data) == Ity_I1)
- sanityCheckFail(bb,stmt,"IRStmt.STle.data: cannot STle :: Ity_I1");
+ case Ist_Store:
+ tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy );
+ tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy );
+ if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
+ sanityCheckFail(bb,stmt,"IRStmt.Store.addr: not :: guest word type");
+ if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1)
+ sanityCheckFail(bb,stmt,"IRStmt.Store.data: cannot Store :: Ity_I1");
+ if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE)
+ sanityCheckFail(bb,stmt,"Ist.Store.end: bogus endianness");
break;
case Ist_Dirty:
/* Mostly check for various kinds of ill-formed dirty calls. */
diff --git a/priv/ir/irmatch.c b/priv/ir/irmatch.c
index fe1fbf4..299fb0a 100644
--- a/priv/ir/irmatch.c
+++ b/priv/ir/irmatch.c
@@ -86,10 +86,11 @@
if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2))
return False;
return True;
- case Iex_LDle:
- if (e->tag != Iex_LDle) return False;
- if (p->Iex.LDle.ty != e->Iex.LDle.ty) return False;
- if (!matchWrk(mi, p->Iex.LDle.addr, e->Iex.LDle.addr))
+ case Iex_Load:
+ if (e->tag != Iex_Load) return False;
+ if (p->Iex.Load.end != e->Iex.Load.end) return False;
+ if (p->Iex.Load.ty != e->Iex.Load.ty) return False;
+ if (!matchWrk(mi, p->Iex.Load.addr, e->Iex.Load.addr))
return False;
return True;
case Iex_Const:
diff --git a/priv/ir/iropt.c b/priv/ir/iropt.c
index af595ef..e0d0108 100644
--- a/priv/ir/iropt.c
+++ b/priv/ir/iropt.c
@@ -253,8 +253,8 @@
if (e->tag == Iex_Binop)
return toBool( isIRAtom(e->Iex.Binop.arg1)
&& isIRAtom(e->Iex.Binop.arg2) );
- if (e->tag == Iex_LDle)
- return isIRAtom(e->Iex.LDle.addr);
+ if (e->tag == Iex_Load)
+ return isIRAtom(e->Iex.Load.addr);
return False;
}
@@ -300,11 +300,12 @@
flatten_Expr(bb, ex->Iex.Unop.arg))));
return IRExpr_Tmp(t1);
- case Iex_LDle:
+ case Iex_Load:
t1 = newIRTemp(bb->tyenv, ty);
addStmtToIRBB(bb, IRStmt_Tmp(t1,
- IRExpr_LDle(ex->Iex.LDle.ty,
- flatten_Expr(bb, ex->Iex.LDle.addr))));
+ IRExpr_Load(ex->Iex.Load.end,
+ ex->Iex.Load.ty,
+ flatten_Expr(bb, ex->Iex.Load.addr))));
return IRExpr_Tmp(t1);
case Iex_CCall:
@@ -389,10 +390,10 @@
addStmtToIRBB(bb, IRStmt_Tmp(st->Ist.Tmp.tmp, e1));
}
break;
- case Ist_STle:
- e1 = flatten_Expr(bb, st->Ist.STle.addr);
- e2 = flatten_Expr(bb, st->Ist.STle.data);
- addStmtToIRBB(bb, IRStmt_STle(e1,e2));
+ case Ist_Store:
+ e1 = flatten_Expr(bb, st->Ist.Store.addr);
+ e2 = flatten_Expr(bb, st->Ist.Store.data);
+ addStmtToIRBB(bb, IRStmt_Store(st->Ist.Store.end, e1,e2));
break;
case Ist_Dirty:
d = st->Ist.Dirty.details;
@@ -652,7 +653,7 @@
isGet = True;
key = mk_key_GetIPutI ( e->Iex.GetI.descr );
break;
- case Iex_LDle:
+ case Iex_Load:
isGet = False;
memRW = True;
break;
@@ -686,9 +687,9 @@
break;
/* all other cases are boring. */
- case Ist_STle:
- vassert(isIRAtom(st->Ist.STle.addr));
- vassert(isIRAtom(st->Ist.STle.data));
+ case Ist_Store:
+ vassert(isIRAtom(st->Ist.Store.addr));
+ vassert(isIRAtom(st->Ist.Store.data));
memRW = True;
break;
@@ -1469,11 +1470,12 @@
subst_Expr(env, ex->Iex.Unop.arg)
);
- case Iex_LDle:
- vassert(isIRAtom(ex->Iex.LDle.addr));
- return IRExpr_LDle(
- ex->Iex.LDle.ty,
- subst_Expr(env, ex->Iex.LDle.addr)
+ case Iex_Load:
+ vassert(isIRAtom(ex->Iex.Load.addr));
+ return IRExpr_Load(
+ ex->Iex.Load.end,
+ ex->Iex.Load.ty,
+ subst_Expr(env, ex->Iex.Load.addr)
);
case Iex_CCall: {
@@ -1552,12 +1554,13 @@
fold_Expr(subst_Expr(env, st->Ist.Tmp.data))
);
- case Ist_STle:
- vassert(isIRAtom(st->Ist.STle.addr));
- vassert(isIRAtom(st->Ist.STle.data));
- return IRStmt_STle(
- fold_Expr(subst_Expr(env, st->Ist.STle.addr)),
- fold_Expr(subst_Expr(env, st->Ist.STle.data))
+ case Ist_Store:
+ vassert(isIRAtom(st->Ist.Store.addr));
+ vassert(isIRAtom(st->Ist.Store.data));
+ return IRStmt_Store(
+ st->Ist.Store.end,
+ fold_Expr(subst_Expr(env, st->Ist.Store.addr)),
+ fold_Expr(subst_Expr(env, st->Ist.Store.data))
);
case Ist_Dirty: {
@@ -1724,8 +1727,8 @@
for (i = 0; e->Iex.CCall.args[i]; i++)
addUses_Expr(set, e->Iex.CCall.args[i]);
return;
- case Iex_LDle:
- addUses_Expr(set, e->Iex.LDle.addr);
+ case Iex_Load:
+ addUses_Expr(set, e->Iex.Load.addr);
return;
case Iex_Binop:
addUses_Expr(set, e->Iex.Binop.arg1);
@@ -1765,9 +1768,9 @@
case Ist_Put:
addUses_Expr(set, st->Ist.Put.data);
return;
- case Ist_STle:
- addUses_Expr(set, st->Ist.STle.addr);
- addUses_Expr(set, st->Ist.STle.data);
+ case Ist_Store:
+ addUses_Expr(set, st->Ist.Store.addr);
+ addUses_Expr(set, st->Ist.Store.data);
return;
case Ist_Dirty:
d = st->Ist.Dirty.details;
@@ -2650,9 +2653,9 @@
}
return False;
- case Ist_STle:
- vassert(isIRAtom(s2->Ist.STle.addr));
- vassert(isIRAtom(s2->Ist.STle.data));
+ case Ist_Store:
+ vassert(isIRAtom(s2->Ist.Store.addr));
+ vassert(isIRAtom(s2->Ist.Store.data));
return False;
default:
@@ -2799,8 +2802,8 @@
case Iex_Unop:
deltaIRExpr(e->Iex.Unop.arg, delta);
break;
- case Iex_LDle:
- deltaIRExpr(e->Iex.LDle.addr, delta);
+ case Iex_Load:
+ deltaIRExpr(e->Iex.Load.addr, delta);
break;
case Iex_CCall:
for (i = 0; e->Iex.CCall.args[i]; i++)
@@ -2846,9 +2849,9 @@
case Ist_Exit:
deltaIRExpr(st->Ist.Exit.guard, delta);
break;
- case Ist_STle:
- deltaIRExpr(st->Ist.STle.addr, delta);
- deltaIRExpr(st->Ist.STle.data, delta);
+ case Ist_Store:
+ deltaIRExpr(st->Ist.Store.addr, delta);
+ deltaIRExpr(st->Ist.Store.data, delta);
break;
case Ist_Dirty:
d = st->Ist.Dirty.details;
@@ -3161,8 +3164,8 @@
occCount_Expr(env, e->Iex.Unop.arg);
return;
- case Iex_LDle:
- occCount_Expr(env, e->Iex.LDle.addr);
+ case Iex_Load:
+ occCount_Expr(env, e->Iex.Load.addr);
return;
case Iex_CCall:
@@ -3207,9 +3210,9 @@
occCount_Expr(env, st->Ist.PutI.ix);
occCount_Expr(env, st->Ist.PutI.data);
return;
- case Ist_STle:
- occCount_Expr(env, st->Ist.STle.addr);
- occCount_Expr(env, st->Ist.STle.data);
+ case Ist_Store:
+ occCount_Expr(env, st->Ist.Store.addr);
+ occCount_Expr(env, st->Ist.Store.data);
return;
case Ist_Dirty:
d = st->Ist.Dirty.details;
@@ -3296,10 +3299,11 @@
e->Iex.Unop.op,
tbSubst_Expr(env, e->Iex.Unop.arg)
);
- case Iex_LDle:
- return IRExpr_LDle(
- e->Iex.LDle.ty,
- tbSubst_Expr(env, e->Iex.LDle.addr)
+ case Iex_Load:
+ return IRExpr_Load(
+ e->Iex.Load.end,
+ e->Iex.Load.ty,
+ tbSubst_Expr(env, e->Iex.Load.addr)
);
case Iex_GetI:
return IRExpr_GetI(
@@ -3329,10 +3333,11 @@
tbSubst_Expr(env, st->Ist.AbiHint.base),
st->Ist.AbiHint.len
);
- case Ist_STle:
- return IRStmt_STle(
- tbSubst_Expr(env, st->Ist.STle.addr),
- tbSubst_Expr(env, st->Ist.STle.data)
+ case Ist_Store:
+ return IRStmt_Store(
+ st->Ist.Store.end,
+ tbSubst_Expr(env, st->Ist.Store.addr),
+ tbSubst_Expr(env, st->Ist.Store.data)
);
case Ist_Tmp:
return IRStmt_Tmp(
@@ -3405,9 +3410,9 @@
case Iex_Unop:
setHints_Expr(doesLoad, doesGet, e->Iex.Unop.arg);
return;
- case Iex_LDle:
+ case Iex_Load:
*doesLoad = True;
- setHints_Expr(doesLoad, doesGet, e->Iex.LDle.addr);
+ setHints_Expr(doesLoad, doesGet, e->Iex.Load.addr);
return;
case Iex_Get:
*doesGet = True;
@@ -3587,7 +3592,7 @@
|| st->tag == Ist_PutI
|| st->tag == Ist_Dirty);
- invStore = toBool(st->tag == Ist_STle
+ invStore = toBool(st->tag == Ist_Store
|| st->tag == Ist_Dirty);
for (k = 0; k < n_tmps; k++) {
@@ -3741,9 +3746,9 @@
case Ist_Put:
vassert(isIRAtom(st->Ist.Put.data));
break;
- case Ist_STle:
- vassert(isIRAtom(st->Ist.STle.addr));
- vassert(isIRAtom(st->Ist.STle.data));
+ case Ist_Store:
+ vassert(isIRAtom(st->Ist.Store.addr));
+ vassert(isIRAtom(st->Ist.Store.data));
break;
case Ist_Dirty:
d = st->Ist.Dirty.details;