florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 1 | /* -*- mode: C; c-basic-offset: 3; -*- */ |
| 2 | |
florian | 5aa9d1e | 2015-09-22 07:21:50 +0000 | [diff] [blame] | 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 | |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 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 | |
carll | 686b17f | 2012-11-16 18:58:08 +0000 | [diff] [blame] | 80 | UNDEF_ORD, // Iop_CmpORD compare |
| 81 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 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 | |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 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; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 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 | |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 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; |
sewardj | 1f4b1eb | 2015-04-06 14:52:28 +0000 | [diff] [blame] | 182 | unsigned arm64 : 1; |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 183 | unsigned x86 : 1; |
| 184 | unsigned mips32 : 1; |
dejanj | 2b308d1 | 2013-08-28 10:03:45 +0000 | [diff] [blame] | 185 | unsigned mips64 : 1; |
sewardj | 112711a | 2015-04-10 12:30:09 +0000 | [diff] [blame] | 186 | unsigned tilegx : 1; |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 187 | } irop_t; |
| 188 | |
| 189 | |
| 190 | /* The maximum number of input operands */ |
| 191 | #define MAX_OPERANDS 4 |
| 192 | |
| 193 | /* An operand of an IROp (also used for the result) */ |
| 194 | typedef struct { |
| 195 | IRType type; |
| 196 | vbits_t vbits; |
| 197 | value_t value; |
| 198 | } opnd_t; |
| 199 | |
| 200 | |
| 201 | /* Carries the data needed to execute and evaluate a test. I.e. |
| 202 | inputs and results (V-bits and actual value). */ |
| 203 | typedef struct { |
| 204 | opnd_t result; |
| 205 | opnd_t opnds[MAX_OPERANDS]; |
| 206 | unsigned rounding_mode; |
| 207 | } test_data_t; |
| 208 | |
| 209 | |
| 210 | /* Function prototypes */ |
florian | f74f542 | 2012-09-13 19:41:12 +0000 | [diff] [blame] | 211 | irop_t *get_irop(IROp); |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 212 | int is_floating_point_op_with_rounding_mode(IROp); |
| 213 | int get_num_operands(IROp); |
| 214 | |
| 215 | void print_opnd(FILE *, const opnd_t *); |
| 216 | |
carll | 24c9e7f | 2012-11-16 19:41:21 +0000 | [diff] [blame] | 217 | int test_unary_op(const irop_t *, test_data_t *); |
| 218 | int test_binary_op(const irop_t *, test_data_t *); |
| 219 | int test_ternary_op(const irop_t *, test_data_t *); |
| 220 | int test_qernary_op(const irop_t *, test_data_t *); |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 221 | |
| 222 | void valgrind_vex_init_for_iri(IRICB *); |
| 223 | void valgrind_execute_test(const irop_t *, test_data_t *); |
| 224 | |
| 225 | IRICB new_iricb(const irop_t *, test_data_t *); |
| 226 | |
| 227 | void panic(const char *) __attribute__((noreturn)); |
| 228 | void complain(const irop_t *, const test_data_t *, vbits_t expected); |
| 229 | |
| 230 | /* Imported from VEX */ |
| 231 | unsigned sizeof_irtype(IRType); |
| 232 | void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2, |
| 233 | IRType *t_arg3, IRType *t_arg4); |
| 234 | |
florian | 9069406 | 2015-05-16 16:17:52 +0000 | [diff] [blame] | 235 | static __inline__ unsigned bitsof_irtype(IRType type) |
florian | bb913cd | 2012-08-28 16:50:39 +0000 | [diff] [blame] | 236 | { |
| 237 | return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8; |
| 238 | } |
| 239 | |
| 240 | |
| 241 | /* Exported variables */ |
| 242 | extern int verbose; |
| 243 | |
| 244 | #endif // VTEST_H |