| /* -*- mode: C; c-basic-offset: 3; -*- */ |
| |
| #ifndef VTEST_H |
| #define VTEST_H |
| |
| /* Main header file for the V-bit tester */ |
| |
| #include <stdint.h> // uint64_t |
| #include "libvex.h" // IROp |
| #include "vbits.h" // vbits_t |
| |
| |
| /* How undefinedness propagates from input to output */ |
| |
| typedef enum { |
| // For any undefined input bit, all output bits are defined. |
| UNDEF_NONE, |
| |
| // For any undefined input bit, all output bits are undefined. |
| UNDEF_ALL, |
| |
| // For each undefined input bit, the corresponding output bit |
| // in the same position is undefined. No other bit is undefined. |
| UNDEF_SAME, |
| |
| // For each undefined input bit, the corresponding output bit |
| // in the same position is undefined. No other bit is undefined. |
| // If the corresponding output bit does not exist, the input bit |
| // does not cause any output bits to be undefined. |
| UNDEF_TRUNC, |
| |
| // For each undefined input bit, the corresponding output bit |
| // in the same position is undefined. No other bit is undefined. |
| // Output bits that do no not have a corresponding input bit are |
| // defined. |
| UNDEF_ZEXT, |
| |
| // For each undefined input bit, the corresponding output bit |
| // in the same position is undefined. If the MSB of the input value |
| // is undefined, so are all output bits with higher significance |
| // than the MSB input bit. |
| UNDEF_SEXT, |
| |
| // For each undefined input bit, the corresponding output bit |
| // and all output bits with higher significance are undefined. |
| UNDEF_LEFT, |
| |
| UNDEF_CONCAT, // nHLto2n ops e.g. Iop_32HLto64 |
| UNDEF_UPPER, // 2nHIton ops e.g. Iop_64HIto32 |
| UNDEF_SHL, // shift-left |
| UNDEF_SHR, // logical shift-right |
| UNDEF_SAR, // arithmetic shift-right |
| UNDEF_OR, // bitwise OR operation |
| UNDEF_AND, // bitwise AND operation |
| |
| UNDEF_ORD, // Iop_CmpORD compare |
| |
| // For IROps I don't know anything about |
| UNDEF_UNKNOWN |
| } undef_t; |
| |
| |
| // Everything we want to know about an IROp |
| typedef struct { |
| IROp op; |
| const char *name; |
| undef_t undef_kind; |
| int shift_amount_is_immediate; |
| // Indicate whether IROp can be tested on a particular architecture |
| unsigned s390x : 1; |
| unsigned amd64 : 1; |
| unsigned ppc32 : 1; |
| unsigned ppc64 : 1; |
| unsigned arm : 1; |
| unsigned arm64 : 1; |
| unsigned x86 : 1; |
| unsigned mips32 : 1; |
| unsigned mips64 : 1; |
| unsigned tilegx : 1; |
| } irop_t; |
| |
| |
| /* The maximum number of input operands */ |
| #define MAX_OPERANDS 4 |
| |
| /* An operand of an IROp (also used for the result) */ |
| typedef struct { |
| IRType type; |
| vbits_t vbits; |
| value_t value; |
| } opnd_t; |
| |
| |
| /* Carries the data needed to execute and evaluate a test. I.e. |
| inputs and results (V-bits and actual value). */ |
| typedef struct { |
| opnd_t result; |
| opnd_t opnds[MAX_OPERANDS]; |
| unsigned rounding_mode; |
| } test_data_t; |
| |
| |
| /* Function prototypes */ |
| irop_t *get_irop(IROp); |
| int is_floating_point_op_with_rounding_mode(IROp); |
| int get_num_operands(IROp); |
| |
| void print_opnd(FILE *, const opnd_t *); |
| |
| int test_unary_op(const irop_t *, test_data_t *); |
| int test_binary_op(const irop_t *, test_data_t *); |
| int test_ternary_op(const irop_t *, test_data_t *); |
| int test_qernary_op(const irop_t *, test_data_t *); |
| |
| void valgrind_vex_init_for_iri(IRICB *); |
| void valgrind_execute_test(const irop_t *, test_data_t *); |
| |
| IRICB new_iricb(const irop_t *, test_data_t *); |
| |
| void panic(const char *) __attribute__((noreturn)); |
| void complain(const irop_t *, const test_data_t *, vbits_t expected); |
| |
| /* Imported from VEX */ |
| unsigned sizeof_irtype(IRType); |
| void typeof_primop(IROp, IRType *t_dst, IRType *t_arg1, IRType *t_arg2, |
| IRType *t_arg3, IRType *t_arg4); |
| |
| static __inline__ unsigned bitsof_irtype(IRType type) |
| { |
| return type == Ity_I1 ? 1 : sizeof_irtype(type) * 8; |
| } |
| |
| |
| /* Exported variables */ |
| extern int verbose; |
| |
| #endif // VTEST_H |