File: vtest.h

package info (click to toggle)
valgrind 1%3A3.24.0-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 176,332 kB
  • sloc: ansic: 795,029; exp: 26,134; xml: 23,472; asm: 14,393; cpp: 9,397; makefile: 7,464; sh: 6,122; perl: 5,446; python: 1,498; javascript: 981; awk: 166; csh: 1
file content (257 lines) | stat: -rw-r--r-- 8,893 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/* -*- mode: C; c-basic-offset: 3; -*- */

/*
   This file is part of MemCheck, a heavyweight Valgrind tool for
   detecting memory errors.

   Copyright (C) 2012-2017  Florian Krohm

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.

   The GNU General Public License is contained in the file COPYING.
*/

#ifndef VTEST_H
#define VTEST_H

/* Main header file for the V-bit tester */

#include <stdint.h>   // uint64_t
#include "libvex.h"   // IROp
#include "vbits.h"    // vbits_t


/* How undefinedness propagates from input to output */

typedef enum {
   // For any undefined input bit, all output bits are defined.
   UNDEF_NONE,

   // For any undefined input bit, all output bits are undefined.
   UNDEF_ALL,

   // For each undefined input bit, the corresponding output bit
   // in the same position is undefined. No other bit is undefined.
   UNDEF_SAME,

   // For each undefined input bit, the corresponding output bit
   // in the same position is undefined. No other bit is undefined.
   // If the corresponding output bit does not exist, the input bit
   // does not cause any output bits to be undefined.
   UNDEF_TRUNC,

   // For each undefined input bit, the corresponding output bit
   // in the same position is undefined. No other bit is undefined.
   // Output bits that do no not have a corresponding input bit are
   // defined.
   UNDEF_ZEXT,

   // For each undefined input bit, the corresponding output bit
   // in the same position is undefined. If the MSB of the input value
   // is undefined, so are all output bits with higher significance
   // than the MSB input bit.
   UNDEF_SEXT,

   // For each undefined input bit, the corresponding output bit
   // and all output bits with higher significance are undefined.
   UNDEF_LEFT,    

   UNDEF_CONCAT,  // nHLto2n ops e.g. Iop_32HLto64
   UNDEF_UPPER,   // 2nHIton ops e.g. Iop_64HIto32
   UNDEF_SHL,     // shift-left
   UNDEF_SHR,     // logical shift-right
   UNDEF_SAR,     // arithmetic shift-right
   UNDEF_OR,      // bitwise OR operation
   UNDEF_AND,     // bitwise AND operation

   UNDEF_ORD,     // Iop_CmpORD compare 

   // Expensive (exact) integer EQ and NE
   UNDEF_CMP_EQ_NE,

   // Expensive (exact) integer addition and subtraction
   UNDEF_INT_ADD,
   UNDEF_INT_SUB,

   /* For each of the following UNDEF_ALL_BxE, E is the number of
    * elements and B is the number of bits in the element.
    *
    * If any bits in one of the E elements is not defined, then the
    * return value has all bits in the corresponding element set to 1.
    */
   UNDEF_ALL_64x2,         // 128-bit vector, two 64-bit elements
   UNDEF_ALL_32x4,         // 128-bit vector, four 32-bit elements
   UNDEF_ALL_16x8,         // 128-bit vector, eight 16-bit elements
   UNDEF_ALL_8x16,         // 128-bit vector, sixteen 8-bit elements

   /* For each of the following UNDEF_ALL_BxE_EVEN, E is the number of
    * elements and B is the number of bits in the element. Elements are
    * numbered from right to left starting with element number 0.
    *
    * If any bits in one of the even numbered elements is not defined, then
    * the return value has all bits in the corresponding element set to 1.
    * The bits in the odd numbered elements are not checked
    */
   UNDEF_ALL_32x4_EVEN,    // 128-bit vector, four 32-bit elements
   UNDEF_ALL_16x8_EVEN,    // 128-bit vector, eight 16-bit elements
   UNDEF_ALL_8x16_EVEN,    // 128-bit vector, sixteen 8-bit elements

   /* For each of the following UNDEF_BxE_TRANSPOSE, E is the number of
    * elements and B is the number of bits in the element.
    *
    * Concatenate bit i from each byte j.  Place concatenated 8 bit value
    * into byte i of the result.  Do for each bit i from 0 to 7 and
    * byte j from 0 to 7 of each 64-bit element.
    */
   UNDEF_64x2_TRANSPOSE,

   /* For each of the following UNDEF_BxE_ROTATE, E is the number of
    * elements and B is the number of bits in the element.
    *
    * The result is the undefined bits in each element rotated by the
    * specified amount.  Bits rotated out of the element are discarded.
    * No additional bits are set to undefined.
    */
   UNDEF_64x2_ROTATE, /* 128-bit vector, two 64-bit elements, rotate
                       * elements left.
                       */
   UNDEF_32x4_ROTATE, /* 128-bit vector, four 32-bit elements, rotate
                       * elements left.
                       */
   UNDEF_16x8_ROTATE, /* 128-bit vector, eight 16-bit elements, rotate
                       * elements left.
                       */
   UNDEF_8x16_ROTATE, /* 128-bit vector, sixteen 8-bit elements, rotate
                       * elements left.
                       */

   /* If the input had some vbits set, the result will have one or more
    * vbits set. Minimal test when the vbit propagation can not be easily
    * calculated.
    */
   UNDEF_SOME,

   /* For UNDEF_NARROW256_AtoB, narrow the elements of size A-bits in
    * the 256-bit source (stored in two 128-bit values) to a 128-bit
    * result with elements of size B-bits.
    *
    * If the source element will fit into the corresponding destination
    * element, then only the undefined bits in the source element are
    * undefined in the corresponding bit position of the destination element.
    *
    * If the source element will not fit into the destination element, then
    * only the lower B undefined bits of the source element will be
    * undefined in the corresponding result element unless the saturate
    * flag is true.  If the saturate flag is true and the element in the
    * source will not fit into the corresponding destination element, then
    * all of the bits in the corresponding destination element are set to one.
    */
   UNDEF_NARROW256_AtoB,

   UNDEF_GT_S_8x16,
   UNDEF_GT_S_16x8,
   UNDEF_GT_S_32x4,
   UNDEF_GT_S_64x2,
   UNDEF_GT_U_8x16,
   UNDEF_GT_U_16x8,
   UNDEF_GT_U_32x4,
   UNDEF_GT_U_64x2,

   // For IROps I don't know anything about
   UNDEF_UNKNOWN
} undef_t;


// Everything we want to know about an IROp
typedef struct {
   IROp op;
   const char *name;
   undef_t     undef_kind;
   /* The following two members describe if this operand has immediate
    *  operands. There are a few restrictions:
    *    (1) An operator can have at most one immediate operand.
    *    (2) If there is an immediate operand, it is the right-most operand.
    *  An immediate_index of 0 means there is no immediate operand.
    */
   unsigned    immediate_index;
   unsigned    immediate_type;

   // Indicate whether IROp can be tested on a particular architecture
   unsigned    s390x  : 1;
   unsigned    amd64  : 1;
   unsigned    ppc32  : 1;
   unsigned    ppc64  : 1;
   unsigned    arm    : 1;
   unsigned    arm64  : 1;
   unsigned    x86    : 1;
   unsigned    mips32 : 1;
   unsigned    mips64 : 1;
} irop_t;


/* The maximum number of input operands */
#define MAX_OPERANDS 4

/* An operand of an IROp (also used for the result) */
typedef struct {
   IRType  type;
   vbits_t vbits;
   value_t value;
} opnd_t;


/* Carries the data needed to execute and evaluate a test. I.e.
   inputs and results (V-bits and actual value). */
typedef struct {
   opnd_t result;
   opnd_t opnds[MAX_OPERANDS];
   unsigned rounding_mode;
} test_data_t;


/* Function prototypes */
irop_t *get_irop(IROp);
int  is_floating_point_op_with_rounding_mode(IROp);
int  get_num_operands(IROp);

void print_opnd(FILE *, const opnd_t *);

int test_unary_op(const irop_t *, test_data_t *);
int test_binary_op(const irop_t *, test_data_t *);
int test_ternary_op(const irop_t *, test_data_t *);
int test_qernary_op(const irop_t *, test_data_t *);

void valgrind_vex_init_for_iri(IRICB *);
void valgrind_execute_test(const irop_t *, test_data_t *);

IRICB new_iricb(const irop_t *, test_data_t *);

void panic(const char *) __attribute__((noreturn));
void complain(const irop_t *, const test_data_t *, vbits_t expected);

/* Imported from VEX */
unsigned sizeof_irtype(IRType);
void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2, 
                   IRType *t_arg3, IRType *t_arg4);

static __inline__ unsigned bitsof_irtype(IRType type)
{
   return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8;
}


/* Exported variables */
extern int verbose;

#endif // VTEST_H