/* declare we're writing guest state */
d->nFxState = 4;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're reading guest state */
d->nFxState = 4;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're writing guest state */
d->nFxState = 5;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're writing guest state */
d->nFxState = 5;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're reading guest state */
d->nFxState = 5;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're writing memory */
d->mFx = Ifx_Write;
d->mAddr = mkexpr(addr);
- d->mSize = 512;
+ d->mSize = 464; /* according to recent Intel docs */
/* declare we're reading guest state */
d->nFxState = 7;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = OFFB_FTOP;
d->fxState[5].fx = Ifx_Read;
d->fxState[5].offset = OFFB_YMM0;
- d->fxState[5].size = 16 * sizeof(U128);
+ d->fxState[5].size = sizeof(U128);
+ /* plus 15 more of the above, spaced out in YMM sized steps */
+ d->fxState[5].nRepeats = 15;
+ d->fxState[5].repeatLen = sizeof(U256);
d->fxState[6].fx = Ifx_Read;
d->fxState[6].offset = OFFB_SSEROUND;
d->fxState[6].size = sizeof(ULong);
/* Be paranoid ... this assertion tries to ensure the 16 %ymm
- images are packed back-to-back. If not, the value of
- d->fxState[5].size is wrong. */
+ images are packed back-to-back. If not, the settings for
+ d->fxState[5] are wrong. */
vassert(32 == sizeof(U256));
vassert(OFFB_YMM15 == (OFFB_YMM0 + 15 * 32));
/* declare we're reading memory */
d->mFx = Ifx_Read;
d->mAddr = mkexpr(addr);
- d->mSize = 512;
+ d->mSize = 464; /* according to recent Intel docs */
/* declare we're writing guest state */
d->nFxState = 7;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
d->fxState[5].fx = Ifx_Write;
d->fxState[5].offset = OFFB_YMM0;
- d->fxState[5].size = 16 * sizeof(U128);
+ d->fxState[5].size = sizeof(U128);
+ /* plus 15 more of the above, spaced out in YMM sized steps */
+ d->fxState[5].nRepeats = 15;
+ d->fxState[5].repeatLen = sizeof(U256);
d->fxState[6].fx = Ifx_Write;
d->fxState[6].offset = OFFB_SSEROUND;
d->fxState[6].size = sizeof(ULong);
/* Be paranoid ... this assertion tries to ensure the 16 %ymm
- images are packed back-to-back. If not, the value of
- d->fxState[5].size is wrong. */
+ images are packed back-to-back. If not, the settings for
+ d->fxState[5] are wrong. */
vassert(32 == sizeof(U256));
vassert(OFFB_YMM15 == (OFFB_YMM0 + 15 * 32));
this roundabout scheme. */
d->needsBBP = True;
d->nFxState = 2;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
/* AES{ENC,ENCLAST,DEC,DECLAST} read both registers, and writes
the second.
AESIMC (0xDB) reads the first register, and writes the second. */
roundabout scheme. */
d->needsBBP = True;
d->nFxState = 2;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = gstOffL;
d->fxState[0].size = sizeof(U128);
this roundabout scheme. */
d->needsBBP = True;
d->nFxState = 2;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = gstOffL;
d->fxState[0].size = sizeof(U128);
/* declare guest state effects */
d->needsBBP = True;
d->nFxState = 4;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Modify;
d->fxState[0].offset = OFFB_RAX;
d->fxState[0].size = 8;
/* declare guest state effects */
d->needsBBP = True;
d->nFxState = 1;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = vD_off;
d->fxState[0].size = sizeof(U128);
/* declare guest state effects */
d->needsBBP = True;
d->nFxState = 1;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = vD_off;
d->fxState[0].size = sizeof(U128);
mkIRExprVec_0());
d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
+ d->nFxState = 1;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
+
d->fxState[0].fx = Ifx_Modify; /* read then write */
d->fxState[0].offset = S390X_GUEST_OFFSET(guest_IA);
d->fxState[0].size = sizeof(ULong);
- d->nFxState = 1;
stmt(IRStmt_Dirty(d));
d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
+ d->nFxState = 1;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
+
d->fxState[0].fx = Ifx_Modify; /* read then write */
d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
d->fxState[0].size = sizeof(ULong);
- d->nFxState = 1;
d->mAddr = mkexpr(op2addr);
/* Pretend all double words are written */
/* declare we're writing guest state */
d->nFxState = 4;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're reading guest state */
d->nFxState = 4;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're writing guest state */
d->nFxState = 5;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're writing guest state */
d->nFxState = 5;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're reading guest state */
d->nFxState = 5;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're writing memory */
d->mFx = Ifx_Write;
d->mAddr = mkexpr(addr);
- d->mSize = 512;
+ d->mSize = 464; /* according to recent Intel docs */
/* declare we're reading guest state */
d->nFxState = 7;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Read;
d->fxState[0].offset = OFFB_FTOP;
/* declare we're reading memory */
d->mFx = Ifx_Read;
d->mAddr = mkexpr(addr);
- d->mSize = 512;
+ d->mSize = 464; /* according to recent Intel docs */
/* declare we're writing guest state */
d->nFxState = 7;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Write;
d->fxState[0].offset = OFFB_FTOP;
/* declare guest state effects */
d->needsBBP = True;
d->nFxState = 4;
+ vex_bzero(&d->fxState, sizeof(d->fxState));
d->fxState[0].fx = Ifx_Modify;
d->fxState[0].offset = OFFB_EAX;
d->fxState[0].size = 4;
/* Invalidate tracked values of those guest state registers that are
modified by this helper. */
for (i = 0; i < d->nFxState; ++i) {
+ /* JRS 1 June 2012: AFAICS, s390 guest doesn't use 'repeat'
+ descriptors in guest state effect descriptions. Hence: */
+ vassert(d->fxState[i].nRepeats == 0 && d->fxState[i].repeatLen == 0);
if ((d->fxState[i].fx == Ifx_Write || d->fxState[i].fx == Ifx_Modify)) {
Int guest_reg = get_guest_reg(d->fxState[i].offset);
if (guest_reg != GUEST_UNKNOWN)
for (i = 0; i < d->nFxState; i++) {
vex_printf(" ");
ppIREffect(d->fxState[i].fx);
- vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
+ vex_printf("-gst(%u,%u", (UInt)d->fxState[i].offset,
+ (UInt)d->fxState[i].size);
+ if (d->fxState[i].nRepeats > 0) {
+ vex_printf(",reps%u,step%u", (UInt)d->fxState[i].nRepeats,
+ (UInt)d->fxState[i].repeatLen);
+ }
+ vex_printf(")");
}
vex_printf(" ::: ");
ppIRCallee(d->cee);
for (i = 0; i < d->nFxState; i++) {
if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
if (d->fxState[i].size <= 0) goto bad_dirty;
+ if (d->fxState[i].nRepeats == 0) {
+ if (d->fxState[i].repeatLen != 0) goto bad_dirty;
+ } else {
+ if (d->fxState[i].repeatLen <= d->fxState[i].size)
+ goto bad_dirty;
+ /* the % is safe because of the .size check above */
+ if ((d->fxState[i].repeatLen % d->fxState[i].size) != 0)
+ goto bad_dirty;
+ }
}
/* check types, minimally */
if (d->guard == NULL) goto bad_dirty;
vassert(8 == sizeof(Addr64));
vassert(16 == sizeof(U128));
vassert(16 == sizeof(V128));
+ vassert(32 == sizeof(U256));
vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
vassert(sizeof(void*) == sizeof(int*));
}
}
+void vex_bzero ( void* sV, UInt n )
+{
+ UInt i;
+ UChar* s = (UChar*)sV;
+ /* No laughing, please. Just don't call this too often. Thank you
+ for your attention. */
+ for (i = 0; i < n; i++) s[i] = 0;
+}
+
/* Convert N0 into ascii in BUF, which is assumed to be big enough (at
least 67 bytes long). Observe BASE, SYNED and HEXCAPS. */
/* String ops */
extern Bool vex_streq ( const HChar* s1, const HChar* s2 );
-extern Int vex_strlen ( const HChar* str );
+extern Int vex_strlen ( const HChar* str );
+extern void vex_bzero ( void* s, UInt n );
/* Storage management: clear the area, and allocate from it. */
/* Effects on resources (eg. registers, memory locations) */
typedef
enum {
- Ifx_None = 0x17000, /* no effect */
+ Ifx_None = 0x1700, /* no effect */
Ifx_Read, /* reads the resource */
Ifx_Write, /* writes the resource */
Ifx_Modify, /* modifies the resource */
typedef
- struct {
+ struct _IRDirty {
/* What to call, and details of args/results */
IRCallee* cee; /* where to call */
IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */
Bool needsBBP; /* True => also pass guest state ptr to callee */
Int nFxState; /* must be 0 .. VEX_N_FXSTATE */
struct {
- IREffect fx; /* read, write or modify? Ifx_None is invalid. */
- Int offset;
- Int size;
+ IREffect fx:16; /* read, write or modify? Ifx_None is invalid. */
+ UShort offset;
+ UShort size;
+ UChar nRepeats;
+ UChar repeatLen;
} fxState[VEX_N_FXSTATE];
+ /* The access can be repeated, as specified by nRepeats and
+ repeatLen. To describe only a single access, nRepeats and
+ repeatLen should be zero. Otherwise, repeatLen must be a
+ multiple of size and greater than size. */
+ /* Overall, the parts of the guest state denoted by (offset,
+ size, nRepeats, repeatLen) is
+ [offset, +size)
+ and, if nRepeats > 0,
+ for (i = 1; i <= nRepeats; i++)
+ [offset + i * repeatLen, +size)
+ A convenient way to enumerate all segments is therefore
+ for (i = 0; i < 1 + nRepeats; i++)
+ [offset + i * repeatLen, +size)
+ */
}
IRDirty;
extern IRPutI* deepCopyIRPutI ( IRPutI* );
+
/* ------------------ Statements ------------------ */
/* The different kinds of statements. Their meaning is explained