vppinfra: table based crc32c for targets without crc32c instructions
[vpp.git] / src / vppinfra / crc32.h
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef __included_crc32_h__
17 #define __included_crc32_h__
18
19 #include <vppinfra/clib.h>
20
21 #if __SSE4_2__
22 #define clib_crc32c_uses_intrinsics
23 #include <x86intrin.h>
24 static_always_inline u32
25 clib_crc32c_u8 (u32 last, u8 data)
26 {
27   return _mm_crc32_u8 (last, data);
28 }
29
30 static_always_inline u32
31 clib_crc32c_u16 (u32 last, u16 data)
32 {
33   return _mm_crc32_u16 (last, data);
34 }
35
36 static_always_inline u32
37 clib_crc32c_u32 (u32 last, u32 data)
38 {
39   return _mm_crc32_u32 (last, data);
40 }
41
42 static_always_inline u32
43 clib_crc32c_u64 (u32 last, u64 data)
44 {
45   return _mm_crc32_u64 (last, data);
46 }
47 #endif
48
49 #if __ARM_FEATURE_CRC32
50 #define clib_crc32c_uses_intrinsics
51 #include <arm_acle.h>
52 static_always_inline u32
53 clib_crc32c_u8 (u32 last, u8 data)
54 {
55   return __crc32cb (last, data);
56 }
57
58 static_always_inline u32
59 clib_crc32c_u16 (u32 last, u16 data)
60 {
61   return __crc32ch (last, data);
62 }
63
64 static_always_inline u32
65 clib_crc32c_u32 (u32 last, u32 data)
66 {
67   return __crc32cw (last, data);
68 }
69
70 static_always_inline u32
71 clib_crc32c_u64 (u32 last, u64 data)
72 {
73   return __crc32cd (last, data);
74 }
75 #endif
76
77 #ifdef clib_crc32c_uses_intrinsics
78 static_always_inline u32
79 clib_crc32c_with_init (u8 *s, int len, u32 last)
80 {
81   for (; len >= 8; len -= 8, s += 8)
82     last = clib_crc32c_u64 (last, *((u64u *) s));
83
84   for (; len >= 4; len -= 4, s += 4)
85     last = clib_crc32c_u32 (last, *((u32u *) s));
86
87   for (; len >= 2; len -= 2, s += 2)
88     last = clib_crc32c_u16 (last, *((u16u *) s));
89
90   for (; len >= 1; len -= 1, s += 1)
91     last = clib_crc32c_u8 (last, *((u8 *) s));
92
93   return last;
94 }
95
96 static_always_inline u32
97 clib_crc32c (u8 *s, int len)
98 {
99   return clib_crc32c_with_init (s, len, 0);
100 }
101 #else
102
103 u32
104 _clib_crc32c (u32 crc, const u8 *p, uword len)
105 {
106   static const u32 clib_crc32c_table[256] = {
107     0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,
108     0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,
109     0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,
110     0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
111     0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,
112     0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,
113     0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,
114     0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
115     0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
116     0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,
117     0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,
118     0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
119     0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,
120     0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,
121     0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,
122     0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
123     0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,
124     0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
125     0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,
126     0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
127     0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,
128     0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,
129     0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,
130     0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
131     0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,
132     0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,
133     0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
134     0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
135     0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,
136     0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,
137     0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,
138     0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
139     0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,
140     0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,
141     0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,
142     0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
143     0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,
144     0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,
145     0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,
146     0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
147     0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,
148     0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,
149     0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,
150     0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
151     0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
152     0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,
153     0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,
154     0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
155     0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,
156     0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,
157     0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,
158     0xAD7D5351L
159   };
160
161   while (len--)
162     crc = (crc >> 8) ^ clib_crc32c_table[(u8) crc ^ p++[0]];
163
164   return crc;
165 }
166
167 u32
168 clib_crc32c (const u8 *p, uword len)
169 {
170   return _clib_crc32c (0, p, len);
171 }
172 #endif
173
174 #endif /* __included_crc32_h__ */
175
176 /*
177  * fd.io coding-style-patch-verification: ON
178  *
179  * Local Variables:
180  * eval: (c-set-style "gnu")
181  * End:
182  */