Home | History | Annotate | Download | only in vbit-test
      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