1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* -*- mode: C; c-basic-offset: 3; -*- */
2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#ifndef VTEST_H
4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define VTEST_H
5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Main header file for the V-bit tester */
7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdint.h>   // uint64_t
9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "libvex.h"   // IROp
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "vbits.h"    // vbits_t
11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* How undefinedness propagates from input to output */
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef enum {
16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For any undefined input bit, all output bits are defined.
17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_NONE,
18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For any undefined input bit, all output bits are undefined.
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_ALL,
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For each undefined input bit, the corresponding output bit
23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // in the same position is undefined. No other bit is undefined.
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_SAME,
25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For each undefined input bit, the corresponding output bit
27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // in the same position is undefined. No other bit is undefined.
28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // If the corresponding output bit does not exist, the input bit
29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // does not cause any output bits to be undefined.
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_TRUNC,
31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For each undefined input bit, the corresponding output bit
33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // in the same position is undefined. No other bit is undefined.
34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Output bits that do no not have a corresponding input bit are
35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // defined.
36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_ZEXT,
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For each undefined input bit, the corresponding output bit
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // in the same position is undefined. If the MSB of the input value
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // is undefined, so are all output bits with higher significance
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // than the MSB input bit.
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_SEXT,
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For each undefined input bit, the corresponding output bit
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // and all output bits with higher significance are undefined.
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_LEFT,
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_CONCAT,  // nHLto2n ops e.g. Iop_32HLto64
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_UPPER,   // 2nHIton ops e.g. Iop_64HIto32
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_SHL,     // shift-left
51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_SHR,     // logical shift-right
52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_SAR,     // arithmetic shift-right
53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_OR,      // bitwise OR operation
54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_AND,     // bitwise AND operation
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_ORD,     // Iop_CmpORD compare
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // For IROps I don't know anything about
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UNDEF_UNKNOWN
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} undef_t;
61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// Everything we want to know about an IROp
64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef struct {
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   IROp op;
66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const char *name;
67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   undef_t     undef_kind;
68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   int         shift_amount_is_immediate;
69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // Indicate whether IROp can be tested on a particular architecture
70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    s390x  : 1;
71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    amd64  : 1;
72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    ppc32  : 1;
73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    ppc64  : 1;
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    arm    : 1;
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    x86    : 1;
76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    mips32 : 1;
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned    mips64 : 1;
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} irop_t;
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* The maximum number of input operands */
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define MAX_OPERANDS 4
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* An operand of an IROp (also used for the result) */
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef struct {
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   IRType  type;
87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t vbits;
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   value_t value;
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} opnd_t;
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Carries the data needed to execute and evaluate a test. I.e.
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   inputs and results (V-bits and actual value). */
94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef struct {
95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   opnd_t result;
96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   opnd_t opnds[MAX_OPERANDS];
97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   unsigned rounding_mode;
98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} test_data_t;
99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Function prototypes */
102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovirop_t *get_irop(IROp);
103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint  is_floating_point_op_with_rounding_mode(IROp);
104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint  get_num_operands(IROp);
105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid print_opnd(FILE *, const opnd_t *);
107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint test_unary_op(const irop_t *, test_data_t *);
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint test_binary_op(const irop_t *, test_data_t *);
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint test_ternary_op(const irop_t *, test_data_t *);
111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint test_qernary_op(const irop_t *, test_data_t *);
112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid valgrind_vex_init_for_iri(IRICB *);
114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid valgrind_execute_test(const irop_t *, test_data_t *);
115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovIRICB new_iricb(const irop_t *, test_data_t *);
117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid panic(const char *) __attribute__((noreturn));
119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid complain(const irop_t *, const test_data_t *, vbits_t expected);
120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Imported from VEX */
122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovunsigned sizeof_irtype(IRType);
123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2,
124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                   IRType *t_arg3, IRType *t_arg4);
125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic unsigned __inline__ bitsof_irtype(IRType type)
127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8;
129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Exported variables */
133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern int verbose;
134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif // VTEST_H
136