InstructionsTest.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <folly/experimental/Instructions.h>
  17. #include <glog/logging.h>
  18. #include <folly/portability/GTest.h>
  19. using namespace folly;
  20. using namespace folly::compression::instructions;
  21. TEST(Instructions, BitExtraction) {
  22. uint64_t value =
  23. 0b11111110'11011100'10111010'10011000'01110110'01010100'00110010'00010000;
  24. if (not Haswell::supported()) {
  25. return;
  26. }
  27. LOG(INFO) << "Testing Haswell on supported machine";
  28. // Extract 4 bits a time, starting from bit 0
  29. uint64_t expected = 0;
  30. for (int i = 0; i < 64 - 4; i += 4) {
  31. EXPECT_EQ(expected, Default::bextr(value, i, 4));
  32. EXPECT_EQ(expected, Haswell::bextr(value, i, 4));
  33. ++expected;
  34. }
  35. // Extract 8 bits a time, starting from bit 1
  36. uint64_t value2 = value << 1;
  37. uint64_t lower = 0;
  38. uint64_t upper = 1;
  39. for (int i = 1; i < 64 - 8; i += 4) {
  40. expected = (lower & 0xF) | ((upper & 0xF) << 4);
  41. EXPECT_EQ(expected, Default::bextr(value2, i, 8));
  42. EXPECT_EQ(expected, Haswell::bextr(value2, i, 8));
  43. ++lower;
  44. ++upper;
  45. }
  46. // Extract 16 bits a time, starting from bit 2
  47. uint64_t value3 = value << 2;
  48. uint64_t part0 = 0;
  49. uint64_t part1 = 1;
  50. uint64_t part2 = 2;
  51. uint64_t part3 = 3;
  52. for (int i = 2; i < 64 - 16; i += 4) {
  53. expected = (part0 & 0xF) | ((part1 & 0xF) << 4) | ((part2 & 0xF) << 8) |
  54. ((part3 & 0xF) << 12);
  55. EXPECT_EQ(expected, Default::bextr(value3, i, 16));
  56. EXPECT_EQ(expected, Haswell::bextr(value3, i, 16));
  57. ++part0;
  58. ++part1;
  59. ++part2;
  60. ++part3;
  61. }
  62. // Extract 32 bits
  63. expected = 0b1011'1010'1001'1000'0111'0110'0101'0100;
  64. EXPECT_EQ(expected, Default::bextr(value, 16, 32));
  65. EXPECT_EQ(expected, Haswell::bextr(value, 16, 32));
  66. // Extract all 64 bits
  67. EXPECT_EQ(value, Default::bextr(value, 0, 64));
  68. EXPECT_EQ(value, Haswell::bextr(value, 0, 64));
  69. // Extract 0 bits
  70. EXPECT_EQ(0, Default::bextr(value, 4, 0));
  71. EXPECT_EQ(0, Haswell::bextr(value, 4, 0));
  72. // Make sure only up to 63-th bits will be extracted
  73. EXPECT_EQ(0b1111, Default::bextr(value, 60, 5));
  74. EXPECT_EQ(0b1111, Haswell::bextr(value, 60, 5));
  75. EXPECT_EQ(0, Default::bextr(value, 64, 8));
  76. EXPECT_EQ(0, Haswell::bextr(value, 64, 8));
  77. EXPECT_EQ(value, Default::bextr(value, 0, 65));
  78. EXPECT_EQ(value, Haswell::bextr(value, 0, 65));
  79. }