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 #include <assert.h>
28 #include <string.h>  // memset
29 #include "vtest.h"
30 
31 
32 /* A convenience function to compute either v1 & ~v2 & val2  or
33    v1 & ~v2 & ~val2  depending on INVERT_VAL2. */
34 static vbits_t
and_combine(vbits_t v1,vbits_t v2,value_t val2,int invert_val2)35 and_combine(vbits_t v1, vbits_t v2, value_t val2, int invert_val2)
36 {
37    assert(v1.num_bits == v2.num_bits);
38 
39    vbits_t new = { .num_bits = v2.num_bits };
40 
41    if (invert_val2) {
42       switch (v2.num_bits) {
43       case 8:  val2.u8  = ~val2.u8  & 0xff;   break;
44       case 16: val2.u16 = ~val2.u16 & 0xffff; break;
45       case 32: val2.u32 = ~val2.u32;          break;
46       case 64: val2.u64 = ~val2.u64;          break;
47       default:
48          panic(__func__);
49       }
50    }
51 
52    switch (v2.num_bits) {
53    case 8:
54       new.bits.u8  = (v1.bits.u8 & ~v2.bits.u8  & val2.u8)  & 0xff;
55       break;
56    case 16:
57       new.bits.u16 = (v1.bits.u16 & ~v2.bits.u16 & val2.u16) & 0xffff;
58       break;
59    case 32:
60       new.bits.u32 = (v1.bits.u32 & ~v2.bits.u32 & val2.u32);
61       break;
62    case 64:
63       new.bits.u64 = (v1.bits.u64 & ~v2.bits.u64 & val2.u64);
64       break;
65    default:
66       panic(__func__);
67    }
68    return new;
69 }
70 
71 /* Check the result of a binary operation. */
72 static void
check_result_for_binary(const irop_t * op,const test_data_t * data)73 check_result_for_binary(const irop_t *op, const test_data_t *data)
74 {
75    const opnd_t *result = &data->result;
76    const opnd_t *opnd1  = &data->opnds[0];
77    const opnd_t *opnd2  = &data->opnds[1];
78    opnd_t tmp;
79    vbits_t expected_vbits;
80 
81    /* Only handle those undef-kinds that actually occur. */
82    switch (op->undef_kind) {
83    case UNDEF_NONE:
84       expected_vbits = defined_vbits(result->vbits.num_bits);
85       break;
86 
87    case UNDEF_ALL:
88       /* Iop_ShlD64, Iop_ShrD64, Iop_ShlD128, Iop_ShrD128 have
89        * one immediate operand in operand 2.
90        */
91       expected_vbits = undefined_vbits(result->vbits.num_bits);
92       break;
93 
94    case UNDEF_LEFT:
95       // LEFT with respect to the leftmost 1-bit in both operands
96       expected_vbits = left_vbits(or_vbits(opnd1->vbits, opnd2->vbits),
97                                   result->vbits.num_bits);
98       break;
99 
100    case UNDEF_SAME:
101       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
102       assert(opnd1->vbits.num_bits == result->vbits.num_bits);
103 
104       // SAME with respect to the 1-bits in both operands
105       expected_vbits = or_vbits(opnd1->vbits, opnd2->vbits);
106       break;
107 
108    case UNDEF_CONCAT:
109       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
110       assert(result->vbits.num_bits == 2 * opnd1->vbits.num_bits);
111       expected_vbits = concat_vbits(opnd1->vbits, opnd2->vbits);
112       break;
113 
114    case UNDEF_SHL:
115       /* If any bit in the 2nd operand is undefined, so are all bits
116          of the result. */
117       if (! completely_defined_vbits(opnd2->vbits)) {
118          expected_vbits = undefined_vbits(result->vbits.num_bits);
119       } else {
120          assert(opnd2->vbits.num_bits == 8);
121          unsigned shift_amount = opnd2->value.u8;
122 
123          expected_vbits = shl_vbits(opnd1->vbits, shift_amount);
124       }
125       break;
126 
127    case UNDEF_SHR:
128       /* If any bit in the 2nd operand is undefined, so are all bits
129          of the result. */
130       if (! completely_defined_vbits(opnd2->vbits)) {
131          expected_vbits = undefined_vbits(result->vbits.num_bits);
132       } else {
133          assert(opnd2->vbits.num_bits == 8);
134          unsigned shift_amount = opnd2->value.u8;
135 
136          expected_vbits = shr_vbits(opnd1->vbits, shift_amount);
137       }
138       break;
139 
140    case UNDEF_SAR:
141       /* If any bit in the 2nd operand is undefined, so are all bits
142          of the result. */
143       if (! completely_defined_vbits(opnd2->vbits)) {
144          expected_vbits = undefined_vbits(result->vbits.num_bits);
145       } else {
146          assert(opnd2->vbits.num_bits == 8);
147          unsigned shift_amount = opnd2->value.u8;
148 
149          expected_vbits = sar_vbits(opnd1->vbits, shift_amount);
150       }
151       break;
152 
153    case UNDEF_AND: {
154       /* Let v1, v2 be the V-bits of the 1st and 2nd operand, respectively
155          Let b1, b2 be the actual value of the 1st and 2nd operand, respect.
156          And output bit is undefined (i.e. its V-bit == 1), iff
157          (1) (v1 == 1) && (v2 == 1)   OR
158          (2) (v1 == 1) && (v2 == 0 && b2 == 1) OR
159          (3) (v2 == 1) && (v1 == 0 && b1 == 1)
160       */
161       vbits_t term1, term2, term3;
162       term1 = and_vbits(opnd1->vbits, opnd2->vbits);
163       term2 = and_combine(opnd1->vbits, opnd2->vbits, opnd2->value, 0);
164       term3 = and_combine(opnd2->vbits, opnd1->vbits, opnd1->value, 0);
165       expected_vbits = or_vbits(term1, or_vbits(term2, term3));
166       break;
167    }
168 
169    case UNDEF_OR: {
170       /* Let v1, v2 be the V-bits of the 1st and 2nd operand, respectively
171          Let b1, b2 be the actual value of the 1st and 2nd operand, respect.
172          And output bit is undefined (i.e. its V-bit == 1), iff
173          (1) (v1 == 1) && (v2 == 1)   OR
174          (2) (v1 == 1) && (v2 == 0 && b2 == 0) OR
175          (3) (v2 == 1) && (v1 == 0 && b1 == 0)
176       */
177       vbits_t term1, term2, term3;
178       term1 = and_vbits(opnd1->vbits, opnd2->vbits);
179       term2 = and_combine(opnd1->vbits, opnd2->vbits, opnd2->value, 1);
180       term3 = and_combine(opnd2->vbits, opnd1->vbits, opnd1->value, 1);
181       expected_vbits = or_vbits(term1, or_vbits(term2, term3));
182       break;
183    }
184 
185    case UNDEF_ORD:
186       /* Set expected_vbits for the Iop_CmpORD category of iops.
187        * If any of the input bits is undefined the least significant
188        * three bits in the result will be set, i.e. 0xe.
189        */
190       expected_vbits = cmpord_vbits(opnd1->vbits.num_bits,
191                                     opnd2->vbits.num_bits);
192       break;
193 
194    case UNDEF_CMP_EQ_NE:
195       expected_vbits = cmp_eq_ne_vbits(opnd1->vbits, opnd2->vbits,
196                                        opnd1->value, opnd2->value);
197       break;
198 
199    case UNDEF_INT_ADD:
200       expected_vbits = int_add_or_sub_vbits(1/*isAdd*/,
201                                             opnd1->vbits, opnd2->vbits,
202                                             opnd1->value, opnd2->value);
203       break;
204 
205    case UNDEF_INT_SUB:
206       expected_vbits = int_add_or_sub_vbits(0/*!isAdd*/,
207                                             opnd1->vbits, opnd2->vbits,
208                                             opnd1->value, opnd2->value);
209       break;
210 
211    case UNDEF_ALL_64x2:
212       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
213       expected_vbits =
214          undefined_vbits_BxE(64, 2,
215                              or_vbits(opnd1->vbits, opnd2->vbits));
216       break;
217 
218    case UNDEF_ALL_32x4:
219       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
220       expected_vbits =
221          undefined_vbits_BxE(32, 4,
222                              or_vbits(opnd1->vbits, opnd2->vbits));
223       break;
224 
225    case UNDEF_ALL_16x8:
226       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
227       expected_vbits =
228          undefined_vbits_BxE(16, 8,
229                              or_vbits(opnd1->vbits, opnd2->vbits));
230       break;
231 
232    case UNDEF_ALL_8x16:
233       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
234       expected_vbits =
235          undefined_vbits_BxE(8, 16,
236                              or_vbits(opnd1->vbits, opnd2->vbits));
237       break;
238 
239    case UNDEF_ALL_32x4_EVEN:
240       /* Only even input bytes are used, result can be twice as wide */
241       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
242       expected_vbits =
243          undefined_vbits_BxE(64, 2,
244                              undefined_vbits_128_even_element(32, 4,
245                                         or_vbits(opnd1->vbits, opnd2->vbits)));
246       break;
247 
248    case UNDEF_ALL_16x8_EVEN:
249       /* Only even input bytes are used, result can be twice as wide */
250       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
251       expected_vbits =
252          undefined_vbits_BxE(32, 4,
253                              undefined_vbits_128_even_element(16, 8,
254                                         or_vbits(opnd1->vbits, opnd2->vbits)));
255       break;
256 
257    case UNDEF_ALL_8x16_EVEN:
258       /* Only even input bytes are used, result can be twice as wide */
259       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
260       expected_vbits =
261          undefined_vbits_BxE(16, 8,
262                              undefined_vbits_128_even_element(8, 16,
263                                         or_vbits(opnd1->vbits, opnd2->vbits)));
264       break;
265 
266    case UNDEF_64x2_ROTATE:
267       /* Rotate left each element in opnd1 by the amount in the corresponding
268        * element of opnd2.
269        */
270       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
271       /* Setup the tmp to match what the vbit tester seems to use.  I can't
272        * use opnd2-value since valgrind doesn't think it has been set.
273        */
274       tmp.value.u128[0] = -1;
275       tmp.value.u128[1] = -1;
276       /* Calculate expected for the first operand when it is shifted.
277        * If any of the vbits are set for the shift field of the second operand
278        * then the result of the expected result for that element is all 1's.
279        */
280       expected_vbits = or_vbits(undefined_vbits_BxE_rotate(64, 2, opnd1->vbits,
281                                                            tmp.value),
282                                 undefined_vbits_BxE(64, 2, opnd2->vbits));
283       break;
284 
285    case UNDEF_32x4_ROTATE:
286       /* Rotate left each element in opnd1 by the amount in the corresponding
287        * element of opnd2.
288        */
289       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
290       expected_vbits = undefined_vbits_BxE_rotate(32, 4, opnd1->vbits,
291                                                   opnd2->value);
292       break;
293 
294    case UNDEF_16x8_ROTATE:
295       /* Rotate left each element in opnd1 by the amount in the corresponding
296        * element of opnd2.
297        */
298       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
299       expected_vbits = undefined_vbits_BxE_rotate(16, 8, opnd1->vbits,
300                                                   opnd2->value);
301       break;
302 
303    case UNDEF_8x16_ROTATE:
304       /* Rotate left each element in opnd1 by the amount in the corresponding
305        * element of opnd2.
306        */
307       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
308       expected_vbits = undefined_vbits_BxE_rotate(16, 8, opnd1->vbits,
309                                                   opnd2->value);
310       break;
311 
312    case UNDEF_SOME:
313       /* The result for the Iop_SHA256 and Iop_SHA256 is a secure hash. If
314        * one of the input bits is not defined there must be atleast one
315        * undefined bit in the output.  Which bit and how many depends on
316        * which bit is undefined.  Don't know the secure hash algorithm so
317        * we can only make sure at least one of the result bits is set.
318        *
319        * The Iop_SHA256, Iop_SHA512 iops have one immediate value in the
320        * second operand.
321        */
322       expected_vbits.num_bits = result->vbits.num_bits;
323 
324       if ((result->vbits.bits.u128[0] != 0) ||
325           (result->vbits.bits.u128[1] != 0)) {
326          expected_vbits.bits.u128[0] = result->vbits.bits.u128[0];
327          expected_vbits.bits.u128[1] = result->vbits.bits.u128[1];
328 
329       } else {
330          /* The input had at least one vbit set but the result doesn't have any
331           * bit set.  Set them all so we will trigger the error on the call
332           * to complain().
333           */
334          expected_vbits.bits.u128[0] = ~0x0ULL;
335          expected_vbits.bits.u128[1] = ~0x0ULL;
336       }
337       break;
338 
339    case UNDEF_NARROW256_AtoB:
340       assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
341       switch(op->op) {
342       case Iop_NarrowBin64to32x4:
343          expected_vbits =
344             undefined_vbits_Narrow256_AtoB(64, 32, opnd1->vbits, opnd1->value,
345                                            opnd2->vbits, opnd2->value,
346                                            False);
347          break;
348       case Iop_QNarrowBin64Sto32Sx4:
349          expected_vbits =
350             undefined_vbits_Narrow256_AtoB(64, 32, opnd1->vbits, opnd1->value,
351                                            opnd2->vbits, opnd2->value,
352                                            True);
353          break;
354       case Iop_QNarrowBin64Uto32Ux4:
355          expected_vbits =
356             undefined_vbits_Narrow256_AtoB(64, 32, opnd1->vbits, opnd1->value,
357                                            opnd2->vbits, opnd2->value,
358                                            True);
359          break;
360       default:
361          fprintf(stderr, "ERROR, unknown Iop for UNDEF_NARROW256_AtoB\n");
362          panic(__func__);
363       }
364       break;
365 
366    default:
367       panic(__func__);
368    }
369 
370    if (! equal_vbits(result->vbits, expected_vbits))
371       complain(op, data, expected_vbits);
372 }
373 
374 
375 static int
test_shift(const irop_t * op,test_data_t * data)376 test_shift(const irop_t *op, test_data_t *data)
377 {
378    unsigned num_input_bits, i;
379    opnd_t *opnds = data->opnds;
380    int tests_done = 0;
381 
382    /* When testing the 1st operand's undefinedness propagation,
383       do so with all possible shift amnounts */
384    for (unsigned amount = 0; amount < bitsof_irtype(opnds[0].type); ++amount) {
385       opnds[1].value.u8 = amount;
386 
387       // 1st (left) operand
388       num_input_bits = bitsof_irtype(opnds[0].type);
389 
390       for (i = 0; i < num_input_bits; ++i) {
391          opnds[0].vbits = onehot_vbits(i, bitsof_irtype(opnds[0].type));
392          opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
393 
394          valgrind_execute_test(op, data);
395 
396          check_result_for_binary(op, data);
397          tests_done++;
398       }
399    }
400 
401    // 2nd (right) operand
402 
403    /* If the operand is an immediate value, there are no v-bits to set. */
404    if (!op->immediate_index) return tests_done;
405 
406    num_input_bits = bitsof_irtype(opnds[1].type);
407 
408    for (i = 0; i < num_input_bits; ++i) {
409       opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
410       opnds[1].vbits = onehot_vbits(i, bitsof_irtype(opnds[1].type));
411 
412       valgrind_execute_test(op, data);
413 
414       check_result_for_binary(op, data);
415 
416       tests_done++;
417    }
418    return tests_done;
419 }
420 
421 
422 static value_t
all_bits_zero_value(unsigned num_bits)423 all_bits_zero_value(unsigned num_bits)
424 {
425    value_t val;
426 
427    switch (num_bits) {
428    case 8:  val.u8  = 0; break;
429    case 16: val.u16 = 0; break;
430    case 32: val.u32 = 0; break;
431    case 64: val.u64 = 0; break;
432    default:
433       panic(__func__);
434    }
435    return val;
436 }
437 
438 
439 static value_t
all_bits_one_value(unsigned num_bits)440 all_bits_one_value(unsigned num_bits)
441 {
442    value_t val;
443 
444    switch (num_bits) {
445    case 8:  val.u8  = 0xff;   break;
446    case 16: val.u16 = 0xffff; break;
447    case 32: val.u32 = ~0u;    break;
448    case 64: val.u64 = ~0ull;  break;
449    default:
450       panic(__func__);
451    }
452    return val;
453 }
454 
455 
456 static int
test_and(const irop_t * op,test_data_t * data)457 test_and(const irop_t *op, test_data_t *data)
458 {
459    unsigned num_input_bits, bitpos;
460    opnd_t *opnds = data->opnds;
461    int tests_done = 0;
462 
463    /* Undefinedness does not propagate if the other operand is 0.
464       Use an all-bits-zero operand and test the other operand in
465       the usual way (one bit undefined at a time). */
466 
467    // 1st (left) operand variable, 2nd operand all-bits-zero
468    num_input_bits = bitsof_irtype(opnds[0].type);
469 
470    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
471       opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
472       opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
473       opnds[1].value = all_bits_zero_value(bitsof_irtype(opnds[1].type));
474 
475       valgrind_execute_test(op, data);
476 
477       check_result_for_binary(op, data);
478       tests_done++;
479    }
480 
481    // 2nd (right) operand variable, 1st operand all-bits-zero
482    num_input_bits = bitsof_irtype(opnds[1].type);
483 
484    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
485       opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
486       opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
487       opnds[0].value = all_bits_zero_value(bitsof_irtype(opnds[0].type));
488 
489       valgrind_execute_test(op, data);
490 
491       check_result_for_binary(op, data);
492       tests_done++;
493    }
494 
495    /* Undefinedness propagates if the other operand is 1.
496       Use an all-bits-one operand and test the other operand in
497       the usual way (one bit undefined at a time). */
498 
499    // 1st (left) operand variable, 2nd operand all-bits-one
500    num_input_bits = bitsof_irtype(opnds[0].type);
501 
502    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
503       opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
504       opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
505       opnds[1].value = all_bits_one_value(bitsof_irtype(opnds[1].type));
506 
507       valgrind_execute_test(op, data);
508 
509       check_result_for_binary(op, data);
510       tests_done++;
511    }
512 
513    // 2nd (right) operand variable, 1st operand all-bits-one
514    num_input_bits = bitsof_irtype(opnds[1].type);
515 
516    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
517       opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
518       opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
519       opnds[0].value = all_bits_one_value(bitsof_irtype(opnds[0].type));
520 
521       valgrind_execute_test(op, data);
522 
523       check_result_for_binary(op, data);
524       tests_done++;
525    }
526    return tests_done;
527 }
528 
529 
530 static int
test_or(const irop_t * op,test_data_t * data)531 test_or(const irop_t *op, test_data_t *data)
532 {
533    unsigned num_input_bits, bitpos;
534    opnd_t *opnds = data->opnds;
535    int tests_done = 0;
536 
537    /* Undefinedness does not propagate if the other operand is 1.
538       Use an all-bits-one operand and test the other operand in
539       the usual way (one bit undefined at a time). */
540 
541    // 1st (left) operand variable, 2nd operand all-bits-one
542    num_input_bits = bitsof_irtype(opnds[0].type);
543 
544    opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
545    opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
546    opnds[1].value = all_bits_one_value(bitsof_irtype(opnds[1].type));
547 
548    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
549       opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
550 
551       valgrind_execute_test(op, data);
552 
553       check_result_for_binary(op, data);
554       tests_done++;
555    }
556 
557    // 2nd (right) operand variable, 1st operand all-bits-one
558    num_input_bits = bitsof_irtype(opnds[1].type);
559 
560    opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
561    opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
562    opnds[0].value = all_bits_one_value(bitsof_irtype(opnds[0].type));
563 
564    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
565       opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
566 
567       valgrind_execute_test(op, data);
568 
569       check_result_for_binary(op, data);
570       tests_done++;
571    }
572 
573    /* Undefinedness propagates if the other operand is 0.
574       Use an all-bits-zero operand and test the other operand in
575       the usual way (one bit undefined at a time). */
576 
577    // 1st (left) operand variable, 2nd operand all-bits-zero
578    num_input_bits = bitsof_irtype(opnds[0].type);
579 
580    opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
581    opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
582    opnds[1].value = all_bits_zero_value(bitsof_irtype(opnds[1].type));
583 
584    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
585       opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
586 
587       valgrind_execute_test(op, data);
588 
589       check_result_for_binary(op, data);
590       tests_done++;
591    }
592 
593    // 2nd (right) operand variable, 1st operand all-bits-zero
594    num_input_bits = bitsof_irtype(opnds[1].type);
595 
596    opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
597    opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
598    opnds[0].value = all_bits_zero_value(bitsof_irtype(opnds[0].type));
599 
600    for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
601       opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
602 
603       valgrind_execute_test(op, data);
604 
605       check_result_for_binary(op, data);
606       tests_done++;
607    }
608    return tests_done;
609 }
610 
611 
612 int
test_binary_op(const irop_t * op,test_data_t * data)613 test_binary_op(const irop_t *op, test_data_t *data)
614 {
615    unsigned num_input_bits, i, bitpos;
616    opnd_t *opnds = data->opnds;
617    int tests_done = 0;
618 
619    /* Handle special cases upfront */
620    switch (op->undef_kind) {
621    case UNDEF_SHL:
622    case UNDEF_SHR:
623    case UNDEF_SAR:
624       return test_shift(op, data);
625 
626    case UNDEF_AND:
627       return test_and(op, data);
628 
629    case UNDEF_OR:
630       return test_or(op, data);
631 
632    default:
633       break;
634    }
635 
636    /* For each operand, set a single bit to undefined and observe how
637       that propagates to the output. Do this for all bits in each
638       operand. */
639    for (i = 0; i < 2; ++i) {
640 
641       /* If this is a Iop that requires an immediate amount,
642          do not iterate the v-bits of the operand */
643       if (((i+1) == op->immediate_index)
644           && (op->immediate_index)) break;
645 
646       num_input_bits = bitsof_irtype(opnds[i].type);
647       opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
648       opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
649 
650       /* Set the value of the 2nd operand to something != 0. So division
651          won't crash. */
652       memset(&opnds[1].value, 0xff, sizeof opnds[1].value);
653 
654       /* For immediate shift amounts choose a value of '1'. That value should
655          not cause a problem. Note: we always assign to the u64 member here.
656          The reason is that in ir_inject.c the value_t type is not visible.
657          The value is picked up there by interpreting the memory as an
658          ULong value. So, we rely on
659          union {
660            ULong   v1;   // value picked up in ir_inject.c
661            value_t v2;   // value assigned here
662          } xx;
663          assert(sizeof xx.v1 == sizeof xx.v2.u64);
664          assert(xx.v1 == xx.v2.u64);
665       */
666 
667       if (op->immediate_index > 0) {
668          assert((op->immediate_type == Ity_I8)
669                 || (op->immediate_type == Ity_I16)
670                 || (op->immediate_type == Ity_I32));
671          opnds[1].value.u64 = 1;
672       }
673 
674       for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
675          opnds[i].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[i].type));
676 
677          valgrind_execute_test(op, data);
678 
679          check_result_for_binary(op, data);
680 
681          tests_done++;
682       }
683    }
684    return tests_done;
685 }
686