• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mode: C; c-basic-offset: 3; -*- */
2 
3 /*
4    This file is part of MemCheck, a heavyweight Valgrind tool for
5    detecting memory errors.
6 
7    Copyright (C) 2012-2017  Florian Krohm
8 
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.
13 
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.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22    02111-1307, USA.
23 
24    The GNU General Public License is contained in the file COPYING.
25 */
26 
27 #ifndef VTEST_H
28 #define VTEST_H
29 
30 /* Main header file for the V-bit tester */
31 
32 #include <stdint.h>   // uint64_t
33 #include "libvex.h"   // IROp
34 #include "vbits.h"    // vbits_t
35 
36 
37 /* How undefinedness propagates from input to output */
38 
39 typedef enum {
40    // For any undefined input bit, all output bits are defined.
41    UNDEF_NONE,
42 
43    // For any undefined input bit, all output bits are undefined.
44    UNDEF_ALL,
45 
46    // For each undefined input bit, the corresponding output bit
47    // in the same position is undefined. No other bit is undefined.
48    UNDEF_SAME,
49 
50    // For each undefined input bit, the corresponding output bit
51    // in the same position is undefined. No other bit is undefined.
52    // If the corresponding output bit does not exist, the input bit
53    // does not cause any output bits to be undefined.
54    UNDEF_TRUNC,
55 
56    // For each undefined input bit, the corresponding output bit
57    // in the same position is undefined. No other bit is undefined.
58    // Output bits that do no not have a corresponding input bit are
59    // defined.
60    UNDEF_ZEXT,
61 
62    // For each undefined input bit, the corresponding output bit
63    // in the same position is undefined. If the MSB of the input value
64    // is undefined, so are all output bits with higher significance
65    // than the MSB input bit.
66    UNDEF_SEXT,
67 
68    // For each undefined input bit, the corresponding output bit
69    // and all output bits with higher significance are undefined.
70    UNDEF_LEFT,
71 
72    UNDEF_CONCAT,  // nHLto2n ops e.g. Iop_32HLto64
73    UNDEF_UPPER,   // 2nHIton ops e.g. Iop_64HIto32
74    UNDEF_SHL,     // shift-left
75    UNDEF_SHR,     // logical shift-right
76    UNDEF_SAR,     // arithmetic shift-right
77    UNDEF_OR,      // bitwise OR operation
78    UNDEF_AND,     // bitwise AND operation
79 
80    UNDEF_ORD,     // Iop_CmpORD compare
81 
82    /* For each of the following UNDEF_ALL_BxE, E is the number of
83     * elements and B is the number of bits in the element.
84     *
85     * If any bits in one of the E elements is not defined, then the
86     * return value has all bits in the corresponding element set to 1.
87     */
88    UNDEF_ALL_64x2,         // 128-bit vector, two 64-bit elements
89    UNDEF_ALL_32x4,         // 128-bit vector, four 32-bit elements
90    UNDEF_ALL_16x8,         // 128-bit vector, eight 16-bit elements
91    UNDEF_ALL_8x16,         // 128-bit vector, sixteen 8-bit elements
92 
93    /* For each of the following UNDEF_ALL_BxE_EVEN, E is the number of
94     * elements and B is the number of bits in the element. Elements are
95     * numbered from right to left starting with element number 0.
96     *
97     * If any bits in one of the even numbered elements is not defined, then
98     * the return value has all bits in the corresponding element set to 1.
99     * The bits in the odd numbered elements are not checked
100     */
101    UNDEF_ALL_32x4_EVEN,    // 128-bit vector, four 32-bit elements
102    UNDEF_ALL_16x8_EVEN,    // 128-bit vector, eight 16-bit elements
103    UNDEF_ALL_8x16_EVEN,    // 128-bit vector, sixteen 8-bit elements
104 
105    /* For each of the following UNDEF_BxE_TRANSPOSE, E is the number of
106     * elements and B is the number of bits in the element.
107     *
108     * Concatenate bit i from each byte j.  Place concatenated 8 bit value
109     * into byte i of the result.  Do for each bit i from 0 to 7 and
110     * byte j from 0 to 7 of each 64-bit element.
111     */
112    UNDEF_64x2_TRANSPOSE,
113 
114    /* For each of the following UNDEF_BxE_ROTATE, E is the number of
115     * elements and B is the number of bits in the element.
116     *
117     * The result is the undefined bits in each element rotated by the
118     * specified amount.  Bits rotated out of the element are discarded.
119     * No additional bits are set to undefined.
120     */
121    UNDEF_64x2_ROTATE, /* 128-bit vector, two 64-bit elements, rotate
122                        * elements left.
123                        */
124    UNDEF_32x4_ROTATE, /* 128-bit vector, four 32-bit elements, rotate
125                        * elements left.
126                        */
127    UNDEF_16x8_ROTATE, /* 128-bit vector, eight 16-bit elements, rotate
128                        * elements left.
129                        */
130    UNDEF_8x16_ROTATE, /* 128-bit vector, sixteen 8-bit elements, rotate
131                        * elements left.
132                        */
133 
134    /* If the input had some vbits set, the result will have one or more
135     * vbits set. Minimal test when the vbit propagation can not be easily
136     * calculated.
137     */
138    UNDEF_SOME,
139 
140    /* For UNDEF_NARROW256_AtoB, narrow the elements of size A-bits in
141     * the 256-bit source (stored in two 128-bit values) to a 128-bit
142     * result with elements of size B-bits.
143     *
144     * If the source element will fit into the corresponding destination
145     * element, then only the undefined bits in the source element are
146     * undefined in the corresponding bit position of the destination element.
147     *
148     * If the source element will not fit into the destination element, then
149     * only the lower B undefined bits of the source element will be
150     * undefined in the corresponding result element unless the saturate
151     * flag is true.  If the saturate flag is true and the element in the
152     * source will not fit into the corresponding destination element, then
153     * all of the bits in the corresponding destination element are set to one.
154     */
155    UNDEF_NARROW256_AtoB,
156 
157    // For IROps I don't know anything about
158    UNDEF_UNKNOWN
159 } undef_t;
160 
161 
162 // Everything we want to know about an IROp
163 typedef struct {
164    IROp op;
165    const char *name;
166    undef_t     undef_kind;
167    /* The following two members describe if this operand has immediate
168     *  operands. There are a few restrictions:
169     *    (1) An operator can have at most one immediate operand.
170     *    (2) If there is an immediate operand, it is the right-most operand.
171     *  An immediate_index of 0 means there is no immediate operand.
172     */
173    unsigned    immediate_index;
174    unsigned    immediate_type;
175 
176    // Indicate whether IROp can be tested on a particular architecture
177    unsigned    s390x  : 1;
178    unsigned    amd64  : 1;
179    unsigned    ppc32  : 1;
180    unsigned    ppc64  : 1;
181    unsigned    arm    : 1;
182    unsigned    arm64  : 1;
183    unsigned    x86    : 1;
184    unsigned    mips32 : 1;
185    unsigned    mips64 : 1;
186 } irop_t;
187 
188 
189 /* The maximum number of input operands */
190 #define MAX_OPERANDS 4
191 
192 /* An operand of an IROp (also used for the result) */
193 typedef struct {
194    IRType  type;
195    vbits_t vbits;
196    value_t value;
197 } opnd_t;
198 
199 
200 /* Carries the data needed to execute and evaluate a test. I.e.
201    inputs and results (V-bits and actual value). */
202 typedef struct {
203    opnd_t result;
204    opnd_t opnds[MAX_OPERANDS];
205    unsigned rounding_mode;
206 } test_data_t;
207 
208 
209 /* Function prototypes */
210 irop_t *get_irop(IROp);
211 int  is_floating_point_op_with_rounding_mode(IROp);
212 int  get_num_operands(IROp);
213 
214 void print_opnd(FILE *, const opnd_t *);
215 
216 int test_unary_op(const irop_t *, test_data_t *);
217 int test_binary_op(const irop_t *, test_data_t *);
218 int test_ternary_op(const irop_t *, test_data_t *);
219 int test_qernary_op(const irop_t *, test_data_t *);
220 
221 void valgrind_vex_init_for_iri(IRICB *);
222 void valgrind_execute_test(const irop_t *, test_data_t *);
223 
224 IRICB new_iricb(const irop_t *, test_data_t *);
225 
226 void panic(const char *) __attribute__((noreturn));
227 void complain(const irop_t *, const test_data_t *, vbits_t expected);
228 
229 /* Imported from VEX */
230 unsigned sizeof_irtype(IRType);
231 void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2,
232                    IRType *t_arg3, IRType *t_arg4);
233 
bitsof_irtype(IRType type)234 static __inline__ unsigned bitsof_irtype(IRType type)
235 {
236    return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8;
237 }
238 
239 
240 /* Exported variables */
241 extern int verbose;
242 
243 #endif // VTEST_H
244