Exemple #1
0
/* Check the result of a ternary operation. */
static void
check_result_for_ternary(const irop_t *op, const test_data_t *data)
{
   const opnd_t *result = &data->result;
   const opnd_t *opnd1  = &data->opnds[0];
   const opnd_t *opnd2  = &data->opnds[1];
   const opnd_t *opnd3  = &data->opnds[2];
   vbits_t expected_vbits;

   /* Only handle those undef-kinds that actually occur. */
   switch (op->undef_kind) {
   case UNDEF_ALL:
      expected_vbits = undefined_vbits(result->vbits.num_bits);
      break;

   case UNDEF_SAME:
      // SAME with respect to the 1-bits in all operands
      expected_vbits = or_vbits(or_vbits(opnd1->vbits, opnd2->vbits),
                                opnd3->vbits);
      break;

   default:
      panic(__func__);
   }

   if (! equal_vbits(result->vbits, expected_vbits))
      complain(op, data, expected_vbits);
}
/* Ity_I1 values cannot be stored or loaded. So vex_inject_ir will load/store
   such a value from/to a 4-byte container. It uses 32to1 and 1Uto32,
   respectively. */
static void
valgrind_set_vbits(opnd_t *opnd)
{
   unsigned rc, num_bytes;
   
   /* 1-bit wide values cannot be read. So we read a 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);

   // Make sure the v-bits were set correctly
   vbits_t actual = { .num_bits = opnd->vbits.num_bits };
   rc = VALGRIND_GET_VBITS(&opnd->value, &actual.bits, num_bytes);
   assert(rc == 1);

   assert(equal_vbits(opnd->vbits, actual));
}


static void
valgrind_get_vbits(opnd_t *opnd)
{
   unsigned rc, num_bytes;

   /* 1-bit wide values cannot be stored. So we store them by writing a
      single byte */
   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);
   assert(rc == 1);
}
Exemple #3
0
void
print_opnd(FILE *fp, const opnd_t *opnd)
{
   fprintf(fp, "vbits = ");
   print_vbits(fp, opnd->vbits);
   /* Write the value only if it is defined. Otherwise, there will be error
      messages about it being undefined */
   if (equal_vbits(opnd->vbits, defined_vbits(opnd->vbits.num_bits))) {
      fprintf(fp, "   value = ");
      print_value(fp, opnd->value, opnd->vbits.num_bits);
   }
}
Exemple #4
0
/* Check the result of a ternary operation. */
static void
check_result_for_ternary(const irop_t *op, const test_data_t *data)
{
   const opnd_t *result = &data->result;
   const opnd_t *opnd1  = &data->opnds[0];
   const opnd_t *opnd2  = &data->opnds[1];
   const opnd_t *opnd3  = &data->opnds[2];
   vbits_t expected_vbits;

   /* Only handle those undef-kinds that actually occur. */
   switch (op->undef_kind) {
   case UNDEF_ALL:
      expected_vbits = undefined_vbits(result->vbits.num_bits);
      break;

   case UNDEF_SAME:
      // SAME with respect to the 1-bits in all operands
      expected_vbits = or_vbits(or_vbits(opnd1->vbits, opnd2->vbits),
                                opnd3->vbits);
      break;

   case UNDEF_SOME:
      expected_vbits.num_bits = result->vbits.num_bits;

      if ((result->vbits.bits.u128[0] != 0) ||
          (result->vbits.bits.u128[1] != 0)) {
         expected_vbits.bits.u128[0] = result->vbits.bits.u128[0];
         expected_vbits.bits.u128[1] = result->vbits.bits.u128[1];

      } else {
         /* The input had at least one vbit set but the result doesn't have any
          * bit set.  Set them all so we will trigger the error on the call
          * to complain().
          */
         expected_vbits.bits.u128[0] = ~0x0ULL;
         expected_vbits.bits.u128[1] = ~0x0ULL;
      }

      break;

   default:
      panic(__func__);
   }

   if (! equal_vbits(result->vbits, expected_vbits))
      complain(op, data, expected_vbits);
}
Exemple #5
0
/* Check the result of a unary operation. */
static void
check_result_for_unary(const irop_t *op, const test_data_t *data)
{
    const opnd_t *result = &data->result;
    const opnd_t *opnd   = &data->opnds[0];
    unsigned num_bits = result->vbits.num_bits;
    vbits_t expected_vbits;

    /* Only handle those undef-kinds that actually occur. */
    switch (op->undef_kind) {
    case UNDEF_ALL:
        expected_vbits = undefined_vbits(num_bits);
        break;

    case UNDEF_SAME:
        expected_vbits = opnd->vbits;
        break;

    case UNDEF_TRUNC:
        expected_vbits = truncate_vbits(opnd->vbits, num_bits);
        break;

    case UNDEF_LEFT:
        expected_vbits = left_vbits(opnd->vbits, num_bits);
        break;

    case UNDEF_UPPER:
        assert(num_bits * 2 == opnd->vbits.num_bits);
        expected_vbits = upper_vbits(opnd->vbits);
        break;

    case UNDEF_SEXT:
        expected_vbits = sextend_vbits(opnd->vbits, num_bits);
        break;

    case UNDEF_ZEXT:
        expected_vbits = zextend_vbits(opnd->vbits, num_bits);
        break;

    default:
        panic(__func__);
    }

    if (! equal_vbits(result->vbits, expected_vbits))
        complain(op, data, expected_vbits);
}