Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.76 KB | None | 0 0
  1. #include "klee/klee.h"
  2. #include <assert.h>
  3. #include <inttypes.h>
  4. #include <stdio.h>
  5. //types and constants used in the functions below
  6.  
  7. const uint64_t m1 = 0x5555555555555555; //binary: 0101...
  8. const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
  9. const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
  10. const uint64_t m8 = 0x00ff00ff00ff00ff; //binary: 8 zeros, 8 ones ...
  11. const uint64_t m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
  12. const uint64_t m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
  13. const uint64_t hff = 0xffffffffffffffff; //binary: all ones
  14. const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
  15.  
  16. //This is a naive implementation, shown for comparison,
  17. //and to help in understanding the better functions.
  18. //It uses 24 arithmetic operations (shift, add, and).
  19. int popcount_1(uint64_t x) {
  20. x = (x & m1 ) + ((x >> 1) & m1 ); //put count of each 2 bits into those 2 bits
  21. x = (x & m2 ) + ((x >> 2) & m2 ); //put count of each 4 bits into those 4 bits
  22. x = (x & m4 ) + ((x >> 4) & m4 ); //put count of each 8 bits into those 8 bits
  23. x = (x & m8 ) + ((x >> 8) & m8 ); //put count of each 16 bits into those 16 bits
  24. x = (x & m16) + ((x >> 16) & m16); //put count of each 32 bits into those 32 bits
  25. x = (x & m32) + ((x >> 32) & m32); //put count of each 64 bits into those 64 bits
  26. return x;
  27. }
  28.  
  29. //This uses fewer arithmetic operations than any other known
  30. //implementation on machines with slow multiplication.
  31. //It uses 17 arithmetic operations.
  32. int popcount_2(uint64_t x) {
  33. x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
  34. x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
  35. x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
  36. x += x >> 8; //put count of each 16 bits into their lowest 8 bits
  37. x += x >> 16; //put count of each 32 bits into their lowest 8 bits
  38. x += x >> 32; //put count of each 64 bits into their lowest 8 bits
  39. return x & 0x7f;
  40. }
  41.  
  42. //This uses fewer arithmetic operations than any other known
  43. //implementation on machines with fast multiplication.
  44. //It uses 12 arithmetic operations, one of which is a multiply.
  45. int popcount_3(uint64_t x) {
  46. x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits
  47. x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
  48. x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits
  49. return (x * h01)>>56; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
  50. }
  51.  
  52. int main() {
  53. uint64_t x = 0;
  54. uint32_t choice = 0;
  55. klee_make_symbolic(&x, sizeof(uint64_t), "x");
  56. klee_make_symbolic(&choice, sizeof(uint32_t), "choice");
  57.  
  58. klee_assume(choice < 6);
  59.  
  60. uint64_t result0 = 0;
  61. uint64_t result1 = 0;
  62. // To prove all are equivalent execution is all orders must be tried.
  63. switch (choice) {
  64. case 0:
  65. printf("Trying combination 0\n");
  66. result0 = popcount_1(x);
  67. result1 = popcount_2(x);
  68. break;
  69. case 1:
  70. printf("Trying combination 1\n");
  71. result0 = popcount_1(x);
  72. result1 = popcount_3(x);
  73. break;
  74. case 2:
  75. printf("Trying combination 2\n");
  76. result0 = popcount_2(x);
  77. result1 = popcount_1(x);
  78. break;
  79. case 3:
  80. printf("Trying combination 3\n");
  81. result0 = popcount_2(x);
  82. result1 = popcount_3(x);
  83. break;
  84. case 4:
  85. printf("Trying combination 4\n");
  86. result0 = popcount_3(x);
  87. result1 = popcount_1(x);
  88. break;
  89. case 5:
  90. printf("Trying combination 5\n");
  91. result0 = popcount_3(x);
  92. result1 = popcount_2(x);
  93. break;
  94. default:
  95. assert(0 && "unreachable");
  96. }
  97.  
  98. assert(result0 == result1 && "Not equivalent");
  99. return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement