Add missing zstd.h to coregrind Makefile.am noinst_HEADERS
[valgrind.git] / memcheck / tests / vbit-test / valgrind.c
blobc24a06d649c754bb8d2e79ae51dee9549d44e723
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*
4 This file is part of MemCheck, a heavyweight Valgrind tool for
5 detecting memory errors.
7 Copyright (C) 2012-2017 Florian Krohm
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 The GNU General Public License is contained in the file COPYING.
25 #include <assert.h>
26 #include "memcheck.h" // VALGRIND_SET_VBITS
27 #include "vtest.h"
30 /* Return a completely initialised control block */
31 IRICB
32 new_iricb(const irop_t *op, test_data_t *data)
34 IRICB cb;
36 cb.op = op->op;
37 cb.result = (HWord)&data->result.value;
38 cb.opnd1 = (HWord)&data->opnds[0].value;
39 cb.opnd2 = (HWord)&data->opnds[1].value;
40 cb.opnd3 = (HWord)&data->opnds[2].value;
41 cb.opnd4 = (HWord)&data->opnds[3].value;
42 cb.t_result = data->result.type;
43 cb.t_opnd1 = data->opnds[0].type;
44 cb.t_opnd2 = data->opnds[1].type;
45 cb.t_opnd3 = data->opnds[2].type;
46 cb.t_opnd4 = data->opnds[3].type;
48 cb.rounding_mode = data->rounding_mode;
50 cb.num_operands = get_num_operands(op->op);
52 cb.immediate_index = op->immediate_index;
53 cb.immediate_type = op->immediate_type;
55 return cb;
59 /* Ity_I1 values cannot be stored or loaded. So vex_inject_ir will load/store
60 such a value from/to a 4-byte container. It uses 32to1 and 1Uto32,
61 respectively. */
62 static void
63 valgrind_set_vbits(opnd_t *opnd)
65 unsigned rc, num_bytes;
67 /* 1-bit wide values cannot be read. So we read a 4 bytes here */
68 num_bytes = opnd->type == Ity_I1 ? 4 : sizeof_irtype(opnd->type);
69 rc = VALGRIND_SET_VBITS(&opnd->value, &opnd->vbits.bits, num_bytes);
70 assert(rc == 1);
72 // Make sure the v-bits were set correctly
73 vbits_t actual = { .num_bits = opnd->vbits.num_bits };
74 rc = VALGRIND_GET_VBITS(&opnd->value, &actual.bits, num_bytes);
75 assert(rc == 1);
77 assert(equal_vbits(opnd->vbits, actual));
81 static void
82 valgrind_get_vbits(opnd_t *opnd)
84 unsigned rc, num_bytes;
86 /* 1-bit wide values cannot be stored. So we store them by writing a
87 single byte */
88 num_bytes = opnd->type == Ity_I1 ? 4 : sizeof_irtype(opnd->type);
89 opnd->vbits.num_bits = bitsof_irtype(opnd->type);
90 rc = VALGRIND_GET_VBITS(&opnd->value, &opnd->vbits.bits, num_bytes);
91 assert(rc == 1);
95 /* Insert a client request that will initialize VEX for IR injection */
96 void
97 valgrind_vex_init_for_iri(IRICB *cb)
99 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__VEX_INIT_FOR_IRI, cb, 0,0,0,0);
103 /* Insert a special opcode that will cause VEX to inject an IR stmt based
104 on the information passed in the IRICB (in valgrind_vex_init_for_iri). */
105 static void
106 valgrind_vex_inject_ir(void)
108 VALGRIND_VEX_INJECT_IR();
112 /* Execute the test under valgrind. Well, yes, we're not really executing
113 it here, just preparing for it... */
114 void
115 valgrind_execute_test(const irop_t *op, test_data_t *data)
117 unsigned i, num_operands;
119 if (verbose > 2) printf("---------- Running a test\n");
120 num_operands = get_num_operands(op->op);
122 for (i = 0; i < num_operands; ++i) {
123 valgrind_set_vbits(&data->opnds[i]);
124 if (verbose > 2) {
125 printf("opnd #%u: ", i);
126 print_opnd(stdout, &data->opnds[i]);
127 printf("\n");
130 if (verbose > 2)
131 if (data->rounding_mode != NO_ROUNDING_MODE)
132 printf("rounding mode %u\n", data->rounding_mode);
134 valgrind_vex_inject_ir();
135 valgrind_get_vbits(&data->result);
136 if (verbose > 2) {
137 printf("result: ");
138 print_opnd(stdout, &data->result);
139 printf("\n");
142 // Now that we have the vbits recorded, clear all the vbits.
143 for (i = 0; i < num_operands; ++i) {
144 VALGRIND_MAKE_MEM_DEFINED(&data->opnds[i].value, sizeof(data->opnds[i].value));