1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* -*- mode: C; c-basic-offset: 3; -*- */ 2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <assert.h> 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "memcheck.h" // VALGRIND_SET_VBITS 5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "vtest.h" 6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return a completely initialised control block */ 9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovIRICB 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovnew_iricb(const irop_t *op, test_data_t *data) 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov IRICB cb; 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.op = op->op; 15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.result = (HWord)&data->result.value; 16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.opnd1 = (HWord)&data->opnds[0].value; 17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.opnd2 = (HWord)&data->opnds[1].value; 18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.opnd3 = (HWord)&data->opnds[2].value; 19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.opnd4 = (HWord)&data->opnds[3].value; 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.t_result = data->result.type; 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.t_opnd1 = data->opnds[0].type; 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.t_opnd2 = data->opnds[1].type; 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.t_opnd3 = data->opnds[2].type; 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.t_opnd4 = data->opnds[3].type; 25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.rounding_mode = data->rounding_mode; 27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.num_operands = get_num_operands(op->op); 29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cb.shift_amount_is_immediate = op->shift_amount_is_immediate; 31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cb; 33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Ity_I1 values cannot be stored or loaded. So vex_inject_ir will load/store 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov such a value from/to a 4-byte container. It uses 32to1 and 1Uto32, 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov respectively. */ 39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvalgrind_set_vbits(opnd_t *opnd) 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unsigned rc, num_bytes; 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 1-bit wide values cannot be read. So we read a 4 bytes here */ 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov num_bytes = opnd->type == Ity_I1 ? 4 : sizeof_irtype(opnd->type); 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rc = VALGRIND_SET_VBITS(&opnd->value, &opnd->vbits.bits, num_bytes); 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(rc == 1); 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Make sure the v-bits were set correctly 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vbits_t actual = { .num_bits = opnd->vbits.num_bits }; 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rc = VALGRIND_GET_VBITS(&opnd->value, &actual.bits, num_bytes); 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(rc == 1); 53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(equal_vbits(opnd->vbits, actual)); 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvalgrind_get_vbits(opnd_t *opnd) 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unsigned rc, num_bytes; 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 1-bit wide values cannot be stored. So we store them by writing a 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov single byte */ 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov num_bytes = opnd->type == Ity_I1 ? 4 : sizeof_irtype(opnd->type); 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov opnd->vbits.num_bits = bitsof_irtype(opnd->type); 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rc = VALGRIND_GET_VBITS(&opnd->value, &opnd->vbits.bits, num_bytes); 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(rc == 1); 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Insert a client request that will initialize VEX for IR injection */ 73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid 74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvalgrind_vex_init_for_iri(IRICB *cb) 75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__VEX_INIT_FOR_IRI, cb, 0,0,0,0); 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Insert a special opcode that will cause VEX to inject an IR stmt based 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov on the information passed in the IRICB (in valgrind_vex_init_for_iri). */ 82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void 83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvalgrind_vex_inject_ir(void) 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VALGRIND_VEX_INJECT_IR(); 86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Execute the test under valgrind. Well, yes, we're not really executing 90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov it here, just preparing for it... */ 91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid 92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvalgrind_execute_test(const irop_t *op, test_data_t *data) 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unsigned i, num_operands; 95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (verbose > 2) printf("---------- Running a test\n"); 97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov num_operands = get_num_operands(op->op); 98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i = 0; i < num_operands; ++i) { 100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valgrind_set_vbits(&data->opnds[i]); 101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (verbose > 2) { 102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("opnd #%u: ", i); 103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov print_opnd(stdout, &data->opnds[i]); 104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (verbose > 2) 108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (data->rounding_mode != NO_ROUNDING_MODE) 109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("rounding mode %u\n", data->rounding_mode); 110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valgrind_vex_inject_ir(); 112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov valgrind_get_vbits(&data->result); 113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (verbose > 2) { 114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("result: "); 115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov print_opnd(stdout, &data->result); 116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("\n"); 117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 119