IRExpr_Load(endian, Ity_I64, addr));
}
if (type == Ity_I1) {
- /* A Boolean value is stored as a 32-bit entity (see store_aux). */
+ /* A Boolean value is stored as a 32-bit entity. For an explanation
+ see comment in vbit-test/vbits.h */
return unop(Iop_32to1, IRExpr_Load(endian, Ity_I32, addr));
}
data = unop(Iop_ReinterpD64asI64, data);
}
if (typeOfIRExpr(irsb->tyenv, data) == Ity_I1) {
- /* We cannot store a single bit. So we store it in a 32-bit container.
- See also load_aux. */
+ /* A Boolean value is stored as a 32-bit entity. For an explanation
+ see comment in vbit-test/vbits.h */
data = unop(Iop_1Uto32, data);
}
stmt(irsb, IRStmt_Store(endian, addr, data));
print_value(FILE *fp, value_t val, unsigned num_bits)
{
switch (num_bits) {
- case 1: fprintf(fp, "%02x", val.u8); break;
+ case 1: fprintf(fp, "%01x", val.u32); break; // see comment in vbits.h
case 8: fprintf(fp, "%02x", val.u8); break;
case 16: fprintf(fp, "%04x", val.u16); break;
case 32: fprintf(fp, "%08x", val.u32); break;
{
unsigned rc, num_bytes;
- /* 1-bit wide values cannot be read. So we read a 4 bytes here */
+ /* 1-bit wide values cannot be read. So we read 4 bytes here */
num_bytes = opnd->type == Ity_I1 ? 4 : sizeof_irtype(opnd->type);
rc = VALGRIND_SET_VBITS(&opnd->value, &opnd->vbits.bits, num_bytes);
assert(rc == 1);
{
unsigned rc, num_bytes;
- /* 1-bit wide values cannot be stored. So we store them by writing a
- single byte */
+ /* 1-bit wide values cannot be stored. So we store them by writing
+ 4 bytes which is what ir_inject.c expects. */
num_bytes = opnd->type == Ity_I1 ? 4 : sizeof_irtype(opnd->type);
opnd->vbits.num_bits = bitsof_irtype(opnd->type);
rc = VALGRIND_GET_VBITS(&opnd->value, &opnd->vbits.bits, num_bytes);
/* A type large enough to hold any IRType'd value. At this point
we do not expect to test with specific floating point values.
- So we don't need to represent them. */
+ So we don't need to represent them.
+
+ NOTE: Values of type Ity_I1 are stored in the u32 variant. This is
+ inconsistent with the way such values are stored elsewhere in VEX,
+ namely, in an 8-bit container. Why is that?
+ The reason is that libvex_ir.h does not provide an Iop_8to1 operator.
+ However, that would be needed in ir_inject.c when loading a 1-bit value
+ from memory (see function load_aux there). Instead of today's
+ return unop(Iop_32to1, IRExpr_Load(endian, Ity_I32, addr));
+ we'd like to write
+ return unop(Iop_8to1, IRExpr_Load(endian, Ity_I8, addr));
+ But cannot do. Grrrrr...
+ */
typedef union {
uint8_t u8;
uint16_t u16;