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-2015  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 IROps I don't know anything about
83    UNDEF_UNKNOWN
84 } undef_t;
85 
86 
87 // Everything we want to know about an IROp
88 typedef struct {
89    IROp op;
90    const char *name;
91    undef_t     undef_kind;
92    int         shift_amount_is_immediate;
93    // Indicate whether IROp can be tested on a particular architecture
94    unsigned    s390x  : 1;
95    unsigned    amd64  : 1;
96    unsigned    ppc32  : 1;
97    unsigned    ppc64  : 1;
98    unsigned    arm    : 1;
99    unsigned    arm64  : 1;
100    unsigned    x86    : 1;
101    unsigned    mips32 : 1;
102    unsigned    mips64 : 1;
103    unsigned    tilegx : 1;
104 } irop_t;
105 
106 
107 /* The maximum number of input operands */
108 #define MAX_OPERANDS 4
109 
110 /* An operand of an IROp (also used for the result) */
111 typedef struct {
112    IRType  type;
113    vbits_t vbits;
114    value_t value;
115 } opnd_t;
116 
117 
118 /* Carries the data needed to execute and evaluate a test. I.e.
119    inputs and results (V-bits and actual value). */
120 typedef struct {
121    opnd_t result;
122    opnd_t opnds[MAX_OPERANDS];
123    unsigned rounding_mode;
124 } test_data_t;
125 
126 
127 /* Function prototypes */
128 irop_t *get_irop(IROp);
129 int  is_floating_point_op_with_rounding_mode(IROp);
130 int  get_num_operands(IROp);
131 
132 void print_opnd(FILE *, const opnd_t *);
133 
134 int test_unary_op(const irop_t *, test_data_t *);
135 int test_binary_op(const irop_t *, test_data_t *);
136 int test_ternary_op(const irop_t *, test_data_t *);
137 int test_qernary_op(const irop_t *, test_data_t *);
138 
139 void valgrind_vex_init_for_iri(IRICB *);
140 void valgrind_execute_test(const irop_t *, test_data_t *);
141 
142 IRICB new_iricb(const irop_t *, test_data_t *);
143 
144 void panic(const char *) __attribute__((noreturn));
145 void complain(const irop_t *, const test_data_t *, vbits_t expected);
146 
147 /* Imported from VEX */
148 unsigned sizeof_irtype(IRType);
149 void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2,
150                    IRType *t_arg3, IRType *t_arg4);
151 
bitsof_irtype(IRType type)152 static __inline__ unsigned bitsof_irtype(IRType type)
153 {
154    return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8;
155 }
156 
157 
158 /* Exported variables */
159 extern int verbose;
160 
161 #endif // VTEST_H
162