2 # Copyright (C) 2001-2009, Parrot Foundation.
7 t/op/bitwise.t - Bitwise Ops
11 % prove t/op/bitwise.t
15 Tests various bitwise logical operations.
20 .include 'test_more.pir'
24 test_shr_i_i_i_shift_rt_()
25 test_shr_i_i_shift_rt_()
26 test_shr_i_i_ic_shift_rt_()
27 test_shr_i_ic_i_shift_rt_()
28 test_shr_i_ic_ic_shift_rt_()
29 test_lsr_i_ic_ic_shift_rt_()
30 test_lsr_i_ic_shift_rt()
31 test_lsr_i_i_i_shift_rt()
32 test_lsr_i_i_ic_shift_rt()
33 test_shr_i_i_ic_shift_rt_negative()
34 test_shl_i_i_i_shift_lt()
35 test_shl_i_i_ic_shift_lt()
36 test_shl_i_ic_i_shift_lt()
37 test_shl_i_ic_ic_shift_lt()
38 test_shl_i_i_shift_lt()
40 test_bxor_i_i_ic_xor()
43 test_band_i_i_ic_and()
44 test_band_i_i_ic_and_2()
50 test_i_reg_shl_and_pmc_shl_are_consistent()
54 .macro exception_is ( M )
57 .get_results (exception)
59 message = exception['message']
63 .sub test_shr_i_i_i_shift_rt_
71 is( $I4, "6", 'shr_i_i_i (>>)' )
72 is( $I2, "6", 'shr_i_i_i (>>)' )
73 is( $I1, "5", 'shr_i_i_i (>>)' )
74 is( $I0, "12", 'shr_i_i_i (>>)' )
77 .sub test_shr_i_i_shift_rt_
84 is( $I0, "6", 'shr_i_i (>>)' )
85 is( $I1, "5", 'shr_i_i (>>)' )
88 .sub test_shr_i_i_ic_shift_rt_
93 is( $I2, "6", 'shr_i_i_ic (>>)' )
94 is( $I1, "5", 'shr_i_i_ic (>>)' )
95 is( $I0, "12", 'shr_i_i_ic (>>)' )
98 .sub test_shr_i_ic_i_shift_rt_
101 shr $I2, 0b001100, $I0
102 shr $I1, 0b010100, $I1
103 is( $I2, "6", 'shr_i_ic_i (>>)' )
104 is( $I1, "5", 'shr_i_ic_i (>>)' )
107 .sub test_shr_i_ic_ic_shift_rt_
110 is( $I2, "6", 'shr_i_ic_ic (>>)' )
111 is( $I1, "5", 'shr_i_ic_ic (>>)' )
114 # The crux of this test is that a proper logical right shift
115 # will clear the most significant bit, so the shifted value
116 # will be a positive value on any 2's or 1's complement CPU
117 .sub test_lsr_i_ic_ic_shift_rt_
120 ok( 1, 'lsr_i_ic_ic (>>)' )
123 ok( 0, 'lsr_i_ic_ic (>>)' )
127 .sub test_lsr_i_ic_shift_rt
131 ok( 1, 'lsr_i_ic (>>) OK')
134 ok( 0, 'lsr_i_ic (>>)')
138 .sub test_lsr_i_i_i_shift_rt
143 ok( 1, 'lsr_i_i_i (>>) OK')
146 ok( 0, 'lsr_i_i_i (>>)')
150 # ... and the missing op signature was untested and wrong in JIT/i386
151 .sub test_lsr_i_i_ic_shift_rt
155 ok( 1, 'lsr_i_i_ic (>>) OK')
158 ok( 0, 'lsr_i_i_ic (>>)')
162 .sub test_shr_i_i_ic_shift_rt_negative
166 ok( 1, 'shr_i_i_ic (>>) negative OK')
169 ok( 0, 'shr_i_i_ic (>>) negative')
173 .sub test_shl_i_i_i_shift_lt
181 is( $I4, "48", 'shl_i_i_i (<<)' )
182 is( $I2, "48", 'shl_i_i_i (<<)' )
183 is( $I1, "40", 'shl_i_i_i (<<)' )
184 is( $I0, "12", 'shl_i_i_i (<<)' )
187 .sub test_shl_i_i_ic_shift_lt
192 is( $I2, "48", 'shl_i_i_ic (<<)' )
193 is( $I1, "40", 'shl_i_i_ic (<<)' )
194 is( $I0, "12", 'shl_i_i_ic (<<)' )
197 .sub test_shl_i_ic_i_shift_lt
200 shl $I2, 0b001100, $I0
201 shl $I1, 0b010100, $I1
202 is( $I2, "48", 'shl_i_ic_i (<<)' )
203 is( $I1, "40", 'shl_i_ic_i (<<)' )
206 .sub test_shl_i_ic_ic_shift_lt
209 is( $I2, "48", 'shl_i_ic_ic (<<)' )
210 is( $I1, "40", 'shl_i_ic_ic (<<)' )
213 .sub test_shl_i_i_shift_lt
220 is( $I0, "24", 'shl_i_i (<<)' )
221 is( $I1, "80", 'shl_i_i (<<)' )
224 .sub test_bxor_i_i_i_xor
228 is( $I2, "42", 'bxor_i_i_i (^)' )
230 is( $I1, "42", 'bxor_i_i_i (^)' )
231 is( $I0, "12", 'bxor_i_i_i (^)' )
234 .sub test_bxor_i_i_ic_xor
236 bxor $I2, $I0, 0b100110
237 is( $I2, "42", 'bxor_i_i_ic (^)' )
238 is( $I0, "12", 'bxor_i_i_ic (^)' )
239 bxor $I0, $I0, 0b100110
240 is( $I0, "42", 'bxor_i_i_ic (^)' )
243 .sub test_bxor_i_ic_xor
247 is( $I2, "15", 'bxor_i|ic (^)' )
250 is( $I2, "0", 'bxor_i|ic (^)' )
253 is( $I2, "0", 'bxor_i|ic (^)' )
256 is( $I2, "22", 'bxor_i|ic (^)' )
259 .sub test_band_i_i_i_and
263 is( $I2, "4", 'band_i_i_i (&)' )
265 is( $I1, "4", 'band_i_i_i (&)' )
266 is( $I0, "12", 'band_i_i_i (&)' )
269 .sub test_band_i_i_ic_and
271 band $I2, $I0,0b010110
272 is( $I2, "4", 'band_i_i_ic (&)' )
273 is( $I0, "12", 'band_i_i_ic (&)' )
274 band $I0,$I0,0b010110
275 is( $I0, "4", 'band_i_i_ic (&)' )
278 .sub test_band_i_i_ic_and_2
282 is( $I2, "0", 'band_i_i|ic (&)' )
286 is( $I2, "12", 'band_i_i|ic (&)' )
290 is( $I2, "42", 'band_i_i|ic (&)' )
294 is( $I2, "1", 'band_i_i|ic (&)' )
301 is( $I2, "30", 'bor_i_i_i (|)' )
303 is( $I1, "30", 'bor_i_i_i (|)' )
304 is( $I0, "12", 'bor_i_i_i (|)' )
309 bor $I2, $I0,0b010110
310 is( $I2, "30", 'bor_i_i_ic (|)' )
311 is( $I0, "12", 'bor_i_i_ic (|)' )
313 is( $I0, "30", 'bor_i_i_ic (|)' )
316 .sub test_bor_i_i_ic_2
320 is( $I2, "15", 'bor_i_i|ic (|) 2' )
323 is( $I2, "12", 'bor_i_i|ic (|) 2' )
326 is( $I2, "42", 'bor_i_i|ic (|) 2' )
329 is( $I2, "23", 'bor_i_i|ic (|) 2' )
338 is( $I2, "51", 'bnot_i_i (~) 2' )
341 is( $I1, "51", 'bnot_i_i (~) 2' )
342 is( $I0, "12", 'bnot_i_i (~) 2' )
345 .sub test_rot_i_i_ic_ic
346 .include "iglobals.pasm"
347 .local pmc interp # a handle to our interpreter object.
350 config = interp[.IGLOBALS_CONFIG_HASH]
351 .local int intvalsize
352 intvalsize = config['intvalsize']
355 int_bits = intvalsize * 8
359 gt intvalsize, 4, do64bit
361 rot $I1, $I0, 1, 32 # 1 left
362 is( $I1, "24", 'rot_i_i_ic_ic' )
363 rot $I1, $I0, -1, 32 # 1 right
364 is( $I1, "6", 'rot_i_i_ic_ic' )
368 rot $I1, $I0, 1, 64 # 1 left
369 is( $I1, "24", 'rot_i_i_ic_ic' )
370 rot $I1, $I0, -1, 64 # 1 right
371 is( $I1, "6", 'rot_i_i_ic_ic' )
376 ## The PMC shl op will promote Integer to Bigint when needed. We can't stuff a
377 ## BigInt in an I register, but we can produce the same result modulo wordsize.
378 ## [Only we cheat by using the word size minus one, so that we don't have to
379 ## deal with negative numbers. -- rgr, 2-Jun-07.]
380 .sub test_i_reg_shl_and_pmc_shl_are_consistent
382 .include "iglobals.pasm"
383 .local pmc interp # a handle to our interpreter object.
386 config = interp[.IGLOBALS_CONFIG_HASH]
391 skip( 2, 'no BigInt lib found' )
396 ## Figure out the wordsize. We need integer_modulus because assigning a
397 ## too-big BigInt throws an error otherwise.
398 .include 'sysinfo.pasm'
399 .local int i_bytes_per_word, i_bits_per_word_minus_one
400 .local pmc bits_per_word_minus_one, integer_modulus
401 i_bytes_per_word = sysinfo .SYSINFO_PARROT_INTSIZE
402 i_bits_per_word_minus_one = 8 * i_bytes_per_word
403 dec i_bits_per_word_minus_one
404 bits_per_word_minus_one = new 'Integer'
405 bits_per_word_minus_one = i_bits_per_word_minus_one
406 integer_modulus = new 'BigInt'
408 integer_modulus <<= bits_per_word_minus_one
410 ## Test shifting a positive number.
413 test_shift($P0, integer_modulus)
415 ## Test shifting a negative number.
417 test_shift($P0, integer_modulus)
423 .param pmc integer_modulus
431 if $P1 > 100 goto done
432 ## shift number and i_number into $P2 and $I2.
435 shl $I2, i_number, $I1
436 ## compare in I registers.
437 $P3 = mod $P2, integer_modulus
439 if $I2 >= 0 goto pos_check
440 ## The register op gave a negative result, but the modulus will always be
441 ## positive. If the truncated result is correct, then the difference will
442 ## be the most negative INTVAL, which is the only number for which -x==x.
445 if $I4 == $I5 goto ok
448 if $I2 == $I3 goto ok
450 ok( 0, "oops; not ok: " )
462 ## set up for the next one
466 ok( 1, 'finished ok' )
471 # cperl-indent-level: 4
474 # vim: expandtab shiftwidth=4 ft=pir: