blob: 89a723751471dc69b176ce8702bf9b9718473b7a [file] [log] [blame]
florianbb913cd2012-08-28 16:50:39 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
florian5aa9d1e2015-09-22 07:21:50 +00003/*
4 This file is part of MemCheck, a heavyweight Valgrind tool for
5 detecting memory errors.
6
Elliott Hughesed398002017-06-21 14:41:24 -07007 Copyright (C) 2012-2017 Florian Krohm
florian5aa9d1e2015-09-22 07:21:50 +00008
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
florianbb913cd2012-08-28 16:50:39 +000027#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. */
34static vbits_t
35and_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
florianbb913cd2012-08-28 16:50:39 +000071/* Check the result of a binary operation. */
72static void
73check_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];
Elliott Hughesa0664b92017-04-18 17:46:52 -070078 opnd_t tmp;
florianbb913cd2012-08-28 16:50:39 +000079 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:
Elliott Hughesa0664b92017-04-18 17:46:52 -070088 /* Iop_ShlD64, Iop_ShrD64, Iop_ShlD128, Iop_ShrD128 have
89 * one immediate operand in operand 2.
90 */
florianbb913cd2012-08-28 16:50:39 +000091 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
carll686b17f2012-11-16 18:58:08 +0000185 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
Elliott Hughesa0664b92017-04-18 17:46:52 -0700194 case UNDEF_ALL_64x2:
195 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
196 expected_vbits =
197 undefined_vbits_BxE(64, 2,
198 or_vbits(opnd1->vbits, opnd2->vbits));
199 break;
200
201 case UNDEF_ALL_32x4:
202 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
203 expected_vbits =
204 undefined_vbits_BxE(32, 4,
205 or_vbits(opnd1->vbits, opnd2->vbits));
206 break;
207
208 case UNDEF_ALL_16x8:
209 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
210 expected_vbits =
211 undefined_vbits_BxE(16, 8,
212 or_vbits(opnd1->vbits, opnd2->vbits));
213 break;
214
215 case UNDEF_ALL_8x16:
216 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
217 expected_vbits =
218 undefined_vbits_BxE(8, 16,
219 or_vbits(opnd1->vbits, opnd2->vbits));
220 break;
221
222 case UNDEF_ALL_32x4_EVEN:
223 /* Only even input bytes are used, result can be twice as wide */
224 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
225 expected_vbits =
226 undefined_vbits_BxE(64, 2,
227 undefined_vbits_128_even_element(32, 4,
228 or_vbits(opnd1->vbits, opnd2->vbits)));
229 break;
230
231 case UNDEF_ALL_16x8_EVEN:
232 /* Only even input bytes are used, result can be twice as wide */
233 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
234 expected_vbits =
235 undefined_vbits_BxE(32, 4,
236 undefined_vbits_128_even_element(16, 8,
237 or_vbits(opnd1->vbits, opnd2->vbits)));
238 break;
239
240 case UNDEF_ALL_8x16_EVEN:
241 /* Only even input bytes are used, result can be twice as wide */
242 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
243 expected_vbits =
244 undefined_vbits_BxE(16, 8,
245 undefined_vbits_128_even_element(8, 16,
246 or_vbits(opnd1->vbits, opnd2->vbits)));
247 break;
248
249 case UNDEF_64x2_ROTATE:
250 /* Rotate left each element in opnd1 by the amount in the corresponding
251 * element of opnd2.
252 */
253 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
254 /* Setup the tmp to match what the vbit tester seems to use. I can't
255 * use opnd2-value since valgrind doesn't think it has been set.
256 */
257 tmp.value.u128[0] = -1;
258 tmp.value.u128[1] = -1;
259 /* Calculate expected for the first operand when it is shifted.
260 * If any of the vbits are set for the shift field of the second operand
261 * then the result of the expected result for that element is all 1's.
262 */
263 expected_vbits = or_vbits(undefined_vbits_BxE_rotate(64, 2, opnd1->vbits,
264 tmp.value),
265 undefined_vbits_BxE(64, 2, opnd2->vbits));
266 break;
267
268 case UNDEF_32x4_ROTATE:
269 /* Rotate left each element in opnd1 by the amount in the corresponding
270 * element of opnd2.
271 */
272 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
273 expected_vbits = undefined_vbits_BxE_rotate(32, 4, opnd1->vbits,
274 opnd2->value);
275 break;
276
277 case UNDEF_16x8_ROTATE:
278 /* Rotate left each element in opnd1 by the amount in the corresponding
279 * element of opnd2.
280 */
281 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
282 expected_vbits = undefined_vbits_BxE_rotate(16, 8, opnd1->vbits,
283 opnd2->value);
284 break;
285
286 case UNDEF_8x16_ROTATE:
287 /* Rotate left each element in opnd1 by the amount in the corresponding
288 * element of opnd2.
289 */
290 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
291 expected_vbits = undefined_vbits_BxE_rotate(16, 8, opnd1->vbits,
292 opnd2->value);
293 break;
294
295 case UNDEF_SOME:
296 /* The result for the Iop_SHA256 and Iop_SHA256 is a secure hash. If
297 * one of the input bits is not defined there must be atleast one
298 * undefined bit in the output. Which bit and how many depends on
299 * which bit is undefined. Don't know the secure hash algorithm so
300 * we can only make sure at least one of the result bits is set.
301 *
302 * The Iop_SHA256, Iop_SHA512 iops have one immediate value in the
303 * second operand.
304 */
305 expected_vbits.num_bits = result->vbits.num_bits;
306
307 if ((result->vbits.bits.u128[0] != 0) ||
308 (result->vbits.bits.u128[1] != 0)) {
309 expected_vbits.bits.u128[0] = result->vbits.bits.u128[0];
310 expected_vbits.bits.u128[1] = result->vbits.bits.u128[1];
311
312 } else {
313 /* The input had at least one vbit set but the result doesn't have any
314 * bit set. Set them all so we will trigger the error on the call
315 * to complain().
316 */
317 expected_vbits.bits.u128[0] = ~0x0ULL;
318 expected_vbits.bits.u128[1] = ~0x0ULL;
319 }
320 break;
321
322 case UNDEF_NARROW256_AtoB:
323 assert(opnd1->vbits.num_bits == opnd2->vbits.num_bits);
324 switch(op->op) {
325 case Iop_NarrowBin64to32x4:
326 expected_vbits =
327 undefined_vbits_Narrow256_AtoB(64, 32, opnd1->vbits, opnd1->value,
328 opnd2->vbits, opnd2->value,
329 False);
330 break;
331 case Iop_QNarrowBin64Sto32Sx4:
332 expected_vbits =
333 undefined_vbits_Narrow256_AtoB(64, 32, opnd1->vbits, opnd1->value,
334 opnd2->vbits, opnd2->value,
335 True);
336 break;
337 case Iop_QNarrowBin64Uto32Ux4:
338 expected_vbits =
339 undefined_vbits_Narrow256_AtoB(64, 32, opnd1->vbits, opnd1->value,
340 opnd2->vbits, opnd2->value,
341 True);
342 break;
343 default:
344 fprintf(stderr, "ERROR, unknown Iop for UNDEF_NARROW256_AtoB\n");
345 panic(__func__);
346 }
347 break;
348
florianbb913cd2012-08-28 16:50:39 +0000349 default:
350 panic(__func__);
351 }
352
353 if (! equal_vbits(result->vbits, expected_vbits))
354 complain(op, data, expected_vbits);
355}
356
357
carll24c9e7f2012-11-16 19:41:21 +0000358static int
florianbb913cd2012-08-28 16:50:39 +0000359test_shift(const irop_t *op, test_data_t *data)
360{
361 unsigned num_input_bits, i;
362 opnd_t *opnds = data->opnds;
carll24c9e7f2012-11-16 19:41:21 +0000363 int tests_done = 0;
florianbb913cd2012-08-28 16:50:39 +0000364
365 /* When testing the 1st operand's undefinedness propagation,
366 do so with all possible shift amnounts */
367 for (unsigned amount = 0; amount < bitsof_irtype(opnds[0].type); ++amount) {
368 opnds[1].value.u8 = amount;
369
370 // 1st (left) operand
371 num_input_bits = bitsof_irtype(opnds[0].type);
372
373 for (i = 0; i < num_input_bits; ++i) {
374 opnds[0].vbits = onehot_vbits(i, bitsof_irtype(opnds[0].type));
375 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
376
377 valgrind_execute_test(op, data);
378
379 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000380 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000381 }
382 }
383
384 // 2nd (right) operand
florianf74f5422012-09-13 19:41:12 +0000385
386 /* If the operand is an immediate value, there are no v-bits to set. */
Elliott Hughesa0664b92017-04-18 17:46:52 -0700387 if (!op->immediate_index) return tests_done;
florianf74f5422012-09-13 19:41:12 +0000388
florianbb913cd2012-08-28 16:50:39 +0000389 num_input_bits = bitsof_irtype(opnds[1].type);
390
391 for (i = 0; i < num_input_bits; ++i) {
392 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
393 opnds[1].vbits = onehot_vbits(i, bitsof_irtype(opnds[1].type));
394
395 valgrind_execute_test(op, data);
396
397 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000398
399 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000400 }
carll24c9e7f2012-11-16 19:41:21 +0000401 return tests_done;
florianbb913cd2012-08-28 16:50:39 +0000402}
403
404
405static value_t
406all_bits_zero_value(unsigned num_bits)
407{
408 value_t val;
409
410 switch (num_bits) {
411 case 8: val.u8 = 0; break;
412 case 16: val.u16 = 0; break;
413 case 32: val.u32 = 0; break;
414 case 64: val.u64 = 0; break;
415 default:
416 panic(__func__);
417 }
418 return val;
419}
420
421
422static value_t
423all_bits_one_value(unsigned num_bits)
424{
425 value_t val;
426
427 switch (num_bits) {
428 case 8: val.u8 = 0xff; break;
429 case 16: val.u16 = 0xffff; break;
430 case 32: val.u32 = ~0u; break;
431 case 64: val.u64 = ~0ull; break;
432 default:
433 panic(__func__);
434 }
435 return val;
436}
437
438
carll24c9e7f2012-11-16 19:41:21 +0000439static int
florianbb913cd2012-08-28 16:50:39 +0000440test_and(const irop_t *op, test_data_t *data)
441{
442 unsigned num_input_bits, bitpos;
443 opnd_t *opnds = data->opnds;
carll24c9e7f2012-11-16 19:41:21 +0000444 int tests_done = 0;
florianbb913cd2012-08-28 16:50:39 +0000445
446 /* Undefinedness does not propagate if the other operand is 0.
447 Use an all-bits-zero operand and test the other operand in
448 the usual way (one bit undefined at a time). */
449
450 // 1st (left) operand variable, 2nd operand all-bits-zero
451 num_input_bits = bitsof_irtype(opnds[0].type);
452
453 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
454 opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
455 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
456 opnds[1].value = all_bits_zero_value(bitsof_irtype(opnds[1].type));
457
458 valgrind_execute_test(op, data);
459
460 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000461 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000462 }
463
464 // 2nd (right) operand variable, 1st operand all-bits-zero
465 num_input_bits = bitsof_irtype(opnds[1].type);
466
467 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
468 opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
469 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
470 opnds[0].value = all_bits_zero_value(bitsof_irtype(opnds[0].type));
471
472 valgrind_execute_test(op, data);
473
474 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000475 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000476 }
477
478 /* Undefinedness propagates if the other operand is 1.
479 Use an all-bits-one operand and test the other operand in
480 the usual way (one bit undefined at a time). */
481
482 // 1st (left) operand variable, 2nd operand all-bits-one
483 num_input_bits = bitsof_irtype(opnds[0].type);
484
485 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
486 opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
487 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
488 opnds[1].value = all_bits_one_value(bitsof_irtype(opnds[1].type));
489
490 valgrind_execute_test(op, data);
491
492 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000493 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000494 }
495
496 // 2nd (right) operand variable, 1st operand all-bits-one
497 num_input_bits = bitsof_irtype(opnds[1].type);
498
499 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
500 opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
501 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
502 opnds[0].value = all_bits_one_value(bitsof_irtype(opnds[0].type));
503
504 valgrind_execute_test(op, data);
505
506 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000507 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000508 }
carll24c9e7f2012-11-16 19:41:21 +0000509 return tests_done;
florianbb913cd2012-08-28 16:50:39 +0000510}
511
512
carll24c9e7f2012-11-16 19:41:21 +0000513static int
florianbb913cd2012-08-28 16:50:39 +0000514test_or(const irop_t *op, test_data_t *data)
515{
516 unsigned num_input_bits, bitpos;
517 opnd_t *opnds = data->opnds;
carll24c9e7f2012-11-16 19:41:21 +0000518 int tests_done = 0;
florianbb913cd2012-08-28 16:50:39 +0000519
520 /* Undefinedness does not propagate if the other operand is 1.
521 Use an all-bits-one operand and test the other operand in
522 the usual way (one bit undefined at a time). */
523
524 // 1st (left) operand variable, 2nd operand all-bits-one
525 num_input_bits = bitsof_irtype(opnds[0].type);
526
527 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
528 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
529 opnds[1].value = all_bits_one_value(bitsof_irtype(opnds[1].type));
530
531 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
532 opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
533
534 valgrind_execute_test(op, data);
535
536 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000537 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000538 }
539
540 // 2nd (right) operand variable, 1st operand all-bits-one
541 num_input_bits = bitsof_irtype(opnds[1].type);
542
543 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
544 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
545 opnds[0].value = all_bits_one_value(bitsof_irtype(opnds[0].type));
546
547 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
548 opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
549
550 valgrind_execute_test(op, data);
551
552 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000553 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000554 }
555
556 /* Undefinedness propagates if the other operand is 0.
557 Use an all-bits-zero operand and test the other operand in
558 the usual way (one bit undefined at a time). */
559
560 // 1st (left) operand variable, 2nd operand all-bits-zero
561 num_input_bits = bitsof_irtype(opnds[0].type);
562
563 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
564 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
565 opnds[1].value = all_bits_zero_value(bitsof_irtype(opnds[1].type));
566
567 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
568 opnds[0].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[0].type));
569
570 valgrind_execute_test(op, data);
571
572 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000573 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000574 }
575
576 // 2nd (right) operand variable, 1st operand all-bits-zero
577 num_input_bits = bitsof_irtype(opnds[1].type);
578
579 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
580 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
581 opnds[0].value = all_bits_zero_value(bitsof_irtype(opnds[0].type));
582
583 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
584 opnds[1].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[1].type));
585
586 valgrind_execute_test(op, data);
587
588 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000589 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000590 }
carll24c9e7f2012-11-16 19:41:21 +0000591 return tests_done;
florianbb913cd2012-08-28 16:50:39 +0000592}
593
594
carll24c9e7f2012-11-16 19:41:21 +0000595int
florianbb913cd2012-08-28 16:50:39 +0000596test_binary_op(const irop_t *op, test_data_t *data)
597{
598 unsigned num_input_bits, i, bitpos;
599 opnd_t *opnds = data->opnds;
carll24c9e7f2012-11-16 19:41:21 +0000600 int tests_done = 0;
florianbb913cd2012-08-28 16:50:39 +0000601
602 /* Handle special cases upfront */
603 switch (op->undef_kind) {
604 case UNDEF_SHL:
605 case UNDEF_SHR:
606 case UNDEF_SAR:
carll24c9e7f2012-11-16 19:41:21 +0000607 return test_shift(op, data);
florianbb913cd2012-08-28 16:50:39 +0000608
609 case UNDEF_AND:
carll24c9e7f2012-11-16 19:41:21 +0000610 return test_and(op, data);
florianbb913cd2012-08-28 16:50:39 +0000611
612 case UNDEF_OR:
carll24c9e7f2012-11-16 19:41:21 +0000613 return test_or(op, data);
florianbb913cd2012-08-28 16:50:39 +0000614
615 default:
616 break;
617 }
618
619 /* For each operand, set a single bit to undefined and observe how
620 that propagates to the output. Do this for all bits in each
621 operand. */
622 for (i = 0; i < 2; ++i) {
florianf74f5422012-09-13 19:41:12 +0000623
Elliott Hughesa0664b92017-04-18 17:46:52 -0700624 /* If this is a Iop that requires an immediate amount,
625 do not iterate the v-bits of the operand */
626 if (((i+1) == op->immediate_index)
627 && (op->immediate_index)) break;
florianf74f5422012-09-13 19:41:12 +0000628
florianbb913cd2012-08-28 16:50:39 +0000629 num_input_bits = bitsof_irtype(opnds[i].type);
630 opnds[0].vbits = defined_vbits(bitsof_irtype(opnds[0].type));
631 opnds[1].vbits = defined_vbits(bitsof_irtype(opnds[1].type));
632
633 /* Set the value of the 2nd operand to something != 0. So division
634 won't crash. */
635 memset(&opnds[1].value, 0xff, sizeof opnds[1].value);
636
florian5c00a612015-10-17 11:18:50 +0000637 /* For immediate shift amounts choose a value of '1'. That value should
638 not cause a problem. Note: we always assign to the u64 member here.
639 The reason is that in ir_inject.c the value_t type is not visible.
640 The value is picked up there by interpreting the memory as an
641 ULong value. So, we rely on
642 union {
643 ULong v1; // value picked up in ir_inject.c
644 value_t v2; // value assigned here
645 } xx;
646 assert(sizeof xx.v1 == sizeof xx.v2.u64);
647 assert(xx.v1 == xx.v2.u64);
648 */
Elliott Hughesa0664b92017-04-18 17:46:52 -0700649
650 if (op->immediate_index > 0) {
651 assert((op->immediate_type == Ity_I8)
652 || (op->immediate_type == Ity_I16)
653 || (op->immediate_type == Ity_I32));
florian5c00a612015-10-17 11:18:50 +0000654 opnds[1].value.u64 = 1;
Elliott Hughesa0664b92017-04-18 17:46:52 -0700655 }
florianf74f5422012-09-13 19:41:12 +0000656
florianbb913cd2012-08-28 16:50:39 +0000657 for (bitpos = 0; bitpos < num_input_bits; ++bitpos) {
658 opnds[i].vbits = onehot_vbits(bitpos, bitsof_irtype(opnds[i].type));
659
660 valgrind_execute_test(op, data);
661
662 check_result_for_binary(op, data);
carll24c9e7f2012-11-16 19:41:21 +0000663
664 tests_done++;
florianbb913cd2012-08-28 16:50:39 +0000665 }
666 }
carll24c9e7f2012-11-16 19:41:21 +0000667 return tests_done;
florianbb913cd2012-08-28 16:50:39 +0000668}