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-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
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
39typedef 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 IROps I don't know anything about
83   UNDEF_UNKNOWN
84} undef_t;
85
86
87// Everything we want to know about an IROp
88typedef struct {
89   IROp op;
90   const char *name;
91   undef_t     undef_kind;
92   int         shift_amount_is_immediate;
93   // Indicate whether IROp can be tested on a particular architecture
94   unsigned    s390x  : 1;
95   unsigned    amd64  : 1;
96   unsigned    ppc32  : 1;
97   unsigned    ppc64  : 1;
98   unsigned    arm    : 1;
99   unsigned    arm64  : 1;
100   unsigned    x86    : 1;
101   unsigned    mips32 : 1;
102   unsigned    mips64 : 1;
103   unsigned    tilegx : 1;
104} irop_t;
105
106
107/* The maximum number of input operands */
108#define MAX_OPERANDS 4
109
110/* An operand of an IROp (also used for the result) */
111typedef struct {
112   IRType  type;
113   vbits_t vbits;
114   value_t value;
115} opnd_t;
116
117
118/* Carries the data needed to execute and evaluate a test. I.e.
119   inputs and results (V-bits and actual value). */
120typedef struct {
121   opnd_t result;
122   opnd_t opnds[MAX_OPERANDS];
123   unsigned rounding_mode;
124} test_data_t;
125
126
127/* Function prototypes */
128irop_t *get_irop(IROp);
129int  is_floating_point_op_with_rounding_mode(IROp);
130int  get_num_operands(IROp);
131
132void print_opnd(FILE *, const opnd_t *);
133
134int test_unary_op(const irop_t *, test_data_t *);
135int test_binary_op(const irop_t *, test_data_t *);
136int test_ternary_op(const irop_t *, test_data_t *);
137int test_qernary_op(const irop_t *, test_data_t *);
138
139void valgrind_vex_init_for_iri(IRICB *);
140void valgrind_execute_test(const irop_t *, test_data_t *);
141
142IRICB new_iricb(const irop_t *, test_data_t *);
143
144void panic(const char *) __attribute__((noreturn));
145void complain(const irop_t *, const test_data_t *, vbits_t expected);
146
147/* Imported from VEX */
148unsigned sizeof_irtype(IRType);
149void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2,
150                   IRType *t_arg3, IRType *t_arg4);
151
152static __inline__ unsigned bitsof_irtype(IRType type)
153{
154   return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8;
155}
156
157
158/* Exported variables */
159extern int verbose;
160
161#endif // VTEST_H
162