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 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