1 /* -*- mode: C; c-basic-offset: 3; -*- */
2 
3 #ifndef VTEST_H
4 #define VTEST_H
5 
6 /* Main header file for the V-bit tester */
7 
8 #include <stdint.h>   // uint64_t
9 #include "libvex.h"   // IROp
10 #include "vbits.h"    // vbits_t
11 
12 
13 /* How undefinedness propagates from input to output */
14 
15 typedef enum {
16    // For any undefined input bit, all output bits are defined.
17    UNDEF_NONE,
18 
19    // For any undefined input bit, all output bits are undefined.
20    UNDEF_ALL,
21 
22    // For each undefined input bit, the corresponding output bit
23    // in the same position is undefined. No other bit is undefined.
24    UNDEF_SAME,
25 
26    // For each undefined input bit, the corresponding output bit
27    // in the same position is undefined. No other bit is undefined.
28    // If the corresponding output bit does not exist, the input bit
29    // does not cause any output bits to be undefined.
30    UNDEF_TRUNC,
31 
32    // For each undefined input bit, the corresponding output bit
33    // in the same position is undefined. No other bit is undefined.
34    // Output bits that do no not have a corresponding input bit are
35    // defined.
36    UNDEF_ZEXT,
37 
38    // For each undefined input bit, the corresponding output bit
39    // in the same position is undefined. If the MSB of the input value
40    // is undefined, so are all output bits with higher significance
41    // than the MSB input bit.
42    UNDEF_SEXT,
43 
44    // For each undefined input bit, the corresponding output bit
45    // and all output bits with higher significance are undefined.
46    UNDEF_LEFT,
47 
48    UNDEF_CONCAT,  // nHLto2n ops e.g. Iop_32HLto64
49    UNDEF_UPPER,   // 2nHIton ops e.g. Iop_64HIto32
50    UNDEF_SHL,     // shift-left
51    UNDEF_SHR,     // logical shift-right
52    UNDEF_SAR,     // arithmetic shift-right
53    UNDEF_OR,      // bitwise OR operation
54    UNDEF_AND,     // bitwise AND operation
55 
56    UNDEF_ORD,     // Iop_CmpORD compare
57 
58    // For IROps I don't know anything about
59    UNDEF_UNKNOWN
60 } undef_t;
61 
62 
63 // Everything we want to know about an IROp
64 typedef struct {
65    IROp op;
66    const char *name;
67    undef_t     undef_kind;
68    int         shift_amount_is_immediate;
69    // Indicate whether IROp can be tested on a particular architecture
70    unsigned    s390x  : 1;
71    unsigned    amd64  : 1;
72    unsigned    ppc32  : 1;
73    unsigned    ppc64  : 1;
74    unsigned    arm    : 1;
75    unsigned    arm64  : 1;
76    unsigned    x86    : 1;
77    unsigned    mips32 : 1;
78    unsigned    mips64 : 1;
79    unsigned    tilegx : 1;
80 } irop_t;
81 
82 
83 /* The maximum number of input operands */
84 #define MAX_OPERANDS 4
85 
86 /* An operand of an IROp (also used for the result) */
87 typedef struct {
88    IRType  type;
89    vbits_t vbits;
90    value_t value;
91 } opnd_t;
92 
93 
94 /* Carries the data needed to execute and evaluate a test. I.e.
95    inputs and results (V-bits and actual value). */
96 typedef struct {
97    opnd_t result;
98    opnd_t opnds[MAX_OPERANDS];
99    unsigned rounding_mode;
100 } test_data_t;
101 
102 
103 /* Function prototypes */
104 irop_t *get_irop(IROp);
105 int  is_floating_point_op_with_rounding_mode(IROp);
106 int  get_num_operands(IROp);
107 
108 void print_opnd(FILE *, const opnd_t *);
109 
110 int test_unary_op(const irop_t *, test_data_t *);
111 int test_binary_op(const irop_t *, test_data_t *);
112 int test_ternary_op(const irop_t *, test_data_t *);
113 int test_qernary_op(const irop_t *, test_data_t *);
114 
115 void valgrind_vex_init_for_iri(IRICB *);
116 void valgrind_execute_test(const irop_t *, test_data_t *);
117 
118 IRICB new_iricb(const irop_t *, test_data_t *);
119 
120 void panic(const char *) __attribute__((noreturn));
121 void complain(const irop_t *, const test_data_t *, vbits_t expected);
122 
123 /* Imported from VEX */
124 unsigned sizeof_irtype(IRType);
125 void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2,
126                    IRType *t_arg3, IRType *t_arg4);
127 
bitsof_irtype(IRType type)128 static __inline__ unsigned bitsof_irtype(IRType type)
129 {
130    return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8;
131 }
132 
133 
134 /* Exported variables */
135 extern int verbose;
136 
137 #endif // VTEST_H
138