Fix m 60 a 0 by making modified variable non-const
[hashcat.git] / OpenCL / inc_rp.cl
1 /**
2  * Authors.....: Jens Steube <jens.steube@gmail.com>
3  *               magnum <john.magnum@hushmail.com>
4  *
5  * License.....: MIT
6  */
7
8 inline u32  apply_rule (const u32 name, const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len);
9 inline u32  apply_rules (const __global u32 *cmds, u32 buf0[4], u32 buf1[4], const u32 len);
10 inline u32x apply_rules_vect (const u32 pw_buf0[4], const u32 pw_buf1[4], const u32 pw_len, const __global kernel_rule_t *rules_buf, const u32 il_pos, u32x w0[4], u32x w1[4]);
11
12 inline u32 generate_cmask (u32 buf)
13 {
14   const u32 rmask = ((buf & 0x40404040) >> 1)
15                  & ~((buf & 0x80808080) >> 2);
16
17   const u32 hmask = (buf & 0x1f1f1f1f) + 0x05050505;
18   const u32 lmask = (buf & 0x1f1f1f1f) + 0x1f1f1f1f;
19
20   return rmask & ~hmask & lmask;
21 }
22
23 inline void truncate_right (u32 w0[4], u32 w1[4], const u32 len)
24 {
25   const u32 tmp = (1 << ((len % 4) * 8)) - 1;
26
27   switch (len / 4)
28   {
29     case  0:  w0[0] &= tmp;
30               w0[1]  = 0;
31               w0[2]  = 0;
32               w0[3]  = 0;
33               w1[0]  = 0;
34               w1[1]  = 0;
35               w1[2]  = 0;
36               w1[3]  = 0;
37               break;
38     case  1:  w0[1] &= tmp;
39               w0[2]  = 0;
40               w0[3]  = 0;
41               w1[0]  = 0;
42               w1[1]  = 0;
43               w1[2]  = 0;
44               w1[3]  = 0;
45               break;
46     case  2:  w0[2] &= tmp;
47               w0[3]  = 0;
48               w1[0]  = 0;
49               w1[1]  = 0;
50               w1[2]  = 0;
51               w1[3]  = 0;
52               break;
53     case  3:  w0[3] &= tmp;
54               w1[0]  = 0;
55               w1[1]  = 0;
56               w1[2]  = 0;
57               w1[3]  = 0;
58               break;
59     case  4:  w1[0] &= tmp;
60               w1[1]  = 0;
61               w1[2]  = 0;
62               w1[3]  = 0;
63               break;
64     case  5:  w1[1] &= tmp;
65               w1[2]  = 0;
66               w1[3]  = 0;
67               break;
68     case  6:  w1[2] &= tmp;
69               w1[3]  = 0;
70               break;
71     case  7:  w1[3] &= tmp;
72               break;
73   }
74 }
75
76 inline void truncate_left (u32 w0[4], u32 w1[4], const u32 len)
77 {
78   const u32 tmp = ~((1 << ((len % 4) * 8)) - 1);
79
80   switch (len / 4)
81   {
82     case  0:  w0[0] &= tmp;
83               break;
84     case  1:  w0[0]  = 0;
85               w0[1] &= tmp;
86               break;
87     case  2:  w0[0]  = 0;
88               w0[1]  = 0;
89               w0[2] &= tmp;
90               break;
91     case  3:  w0[0]  = 0;
92               w0[1]  = 0;
93               w0[2]  = 0;
94               w0[3] &= tmp;
95               break;
96     case  4:  w0[0]  = 0;
97               w0[1]  = 0;
98               w0[2]  = 0;
99               w0[3]  = 0;
100               w1[0] &= tmp;
101               break;
102     case  5:  w0[0]  = 0;
103               w0[1]  = 0;
104               w0[2]  = 0;
105               w0[3]  = 0;
106               w1[0]  = 0;
107               w1[1] &= tmp;
108               break;
109     case  6:  w0[0]  = 0;
110               w0[1]  = 0;
111               w0[2]  = 0;
112               w0[3]  = 0;
113               w1[0]  = 0;
114               w1[1]  = 0;
115               w1[2] &= tmp;
116               break;
117     case  7:  w0[0]  = 0;
118               w0[1]  = 0;
119               w0[2]  = 0;
120               w0[3]  = 0;
121               w1[0]  = 0;
122               w1[1]  = 0;
123               w1[2]  = 0;
124               w1[3] &= tmp;
125               break;
126   }
127 }
128
129 inline void lshift_block (const u32 in0[4], const u32 in1[4], u32 out0[4], u32 out1[4])
130 {
131   out0[0] = amd_bytealign_S (in0[1], in0[0], 1);
132   out0[1] = amd_bytealign_S (in0[2], in0[1], 1);
133   out0[2] = amd_bytealign_S (in0[3], in0[2], 1);
134   out0[3] = amd_bytealign_S (in1[0], in0[3], 1);
135   out1[0] = amd_bytealign_S (in1[1], in1[0], 1);
136   out1[1] = amd_bytealign_S (in1[2], in1[1], 1);
137   out1[2] = amd_bytealign_S (in1[3], in1[2], 1);
138   out1[3] = amd_bytealign_S (     0, in1[3], 1);
139 }
140
141 inline void rshift_block (const u32 in0[4], const u32 in1[4], u32 out0[4], u32 out1[4])
142 {
143   out1[3] = amd_bytealign_S (in1[3], in1[2], 3);
144   out1[2] = amd_bytealign_S (in1[2], in1[1], 3);
145   out1[1] = amd_bytealign_S (in1[1], in1[0], 3);
146   out1[0] = amd_bytealign_S (in1[0], in0[3], 3);
147   out0[3] = amd_bytealign_S (in0[3], in0[2], 3);
148   out0[2] = amd_bytealign_S (in0[2], in0[1], 3);
149   out0[1] = amd_bytealign_S (in0[1], in0[0], 3);
150   out0[0] = amd_bytealign_S (in0[0],      0, 3);
151 }
152
153 inline void lshift_block_N (const u32 in0[4], const u32 in1[4], u32 out0[4], u32 out1[4], const u32 num)
154 {
155   switch (num)
156   {
157     case  0:  out0[0] = in0[0];
158               out0[1] = in0[1];
159               out0[2] = in0[2];
160               out0[3] = in0[3];
161               out1[0] = in1[0];
162               out1[1] = in1[1];
163               out1[2] = in1[2];
164               out1[3] = in1[3];
165               break;
166     case  1:  out0[0] = amd_bytealign_S (in0[1], in0[0], 1);
167               out0[1] = amd_bytealign_S (in0[2], in0[1], 1);
168               out0[2] = amd_bytealign_S (in0[3], in0[2], 1);
169               out0[3] = amd_bytealign_S (in1[0], in0[3], 1);
170               out1[0] = amd_bytealign_S (in1[1], in1[0], 1);
171               out1[1] = amd_bytealign_S (in1[2], in1[1], 1);
172               out1[2] = amd_bytealign_S (in1[3], in1[2], 1);
173               out1[3] = amd_bytealign_S (     0, in1[3], 1);
174               break;
175     case  2:  out0[0] = amd_bytealign_S (in0[1], in0[0], 2);
176               out0[1] = amd_bytealign_S (in0[2], in0[1], 2);
177               out0[2] = amd_bytealign_S (in0[3], in0[2], 2);
178               out0[3] = amd_bytealign_S (in1[0], in0[3], 2);
179               out1[0] = amd_bytealign_S (in1[1], in1[0], 2);
180               out1[1] = amd_bytealign_S (in1[2], in1[1], 2);
181               out1[2] = amd_bytealign_S (in1[3], in1[2], 2);
182               out1[3] = amd_bytealign_S (     0, in1[3], 2);
183               break;
184     case  3:  out0[0] = amd_bytealign_S (in0[1], in0[0], 3);
185               out0[1] = amd_bytealign_S (in0[2], in0[1], 3);
186               out0[2] = amd_bytealign_S (in0[3], in0[2], 3);
187               out0[3] = amd_bytealign_S (in1[0], in0[3], 3);
188               out1[0] = amd_bytealign_S (in1[1], in1[0], 3);
189               out1[1] = amd_bytealign_S (in1[2], in1[1], 3);
190               out1[2] = amd_bytealign_S (in1[3], in1[2], 3);
191               out1[3] = amd_bytealign_S (     0, in1[3], 3);
192               break;
193     case  4:  out0[0] = in0[1];
194               out0[1] = in0[2];
195               out0[2] = in0[3];
196               out0[3] = in1[0];
197               out1[0] = in1[1];
198               out1[1] = in1[2];
199               out1[2] = in1[3];
200               out1[3] = 0;
201               break;
202     case  5:  out0[0] = amd_bytealign_S (in0[2], in0[1], 1);
203               out0[1] = amd_bytealign_S (in0[3], in0[2], 1);
204               out0[2] = amd_bytealign_S (in1[0], in0[3], 1);
205               out0[3] = amd_bytealign_S (in1[1], in1[0], 1);
206               out1[0] = amd_bytealign_S (in1[2], in1[1], 1);
207               out1[1] = amd_bytealign_S (in1[3], in1[2], 1);
208               out1[2] = amd_bytealign_S (     0, in1[3], 1);
209               out1[3] = 0;
210               break;
211     case  6:  out0[0] = amd_bytealign_S (in0[2], in0[1], 2);
212               out0[1] = amd_bytealign_S (in0[3], in0[2], 2);
213               out0[2] = amd_bytealign_S (in1[0], in0[3], 2);
214               out0[3] = amd_bytealign_S (in1[1], in1[0], 2);
215               out1[0] = amd_bytealign_S (in1[2], in1[1], 2);
216               out1[1] = amd_bytealign_S (in1[3], in1[2], 2);
217               out1[2] = amd_bytealign_S (     0, in1[3], 2);
218               out1[3] = 0;
219               break;
220     case  7:  out0[0] = amd_bytealign_S (in0[2], in0[1], 3);
221               out0[1] = amd_bytealign_S (in0[3], in0[2], 3);
222               out0[2] = amd_bytealign_S (in1[0], in0[3], 3);
223               out0[3] = amd_bytealign_S (in1[1], in1[0], 3);
224               out1[0] = amd_bytealign_S (in1[2], in1[1], 3);
225               out1[1] = amd_bytealign_S (in1[3], in1[2], 3);
226               out1[2] = amd_bytealign_S (     0, in1[3], 3);
227               out1[3] = 0;
228               break;
229     case  8:  out0[0] = in0[2];
230               out0[1] = in0[3];
231               out0[2] = in1[0];
232               out0[3] = in1[1];
233               out1[0] = in1[2];
234               out1[1] = in1[3];
235               out1[2] = 0;
236               out1[3] = 0;
237               break;
238     case  9:  out0[0] = amd_bytealign_S (in0[3], in0[2], 1);
239               out0[1] = amd_bytealign_S (in1[0], in0[3], 1);
240               out0[2] = amd_bytealign_S (in1[1], in1[0], 1);
241               out0[3] = amd_bytealign_S (in1[2], in1[1], 1);
242               out1[0] = amd_bytealign_S (in1[3], in1[2], 1);
243               out1[1] = amd_bytealign_S (     0, in1[3], 1);
244               out1[2] = 0;
245               out1[3] = 0;
246               break;
247     case 10:  out0[0] = amd_bytealign_S (in0[3], in0[2], 2);
248               out0[1] = amd_bytealign_S (in1[0], in0[3], 2);
249               out0[2] = amd_bytealign_S (in1[1], in1[0], 2);
250               out0[3] = amd_bytealign_S (in1[2], in1[1], 2);
251               out1[0] = amd_bytealign_S (in1[3], in1[2], 2);
252               out1[1] = amd_bytealign_S (     0, in1[3], 2);
253               out1[2] = 0;
254               out1[3] = 0;
255               break;
256     case 11:  out0[0] = amd_bytealign_S (in0[3], in0[2], 3);
257               out0[1] = amd_bytealign_S (in1[0], in0[3], 3);
258               out0[2] = amd_bytealign_S (in1[1], in1[0], 3);
259               out0[3] = amd_bytealign_S (in1[2], in1[1], 3);
260               out1[0] = amd_bytealign_S (in1[3], in1[2], 3);
261               out1[1] = amd_bytealign_S (     0, in1[3], 3);
262               out1[2] = 0;
263               out1[3] = 0;
264               break;
265     case 12:  out0[0] = in0[3];
266               out0[1] = in1[0];
267               out0[2] = in1[1];
268               out0[3] = in1[2];
269               out1[0] = in1[3];
270               out1[1] = 0;
271               out1[2] = 0;
272               out1[3] = 0;
273               break;
274     case 13:  out0[0] = amd_bytealign_S (in1[0], in0[3], 1);
275               out0[1] = amd_bytealign_S (in1[1], in1[0], 1);
276               out0[2] = amd_bytealign_S (in1[2], in1[1], 1);
277               out0[3] = amd_bytealign_S (in1[3], in1[2], 1);
278               out1[0] = amd_bytealign_S (     0, in1[3], 1);
279               out1[1] = 0;
280               out1[2] = 0;
281               out1[3] = 0;
282               break;
283     case 14:  out0[0] = amd_bytealign_S (in1[0], in0[3], 2);
284               out0[1] = amd_bytealign_S (in1[1], in1[0], 2);
285               out0[2] = amd_bytealign_S (in1[2], in1[1], 2);
286               out0[3] = amd_bytealign_S (in1[3], in1[2], 2);
287               out1[0] = amd_bytealign_S (     0, in1[3], 2);
288               out1[1] = 0;
289               out1[2] = 0;
290               out1[3] = 0;
291               break;
292     case 15:  out0[0] = amd_bytealign_S (in1[0], in0[3], 3);
293               out0[1] = amd_bytealign_S (in1[1], in1[0], 3);
294               out0[2] = amd_bytealign_S (in1[2], in1[1], 3);
295               out0[3] = amd_bytealign_S (in1[3], in1[2], 3);
296               out1[0] = amd_bytealign_S (     0, in1[3], 3);
297               out1[1] = 0;
298               out1[2] = 0;
299               out1[3] = 0;
300               break;
301     case 16:  out0[0] = in1[0];
302               out0[1] = in1[1];
303               out0[2] = in1[2];
304               out0[3] = in1[3];
305               out1[0] = 0;
306               out1[1] = 0;
307               out1[2] = 0;
308               out1[3] = 0;
309               break;
310     case 17:  out0[0] = amd_bytealign_S (in1[1], in1[0], 1);
311               out0[1] = amd_bytealign_S (in1[2], in1[1], 1);
312               out0[2] = amd_bytealign_S (in1[3], in1[2], 1);
313               out0[3] = amd_bytealign_S (     0, in1[3], 1);
314               out1[0] = 0;
315               out1[1] = 0;
316               out1[2] = 0;
317               out1[3] = 0;
318               break;
319     case 18:  out0[0] = amd_bytealign_S (in1[1], in1[0], 2);
320               out0[1] = amd_bytealign_S (in1[2], in1[1], 2);
321               out0[2] = amd_bytealign_S (in1[3], in1[2], 2);
322               out0[3] = amd_bytealign_S (     0, in1[3], 2);
323               out1[0] = 0;
324               out1[1] = 0;
325               out1[2] = 0;
326               out1[3] = 0;
327               break;
328     case 19:  out0[0] = amd_bytealign_S (in1[1], in1[0], 3);
329               out0[1] = amd_bytealign_S (in1[2], in1[1], 3);
330               out0[2] = amd_bytealign_S (in1[3], in1[2], 3);
331               out0[3] = amd_bytealign_S (     0, in1[3], 3);
332               out1[0] = 0;
333               out1[1] = 0;
334               out1[2] = 0;
335               out1[3] = 0;
336               break;
337     case 20:  out0[0] = in1[1];
338               out0[1] = in1[2];
339               out0[2] = in1[3];
340               out0[3] = 0;
341               out1[0] = 0;
342               out1[1] = 0;
343               out1[2] = 0;
344               out1[3] = 0;
345               break;
346     case 21:  out0[0] = amd_bytealign_S (in1[2], in1[1], 1);
347               out0[1] = amd_bytealign_S (in1[3], in1[2], 1);
348               out0[2] = amd_bytealign_S (     0, in1[3], 1);
349               out0[3] = 0;
350               out1[0] = 0;
351               out1[1] = 0;
352               out1[2] = 0;
353               out1[3] = 0;
354               break;
355     case 22:  out0[0] = amd_bytealign_S (in1[2], in1[1], 2);
356               out0[1] = amd_bytealign_S (in1[3], in1[2], 2);
357               out0[2] = amd_bytealign_S (     0, in1[3], 2);
358               out0[3] = 0;
359               out1[0] = 0;
360               out1[1] = 0;
361               out1[2] = 0;
362               out1[3] = 0;
363               break;
364     case 23:  out0[0] = amd_bytealign_S (in1[2], in1[1], 3);
365               out0[1] = amd_bytealign_S (in1[3], in1[2], 3);
366               out0[2] = amd_bytealign_S (     0, in1[3], 3);
367               out0[3] = 0;
368               out1[0] = 0;
369               out1[1] = 0;
370               out1[2] = 0;
371               out1[3] = 0;
372               break;
373     case 24:  out0[0] = in1[2];
374               out0[1] = in1[3];
375               out0[2] = 0;
376               out0[3] = 0;
377               out1[0] = 0;
378               out1[1] = 0;
379               out1[2] = 0;
380               out1[3] = 0;
381               break;
382     case 25:  out0[0] = amd_bytealign_S (in1[3], in1[2], 1);
383               out0[1] = amd_bytealign_S (     0, in1[3], 1);
384               out0[2] = 0;
385               out0[3] = 0;
386               out1[0] = 0;
387               out1[1] = 0;
388               out1[2] = 0;
389               out1[3] = 0;
390               break;
391     case 26:  out0[0] = amd_bytealign_S (in1[3], in1[2], 2);
392               out0[1] = amd_bytealign_S (     0, in1[3], 2);
393               out0[2] = 0;
394               out0[3] = 0;
395               out1[0] = 0;
396               out1[1] = 0;
397               out1[2] = 0;
398               out1[3] = 0;
399               break;
400     case 27:  out0[0] = amd_bytealign_S (in1[3], in1[2], 3);
401               out0[1] = amd_bytealign_S (     0, in1[3], 3);
402               out0[2] = 0;
403               out0[3] = 0;
404               out1[0] = 0;
405               out1[1] = 0;
406               out1[2] = 0;
407               out1[3] = 0;
408               break;
409     case 28:  out0[0] = in1[3];
410               out0[1] = 0;
411               out0[2] = 0;
412               out0[3] = 0;
413               out1[0] = 0;
414               out1[1] = 0;
415               out1[2] = 0;
416               out1[3] = 0;
417               break;
418     case 29:  out0[0] = amd_bytealign_S (     0, in1[3], 1);
419               out0[1] = 0;
420               out0[2] = 0;
421               out0[3] = 0;
422               out1[0] = 0;
423               out1[1] = 0;
424               out1[2] = 0;
425               out1[3] = 0;
426               break;
427     case 30:  out0[0] = amd_bytealign_S (     0, in1[3], 2);
428               out0[1] = 0;
429               out0[2] = 0;
430               out0[3] = 0;
431               out1[0] = 0;
432               out1[1] = 0;
433               out1[2] = 0;
434               out1[3] = 0;
435               break;
436     case 31:  out0[0] = amd_bytealign_S (     0, in1[3], 3);
437               out0[1] = 0;
438               out0[2] = 0;
439               out0[3] = 0;
440               out1[0] = 0;
441               out1[1] = 0;
442               out1[2] = 0;
443               out1[3] = 0;
444               break;
445   }
446 }
447
448 inline void rshift_block_N (const u32 in0[4], const u32 in1[4], u32 out0[4], u32 out1[4], const u32 num)
449 {
450   switch (num)
451   {
452     case  0:  out1[3] = in1[3];
453               out1[2] = in1[2];
454               out1[1] = in1[1];
455               out1[0] = in1[0];
456               out0[3] = in0[3];
457               out0[2] = in0[2];
458               out0[1] = in0[1];
459               out0[0] = in0[0];
460               break;
461     case  1:  out1[3] = amd_bytealign_S (in1[3], in1[2], 3);
462               out1[2] = amd_bytealign_S (in1[2], in1[1], 3);
463               out1[1] = amd_bytealign_S (in1[1], in1[0], 3);
464               out1[0] = amd_bytealign_S (in1[0], in0[3], 3);
465               out0[3] = amd_bytealign_S (in0[3], in0[2], 3);
466               out0[2] = amd_bytealign_S (in0[2], in0[1], 3);
467               out0[1] = amd_bytealign_S (in0[1], in0[0], 3);
468               out0[0] = amd_bytealign_S (in0[0],      0, 3);
469               break;
470     case  2:  out1[3] = amd_bytealign_S (in1[3], in1[2], 2);
471               out1[2] = amd_bytealign_S (in1[2], in1[1], 2);
472               out1[1] = amd_bytealign_S (in1[1], in1[0], 2);
473               out1[0] = amd_bytealign_S (in1[0], in0[3], 2);
474               out0[3] = amd_bytealign_S (in0[3], in0[2], 2);
475               out0[2] = amd_bytealign_S (in0[2], in0[1], 2);
476               out0[1] = amd_bytealign_S (in0[1], in0[0], 2);
477               out0[0] = amd_bytealign_S (in0[0],      0, 2);
478               break;
479     case  3:  out1[3] = amd_bytealign_S (in1[3], in1[2], 1);
480               out1[2] = amd_bytealign_S (in1[2], in1[1], 1);
481               out1[1] = amd_bytealign_S (in1[1], in1[0], 1);
482               out1[0] = amd_bytealign_S (in1[0], in0[3], 1);
483               out0[3] = amd_bytealign_S (in0[3], in0[2], 1);
484               out0[2] = amd_bytealign_S (in0[2], in0[1], 1);
485               out0[1] = amd_bytealign_S (in0[1], in0[0], 1);
486               out0[0] = amd_bytealign_S (in0[0],      0, 1);
487               break;
488     case  4:  out1[3] = in1[2];
489               out1[2] = in1[1];
490               out1[1] = in1[0];
491               out1[0] = in0[3];
492               out0[3] = in0[2];
493               out0[2] = in0[1];
494               out0[1] = in0[0];
495               out0[0] = 0;
496               break;
497     case  5:  out1[3] = amd_bytealign_S (in1[2], in1[1], 3);
498               out1[2] = amd_bytealign_S (in1[1], in1[0], 3);
499               out1[1] = amd_bytealign_S (in1[0], in0[3], 3);
500               out1[0] = amd_bytealign_S (in0[3], in0[2], 3);
501               out0[3] = amd_bytealign_S (in0[2], in0[1], 3);
502               out0[2] = amd_bytealign_S (in0[1], in0[0], 3);
503               out0[1] = amd_bytealign_S (in0[0],      0, 3);
504               out0[0] = 0;
505               break;
506     case  6:  out1[3] = amd_bytealign_S (in1[2], in1[1], 2);
507               out1[2] = amd_bytealign_S (in1[1], in1[0], 2);
508               out1[1] = amd_bytealign_S (in1[0], in0[3], 2);
509               out1[0] = amd_bytealign_S (in0[3], in0[2], 2);
510               out0[3] = amd_bytealign_S (in0[2], in0[1], 2);
511               out0[2] = amd_bytealign_S (in0[1], in0[0], 2);
512               out0[1] = amd_bytealign_S (in0[0],      0, 2);
513               out0[0] = 0;
514               break;
515     case  7:  out1[3] = amd_bytealign_S (in1[2], in1[1], 1);
516               out1[2] = amd_bytealign_S (in1[1], in1[0], 1);
517               out1[1] = amd_bytealign_S (in1[0], in0[3], 1);
518               out1[0] = amd_bytealign_S (in0[3], in0[2], 1);
519               out0[3] = amd_bytealign_S (in0[2], in0[1], 1);
520               out0[2] = amd_bytealign_S (in0[1], in0[0], 1);
521               out0[1] = amd_bytealign_S (in0[0],      0, 1);
522               out0[0] = 0;
523               break;
524     case  8:  out1[3] = in1[1];
525               out1[2] = in1[0];
526               out1[1] = in0[3];
527               out1[0] = in0[2];
528               out0[3] = in0[1];
529               out0[2] = in0[0];
530               out0[1] = 0;
531               out0[0] = 0;
532               break;
533     case  9:  out1[3] = amd_bytealign_S (in1[1], in1[0], 3);
534               out1[2] = amd_bytealign_S (in1[0], in0[3], 3);
535               out1[1] = amd_bytealign_S (in0[3], in0[2], 3);
536               out1[0] = amd_bytealign_S (in0[2], in0[1], 3);
537               out0[3] = amd_bytealign_S (in0[1], in0[0], 3);
538               out0[2] = amd_bytealign_S (in0[0],      0, 3);
539               out0[1] = 0;
540               out0[0] = 0;
541               break;
542     case 10:  out1[3] = amd_bytealign_S (in1[1], in1[0], 2);
543               out1[2] = amd_bytealign_S (in1[0], in0[3], 2);
544               out1[1] = amd_bytealign_S (in0[3], in0[2], 2);
545               out1[0] = amd_bytealign_S (in0[2], in0[1], 2);
546               out0[3] = amd_bytealign_S (in0[1], in0[0], 2);
547               out0[2] = amd_bytealign_S (in0[0],      0, 2);
548               out0[1] = 0;
549               out0[0] = 0;
550               break;
551     case 11:  out1[3] = amd_bytealign_S (in1[1], in1[0], 1);
552               out1[2] = amd_bytealign_S (in1[0], in0[3], 1);
553               out1[1] = amd_bytealign_S (in0[3], in0[2], 1);
554               out1[0] = amd_bytealign_S (in0[2], in0[1], 1);
555               out0[3] = amd_bytealign_S (in0[1], in0[0], 1);
556               out0[2] = amd_bytealign_S (in0[0],      0, 1);
557               out0[1] = 0;
558               out0[0] = 0;
559               break;
560     case 12:  out1[3] = in1[0];
561               out1[2] = in0[3];
562               out1[1] = in0[2];
563               out1[0] = in0[1];
564               out0[3] = in0[0];
565               out0[2] = 0;
566               out0[1] = 0;
567               out0[0] = 0;
568               break;
569     case 13:  out1[3] = amd_bytealign_S (in1[0], in0[3], 3);
570               out1[2] = amd_bytealign_S (in0[3], in0[2], 3);
571               out1[1] = amd_bytealign_S (in0[2], in0[1], 3);
572               out1[0] = amd_bytealign_S (in0[1], in0[0], 3);
573               out0[3] = amd_bytealign_S (in0[0],      0, 3);
574               out0[2] = 0;
575               out0[1] = 0;
576               out0[0] = 0;
577               break;
578     case 14:  out1[3] = amd_bytealign_S (in1[0], in0[3], 2);
579               out1[2] = amd_bytealign_S (in0[3], in0[2], 2);
580               out1[1] = amd_bytealign_S (in0[2], in0[1], 2);
581               out1[0] = amd_bytealign_S (in0[1], in0[0], 2);
582               out0[3] = amd_bytealign_S (in0[0],      0, 2);
583               out0[2] = 0;
584               out0[1] = 0;
585               out0[0] = 0;
586               break;
587     case 15:  out1[3] = amd_bytealign_S (in1[0], in0[3], 1);
588               out1[2] = amd_bytealign_S (in0[3], in0[2], 1);
589               out1[1] = amd_bytealign_S (in0[2], in0[1], 1);
590               out1[0] = amd_bytealign_S (in0[1], in0[0], 1);
591               out0[3] = amd_bytealign_S (in0[0],      0, 1);
592               out0[2] = 0;
593               out0[1] = 0;
594               out0[0] = 0;
595               break;
596     case 16:  out1[3] = in0[3];
597               out1[2] = in0[2];
598               out1[1] = in0[1];
599               out1[0] = in0[0];
600               out0[3] = 0;
601               out0[2] = 0;
602               out0[1] = 0;
603               out0[0] = 0;
604               break;
605     case 17:  out1[3] = amd_bytealign_S (in0[3], in0[2], 3);
606               out1[2] = amd_bytealign_S (in0[2], in0[1], 3);
607               out1[1] = amd_bytealign_S (in0[1], in0[0], 3);
608               out1[0] = amd_bytealign_S (in0[0],      0, 3);
609               out0[3] = 0;
610               out0[2] = 0;
611               out0[1] = 0;
612               out0[0] = 0;
613               break;
614     case 18:  out1[3] = amd_bytealign_S (in0[3], in0[2], 2);
615               out1[2] = amd_bytealign_S (in0[2], in0[1], 2);
616               out1[1] = amd_bytealign_S (in0[1], in0[0], 2);
617               out1[0] = amd_bytealign_S (in0[0],      0, 2);
618               out0[3] = 0;
619               out0[2] = 0;
620               out0[1] = 0;
621               out0[0] = 0;
622               break;
623     case 19:  out1[3] = amd_bytealign_S (in0[3], in0[2], 1);
624               out1[2] = amd_bytealign_S (in0[2], in0[1], 1);
625               out1[1] = amd_bytealign_S (in0[1], in0[0], 1);
626               out1[0] = amd_bytealign_S (in0[0],      0, 1);
627               out0[3] = 0;
628               out0[2] = 0;
629               out0[1] = 0;
630               out0[0] = 0;
631               break;
632     case 20:  out1[3] = in0[2];
633               out1[2] = in0[1];
634               out1[1] = in0[0];
635               out1[0] = 0;
636               out0[3] = 0;
637               out0[2] = 0;
638               out0[1] = 0;
639               out0[0] = 0;
640               break;
641     case 21:  out1[3] = amd_bytealign_S (in0[2], in0[1], 3);
642               out1[2] = amd_bytealign_S (in0[1], in0[0], 3);
643               out1[1] = amd_bytealign_S (in0[0],      0, 3);
644               out1[0] = 0;
645               out0[3] = 0;
646               out0[2] = 0;
647               out0[1] = 0;
648               out0[0] = 0;
649               break;
650     case 22:  out1[3] = amd_bytealign_S (in0[2], in0[1], 2);
651               out1[2] = amd_bytealign_S (in0[1], in0[0], 2);
652               out1[1] = amd_bytealign_S (in0[0],      0, 2);
653               out1[0] = 0;
654               out0[3] = 0;
655               out0[2] = 0;
656               out0[1] = 0;
657               out0[0] = 0;
658               break;
659     case 23:  out1[3] = amd_bytealign_S (in0[2], in0[1], 1);
660               out1[2] = amd_bytealign_S (in0[1], in0[0], 1);
661               out1[1] = amd_bytealign_S (in0[0],      0, 1);
662               out1[0] = 0;
663               out0[3] = 0;
664               out0[2] = 0;
665               out0[1] = 0;
666               out0[0] = 0;
667               break;
668     case 24:  out1[3] = in0[1];
669               out1[2] = in0[0];
670               out1[1] = 0;
671               out1[0] = 0;
672               out0[3] = 0;
673               out0[2] = 0;
674               out0[1] = 0;
675               out0[0] = 0;
676               break;
677     case 25:  out1[3] = amd_bytealign_S (in0[1], in0[0], 3);
678               out1[2] = amd_bytealign_S (in0[0],      0, 3);
679               out1[1] = 0;
680               out1[0] = 0;
681               out0[3] = 0;
682               out0[2] = 0;
683               out0[1] = 0;
684               out0[0] = 0;
685               break;
686     case 26:  out1[3] = amd_bytealign_S (in0[1], in0[0], 2);
687               out1[2] = amd_bytealign_S (in0[0],      0, 2);
688               out1[1] = 0;
689               out1[0] = 0;
690               out0[3] = 0;
691               out0[2] = 0;
692               out0[1] = 0;
693               out0[0] = 0;
694               break;
695     case 27:  out1[3] = amd_bytealign_S (in0[1], in0[0], 1);
696               out1[2] = amd_bytealign_S (in0[0],      0, 1);
697               out1[1] = 0;
698               out1[0] = 0;
699               out0[3] = 0;
700               out0[2] = 0;
701               out0[1] = 0;
702               out0[0] = 0;
703               break;
704     case 28:  out1[3] = in0[0];
705               out1[2] = 0;
706               out1[1] = 0;
707               out1[0] = 0;
708               out0[3] = 0;
709               out0[2] = 0;
710               out0[1] = 0;
711               out0[0] = 0;
712               break;
713     case 29:  out1[3] = amd_bytealign_S (in0[0],      0, 3);
714               out1[2] = 0;
715               out1[1] = 0;
716               out1[0] = 0;
717               out0[3] = 0;
718               out0[2] = 0;
719               out0[1] = 0;
720               out0[0] = 0;
721               break;
722     case 30:  out1[3] = amd_bytealign_S (in0[0],      0, 2);
723               out1[2] = 0;
724               out1[1] = 0;
725               out1[0] = 0;
726               out0[3] = 0;
727               out0[2] = 0;
728               out0[1] = 0;
729               out0[0] = 0;
730               break;
731     case 31:  out1[3] = amd_bytealign_S (in0[0],      0, 1);
732               out1[2] = 0;
733               out1[1] = 0;
734               out1[0] = 0;
735               out0[3] = 0;
736               out0[2] = 0;
737               out0[1] = 0;
738               out0[0] = 0;
739               break;
740   }
741 }
742
743 inline void append_block1 (const u32 offset, u32 dst0[4], u32 dst1[4], const u32 src_r0)
744 {
745   u32 tmp[2];
746
747   switch (offset & 3)
748   {
749     case  0:  tmp[0] = src_r0;
750               tmp[1] = 0;
751               break;
752     case  1:  tmp[0] = src_r0 <<  8;
753               tmp[1] = src_r0 >> 24;
754               break;
755     case  2:  tmp[0] = src_r0 << 16;
756               tmp[1] = src_r0 >> 16;
757               break;
758     case  3:  tmp[0] = src_r0 << 24;
759               tmp[1] = src_r0 >>  8;
760               break;
761   }
762
763   switch (offset / 4)
764   {
765     case  0:  dst0[0] |= tmp[0];
766               dst0[1]  = tmp[1];
767               break;
768     case  1:  dst0[1] |= tmp[0];
769               dst0[2]  = tmp[1];
770               break;
771     case  2:  dst0[2] |= tmp[0];
772               dst0[3]  = tmp[1];
773               break;
774     case  3:  dst0[3] |= tmp[0];
775               dst1[0]  = tmp[1];
776               break;
777     case  4:  dst1[0] |= tmp[0];
778               dst1[1]  = tmp[1];
779               break;
780     case  5:  dst1[1] |= tmp[0];
781               dst1[2]  = tmp[1];
782               break;
783     case  6:  dst1[2] |= tmp[0];
784               dst1[3]  = tmp[1];
785               break;
786     case  7:  dst1[3] |= tmp[0];
787               break;
788   }
789 }
790
791 inline void append_block8 (const u32 offset, u32 dst0[4], u32 dst1[4], const u32 src_l0[4], const u32 src_l1[4], const u32 src_r0[4], const u32 src_r1[4])
792 {
793   switch (offset)
794   {
795     case 31:
796       dst1[3] = src_l1[3] | src_r0[0] << 24;
797       break;
798     case 30:
799       dst1[3] = src_l1[3] | src_r0[0] << 16;
800       break;
801     case 29:
802       dst1[3] = src_l1[3] | src_r0[0] <<  8;
803       break;
804     case 28:
805       dst1[3] = src_r0[0];
806       break;
807     case 27:
808       dst1[3] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
809       dst1[2] = src_l1[2] | src_r0[0] << 24;
810       break;
811     case 26:
812       dst1[3] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
813       dst1[2] = src_l1[2] | src_r0[0] << 16;
814       break;
815     case 25:
816       dst1[3] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
817       dst1[2] = src_l1[2] | src_r0[0] <<  8;
818       break;
819     case 24:
820       dst1[3] = src_r0[1];
821       dst1[2] = src_r0[0];
822       break;
823     case 23:
824       dst1[3] = amd_bytealign_S (src_r0[2], src_r0[1], 1);
825       dst1[2] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
826       dst1[1] = src_l1[1] | src_r0[0] << 24;
827       break;
828     case 22:
829       dst1[3] = amd_bytealign_S (src_r0[2], src_r0[1], 2);
830       dst1[2] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
831       dst1[1] = src_l1[1] | src_r0[0] << 16;
832       break;
833     case 21:
834       dst1[3] = amd_bytealign_S (src_r0[2], src_r0[1], 3);
835       dst1[2] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
836       dst1[1] = src_l1[1] | src_r0[0] <<  8;
837       break;
838     case 20:
839       dst1[3] = src_r0[2];
840       dst1[2] = src_r0[1];
841       dst1[1] = src_r0[0];
842       break;
843     case 19:
844       dst1[3] = amd_bytealign_S (src_r0[3], src_r0[2], 1);
845       dst1[2] = amd_bytealign_S (src_r0[2], src_r0[1], 1);
846       dst1[1] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
847       dst1[0] = src_l1[0] | src_r0[0] << 24;
848       break;
849     case 18:
850       dst1[3] = amd_bytealign_S (src_r0[3], src_r0[2], 2);
851       dst1[2] = amd_bytealign_S (src_r0[2], src_r0[1], 2);
852       dst1[1] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
853       dst1[0] = src_l1[0] | src_r0[0] << 16;
854       break;
855     case 17:
856       dst1[3] = amd_bytealign_S (src_r0[3], src_r0[2], 3);
857       dst1[2] = amd_bytealign_S (src_r0[2], src_r0[1], 3);
858       dst1[1] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
859       dst1[0] = src_l1[0] | src_r0[0] <<  8;
860       break;
861     case 16:
862       dst1[3] = src_r0[3];
863       dst1[2] = src_r0[2];
864       dst1[1] = src_r0[1];
865       dst1[0] = src_r0[0];
866       break;
867     case 15:
868       dst1[3] = amd_bytealign_S (src_r1[0], src_r0[3], 1);
869       dst1[2] = amd_bytealign_S (src_r0[3], src_r0[2], 1);
870       dst1[1] = amd_bytealign_S (src_r0[2], src_r0[1], 1);
871       dst1[0] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
872       dst0[3] = src_l0[3] | src_r0[0] << 24;
873       break;
874     case 14:
875       dst1[3] = amd_bytealign_S (src_r1[0], src_r0[3], 2);
876       dst1[2] = amd_bytealign_S (src_r0[3], src_r0[2], 2);
877       dst1[1] = amd_bytealign_S (src_r0[2], src_r0[1], 2);
878       dst1[0] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
879       dst0[3] = src_l0[3] | src_r0[0] << 16;
880       break;
881     case 13:
882       dst1[3] = amd_bytealign_S (src_r1[0], src_r0[3], 3);
883       dst1[2] = amd_bytealign_S (src_r0[3], src_r0[2], 3);
884       dst1[1] = amd_bytealign_S (src_r0[2], src_r0[1], 3);
885       dst1[0] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
886       dst0[3] = src_l0[3] | src_r0[0] <<  8;
887       break;
888     case 12:
889       dst1[3] = src_r1[0];
890       dst1[2] = src_r0[3];
891       dst1[1] = src_r0[2];
892       dst1[0] = src_r0[1];
893       dst0[3] = src_r0[0];
894       break;
895     case 11:
896       dst1[3] = amd_bytealign_S (src_r1[1], src_r1[0], 1);
897       dst1[2] = amd_bytealign_S (src_r1[0], src_r0[3], 1);
898       dst1[1] = amd_bytealign_S (src_r0[3], src_r0[2], 1);
899       dst1[0] = amd_bytealign_S (src_r0[2], src_r0[1], 1);
900       dst0[3] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
901       dst0[2] = src_l0[2] | src_r0[0] << 24;
902       break;
903     case 10:
904       dst1[3] = amd_bytealign_S (src_r1[1], src_r1[0], 2);
905       dst1[2] = amd_bytealign_S (src_r1[0], src_r0[3], 2);
906       dst1[1] = amd_bytealign_S (src_r0[3], src_r0[2], 2);
907       dst1[0] = amd_bytealign_S (src_r0[2], src_r0[1], 2);
908       dst0[3] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
909       dst0[2] = src_l0[2] | src_r0[0] << 16;
910       break;
911     case 9:
912       dst1[3] = amd_bytealign_S (src_r1[1], src_r1[0], 3);
913       dst1[2] = amd_bytealign_S (src_r1[0], src_r0[3], 3);
914       dst1[1] = amd_bytealign_S (src_r0[3], src_r0[2], 3);
915       dst1[0] = amd_bytealign_S (src_r0[2], src_r0[1], 3);
916       dst0[3] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
917       dst0[2] = src_l0[2] | src_r0[0] <<  8;
918       break;
919     case 8:
920       dst1[3] = src_r1[1];
921       dst1[2] = src_r1[0];
922       dst1[1] = src_r0[3];
923       dst1[0] = src_r0[2];
924       dst0[3] = src_r0[1];
925       dst0[2] = src_r0[0];
926       break;
927     case 7:
928       dst1[3] = amd_bytealign_S (src_r1[2], src_r1[1], 1);
929       dst1[2] = amd_bytealign_S (src_r1[1], src_r1[0], 1);
930       dst1[1] = amd_bytealign_S (src_r1[0], src_r0[3], 1);
931       dst1[0] = amd_bytealign_S (src_r0[3], src_r0[2], 1);
932       dst0[3] = amd_bytealign_S (src_r0[2], src_r0[1], 1);
933       dst0[2] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
934       dst0[1] = src_l0[1] | src_r0[0] << 24;
935       break;
936     case 6:
937       dst1[3] = amd_bytealign_S (src_r1[2], src_r1[1], 2);
938       dst1[2] = amd_bytealign_S (src_r1[1], src_r1[0], 2);
939       dst1[1] = amd_bytealign_S (src_r1[0], src_r0[3], 2);
940       dst1[0] = amd_bytealign_S (src_r0[3], src_r0[2], 2);
941       dst0[3] = amd_bytealign_S (src_r0[2], src_r0[1], 2);
942       dst0[2] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
943       dst0[1] = src_l0[1] | src_r0[0] << 16;
944       break;
945     case 5:
946       dst1[3] = amd_bytealign_S (src_r1[2], src_r1[1], 3);
947       dst1[2] = amd_bytealign_S (src_r1[1], src_r1[0], 3);
948       dst1[1] = amd_bytealign_S (src_r1[0], src_r0[3], 3);
949       dst1[0] = amd_bytealign_S (src_r0[3], src_r0[2], 3);
950       dst0[3] = amd_bytealign_S (src_r0[2], src_r0[1], 3);
951       dst0[2] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
952       dst0[1] = src_l0[1] | src_r0[0] <<  8;
953       break;
954     case 4:
955       dst1[3] = src_r1[2];
956       dst1[2] = src_r1[1];
957       dst1[1] = src_r1[0];
958       dst1[0] = src_r0[3];
959       dst0[3] = src_r0[2];
960       dst0[2] = src_r0[1];
961       dst0[1] = src_r0[0];
962       break;
963     case 3:
964       dst1[3] = amd_bytealign_S (src_r1[3], src_r1[2], 1);
965       dst1[2] = amd_bytealign_S (src_r1[2], src_r1[1], 1);
966       dst1[1] = amd_bytealign_S (src_r1[1], src_r1[0], 1);
967       dst1[0] = amd_bytealign_S (src_r1[0], src_r0[3], 1);
968       dst0[3] = amd_bytealign_S (src_r0[3], src_r0[2], 1);
969       dst0[2] = amd_bytealign_S (src_r0[2], src_r0[1], 1);
970       dst0[1] = amd_bytealign_S (src_r0[1], src_r0[0], 1);
971       dst0[0] = src_l0[0] | src_r0[0] << 24;
972       break;
973     case 2:
974       dst1[3] = amd_bytealign_S (src_r1[3], src_r1[2], 2);
975       dst1[2] = amd_bytealign_S (src_r1[2], src_r1[1], 2);
976       dst1[1] = amd_bytealign_S (src_r1[1], src_r1[0], 2);
977       dst1[0] = amd_bytealign_S (src_r1[0], src_r0[3], 2);
978       dst0[3] = amd_bytealign_S (src_r0[3], src_r0[2], 2);
979       dst0[2] = amd_bytealign_S (src_r0[2], src_r0[1], 2);
980       dst0[1] = amd_bytealign_S (src_r0[1], src_r0[0], 2);
981       dst0[0] = src_l0[0] | src_r0[0] << 16;
982       break;
983     case 1:
984       dst1[3] = amd_bytealign_S (src_r1[3], src_r1[2], 3);
985       dst1[2] = amd_bytealign_S (src_r1[2], src_r1[1], 3);
986       dst1[1] = amd_bytealign_S (src_r1[1], src_r1[0], 3);
987       dst1[0] = amd_bytealign_S (src_r1[0], src_r0[3], 3);
988       dst0[3] = amd_bytealign_S (src_r0[3], src_r0[2], 3);
989       dst0[2] = amd_bytealign_S (src_r0[2], src_r0[1], 3);
990       dst0[1] = amd_bytealign_S (src_r0[1], src_r0[0], 3);
991       dst0[0] = src_l0[0] | src_r0[0] <<  8;
992       break;
993     case 0:
994       dst1[3] = src_r1[3];
995       dst1[2] = src_r1[2];
996       dst1[1] = src_r1[1];
997       dst1[0] = src_r1[0];
998       dst0[3] = src_r0[3];
999       dst0[2] = src_r0[2];
1000       dst0[1] = src_r0[1];
1001       dst0[0] = src_r0[0];
1002       break;
1003   }
1004 }
1005
1006 inline void reverse_block (u32 in0[4], u32 in1[4], u32 out0[4], u32 out1[4], const u32 len)
1007 {
1008   rshift_block_N (in0, in1, out0, out1, 32 - len);
1009
1010   u32 tib40[4];
1011   u32 tib41[4];
1012
1013   tib40[0] = out1[3];
1014   tib40[1] = out1[2];
1015   tib40[2] = out1[1];
1016   tib40[3] = out1[0];
1017   tib41[0] = out0[3];
1018   tib41[1] = out0[2];
1019   tib41[2] = out0[1];
1020   tib41[3] = out0[0];
1021
1022   out0[0] = swap32_S (tib40[0]);
1023   out0[1] = swap32_S (tib40[1]);
1024   out0[2] = swap32_S (tib40[2]);
1025   out0[3] = swap32_S (tib40[3]);
1026   out1[0] = swap32_S (tib41[0]);
1027   out1[1] = swap32_S (tib41[1]);
1028   out1[2] = swap32_S (tib41[2]);
1029   out1[3] = swap32_S (tib41[3]);
1030 }
1031
1032 inline u32 rule_op_mangle_lrest (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1033 {
1034   buf0[0] |= (generate_cmask (buf0[0]));
1035   buf0[1] |= (generate_cmask (buf0[1]));
1036   buf0[2] |= (generate_cmask (buf0[2]));
1037   buf0[3] |= (generate_cmask (buf0[3]));
1038   buf1[0] |= (generate_cmask (buf1[0]));
1039   buf1[1] |= (generate_cmask (buf1[1]));
1040   buf1[2] |= (generate_cmask (buf1[2]));
1041   buf1[3] |= (generate_cmask (buf1[3]));
1042
1043   return in_len;
1044 }
1045
1046 inline u32 rule_op_mangle_urest (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1047 {
1048   buf0[0] &= ~(generate_cmask (buf0[0]));
1049   buf0[1] &= ~(generate_cmask (buf0[1]));
1050   buf0[2] &= ~(generate_cmask (buf0[2]));
1051   buf0[3] &= ~(generate_cmask (buf0[3]));
1052   buf1[0] &= ~(generate_cmask (buf1[0]));
1053   buf1[1] &= ~(generate_cmask (buf1[1]));
1054   buf1[2] &= ~(generate_cmask (buf1[2]));
1055   buf1[3] &= ~(generate_cmask (buf1[3]));
1056
1057   return in_len;
1058 }
1059
1060 inline u32 rule_op_mangle_lrest_ufirst (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1061 {
1062   rule_op_mangle_lrest (p0, p1, buf0, buf1, in_len);
1063
1064   buf0[0] &= ~(0x00000020 & generate_cmask (buf0[0]));
1065
1066   return in_len;
1067 }
1068
1069 inline u32 rule_op_mangle_urest_lfirst (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1070 {
1071   rule_op_mangle_urest (p0, p1, buf0, buf1, in_len);
1072
1073   buf0[0] |= (0x00000020 & generate_cmask (buf0[0]));
1074
1075   return in_len;
1076 }
1077
1078 inline u32 rule_op_mangle_trest (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1079 {
1080   buf0[0] ^= (generate_cmask (buf0[0]));
1081   buf0[1] ^= (generate_cmask (buf0[1]));
1082   buf0[2] ^= (generate_cmask (buf0[2]));
1083   buf0[3] ^= (generate_cmask (buf0[3]));
1084   buf1[0] ^= (generate_cmask (buf1[0]));
1085   buf1[1] ^= (generate_cmask (buf1[1]));
1086   buf1[2] ^= (generate_cmask (buf1[2]));
1087   buf1[3] ^= (generate_cmask (buf1[3]));
1088
1089   return in_len;
1090 }
1091
1092 inline u32 rule_op_mangle_toggle_at (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1093 {
1094   if (p0 >= in_len) return (in_len);
1095
1096   const u32 tmp = 0x20u << ((p0 & 3) * 8);
1097
1098   switch (p0 / 4)
1099   {
1100     case  0:  buf0[0] ^= (tmp & generate_cmask (buf0[0])); break;
1101     case  1:  buf0[1] ^= (tmp & generate_cmask (buf0[1])); break;
1102     case  2:  buf0[2] ^= (tmp & generate_cmask (buf0[2])); break;
1103     case  3:  buf0[3] ^= (tmp & generate_cmask (buf0[3])); break;
1104     case  4:  buf1[0] ^= (tmp & generate_cmask (buf1[0])); break;
1105     case  5:  buf1[1] ^= (tmp & generate_cmask (buf1[1])); break;
1106     case  6:  buf1[2] ^= (tmp & generate_cmask (buf1[2])); break;
1107     case  7:  buf1[3] ^= (tmp & generate_cmask (buf1[3])); break;
1108   }
1109
1110   return in_len;
1111 }
1112
1113 inline u32 rule_op_mangle_reverse (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1114 {
1115   reverse_block (buf0, buf1, buf0, buf1, in_len);
1116
1117   return in_len;
1118 }
1119
1120 inline u32 rule_op_mangle_dupeword (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1121 {
1122   if ((in_len + in_len) >= 32) return (in_len);
1123
1124   u32 out_len = in_len;
1125
1126   append_block8 (out_len, buf0, buf1, buf0, buf1, buf0, buf1);
1127
1128   out_len += in_len;
1129
1130   return out_len;
1131 }
1132
1133 inline u32 rule_op_mangle_dupeword_times (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1134 {
1135   if (((in_len * p0) + in_len) >= 32) return (in_len);
1136
1137   u32 out_len = in_len;
1138
1139   u32 tib40[4];
1140   u32 tib41[4];
1141
1142   tib40[0] = buf0[0];
1143   tib40[1] = buf0[1];
1144   tib40[2] = buf0[2];
1145   tib40[3] = buf0[3];
1146   tib41[0] = buf1[0];
1147   tib41[1] = buf1[1];
1148   tib41[2] = buf1[2];
1149   tib41[3] = buf1[3];
1150
1151   for (u32 i = 0; i < p0; i++)
1152   {
1153     append_block8 (out_len, buf0, buf1, buf0, buf1, tib40, tib41);
1154
1155     out_len += in_len;
1156   }
1157
1158   return out_len;
1159 }
1160
1161 inline u32 rule_op_mangle_reflect (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1162 {
1163   if ((in_len + in_len) >= 32) return (in_len);
1164
1165   u32 out_len = in_len;
1166
1167   u32 tib40[4];
1168   u32 tib41[4];
1169
1170   reverse_block (buf0, buf1, tib40, tib41, out_len);
1171
1172   append_block8 (out_len, buf0, buf1, buf0, buf1, tib40, tib41);
1173
1174   out_len += in_len;
1175
1176   return out_len;
1177 }
1178
1179 inline u32 rule_op_mangle_append (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1180 {
1181   if ((in_len + 1) >= 32) return (in_len);
1182
1183   u32 out_len = in_len;
1184
1185   append_block1 (out_len, buf0, buf1, p0);
1186
1187   out_len++;
1188
1189   return out_len;
1190 }
1191
1192 inline u32 rule_op_mangle_prepend (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1193 {
1194   if ((in_len + 1) >= 32) return (in_len);
1195
1196   u32 out_len = in_len;
1197
1198   rshift_block (buf0, buf1, buf0, buf1);
1199
1200   buf0[0] = buf0[0] | p0;
1201
1202   out_len++;
1203
1204   return out_len;
1205 }
1206
1207 inline u32 rule_op_mangle_rotate_left (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1208 {
1209   if (in_len == 0) return (in_len);
1210
1211   const u32 in_len1 = in_len - 1;
1212
1213   const u32 sh = (in_len1 & 3) * 8;
1214
1215   const u32 tmp = (buf0[0] & 0xff) << sh;
1216
1217   lshift_block (buf0, buf1, buf0, buf1);
1218
1219   switch (in_len1 / 4)
1220   {
1221     case  0:  buf0[0] |= tmp; break;
1222     case  1:  buf0[1] |= tmp; break;
1223     case  2:  buf0[2] |= tmp; break;
1224     case  3:  buf0[3] |= tmp; break;
1225     case  4:  buf1[0] |= tmp; break;
1226     case  5:  buf1[1] |= tmp; break;
1227     case  6:  buf1[2] |= tmp; break;
1228     case  7:  buf1[3] |= tmp; break;
1229   }
1230
1231   return in_len;
1232 }
1233
1234 inline u32 rule_op_mangle_rotate_right (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1235 {
1236   if (in_len == 0) return (in_len);
1237
1238   const u32 in_len1 = in_len - 1;
1239
1240   const u32 sh = (in_len1 & 3) * 8;
1241
1242   u32 tmp = 0;
1243
1244   switch (in_len1 / 4)
1245   {
1246     case  0:  tmp = (buf0[0] >> sh) & 0xff; break;
1247     case  1:  tmp = (buf0[1] >> sh) & 0xff; break;
1248     case  2:  tmp = (buf0[2] >> sh) & 0xff; break;
1249     case  3:  tmp = (buf0[3] >> sh) & 0xff; break;
1250     case  4:  tmp = (buf1[0] >> sh) & 0xff; break;
1251     case  5:  tmp = (buf1[1] >> sh) & 0xff; break;
1252     case  6:  tmp = (buf1[2] >> sh) & 0xff; break;
1253     case  7:  tmp = (buf1[3] >> sh) & 0xff; break;
1254   }
1255
1256   rshift_block (buf0, buf1, buf0, buf1);
1257
1258   buf0[0] |= tmp;
1259
1260   truncate_right (buf0, buf1, in_len);
1261
1262   return in_len;
1263 }
1264
1265 inline u32 rule_op_mangle_delete_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1266 {
1267   if (in_len == 0) return (in_len);
1268
1269   const u32 in_len1 = in_len - 1;
1270
1271   lshift_block (buf0, buf1, buf0, buf1);
1272
1273   return in_len1;
1274 }
1275
1276 inline u32 rule_op_mangle_delete_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1277 {
1278   if (in_len == 0) return (in_len);
1279
1280   const u32 in_len1 = in_len - 1;
1281
1282   const u32 tmp = (1 << ((in_len1 & 3) * 8)) - 1;
1283
1284   switch (in_len1 / 4)
1285   {
1286     case  0:  buf0[0] &= tmp; break;
1287     case  1:  buf0[1] &= tmp; break;
1288     case  2:  buf0[2] &= tmp; break;
1289     case  3:  buf0[3] &= tmp; break;
1290     case  4:  buf1[0] &= tmp; break;
1291     case  5:  buf1[1] &= tmp; break;
1292     case  6:  buf1[2] &= tmp; break;
1293     case  7:  buf1[3] &= tmp; break;
1294   }
1295
1296   return in_len1;
1297 }
1298
1299 inline u32 rule_op_mangle_delete_at (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1300 {
1301   if (p0 >= in_len) return (in_len);
1302
1303   u32 out_len = in_len;
1304
1305   u32 tib40[4];
1306   u32 tib41[4];
1307
1308   lshift_block (buf0, buf1, tib40, tib41);
1309
1310   const u32 ml = (1 << ((p0 & 3) * 8)) - 1;
1311   const u32 mr = ~ml;
1312
1313   switch (p0 / 4)
1314   {
1315     case  0:  buf0[0] =  (buf0[0] & ml)
1316                       | (tib40[0] & mr);
1317               buf0[1] =  tib40[1];
1318               buf0[2] =  tib40[2];
1319               buf0[3] =  tib40[3];
1320               buf1[0] =  tib41[0];
1321               buf1[1] =  tib41[1];
1322               buf1[2] =  tib41[2];
1323               buf1[3] =  tib41[3];
1324               break;
1325     case  1:  buf0[1] =  (buf0[1] & ml)
1326                       | (tib40[1] & mr);
1327               buf0[2] =  tib40[2];
1328               buf0[3] =  tib40[3];
1329               buf1[0] =  tib41[0];
1330               buf1[1] =  tib41[1];
1331               buf1[2] =  tib41[2];
1332               buf1[3] =  tib41[3];
1333               break;
1334     case  2:  buf0[2] =  (buf0[2] & ml)
1335                       | (tib40[2] & mr);
1336               buf0[3] =  tib40[3];
1337               buf1[0] =  tib41[0];
1338               buf1[1] =  tib41[1];
1339               buf1[2] =  tib41[2];
1340               buf1[3] =  tib41[3];
1341               break;
1342     case  3:  buf0[3] =  (buf0[3] & ml)
1343                       | (tib40[3] & mr);
1344               buf1[0] =  tib41[0];
1345               buf1[1] =  tib41[1];
1346               buf1[2] =  tib41[2];
1347               buf1[3] =  tib41[3];
1348               break;
1349     case  4:  buf1[0] =  (buf1[0] & ml)
1350                       | (tib41[0] & mr);
1351               buf1[1] =  tib41[1];
1352               buf1[2] =  tib41[2];
1353               buf1[3] =  tib41[3];
1354               break;
1355     case  5:  buf1[1] =  (buf1[1] & ml)
1356                       | (tib41[1] & mr);
1357               buf1[2] =  tib41[2];
1358               buf1[3] =  tib41[3];
1359               break;
1360     case  6:  buf1[2] =  (buf1[2] & ml)
1361                       | (tib41[2] & mr);
1362               buf1[3] =  tib41[3];
1363               break;
1364     case  7:  buf1[3] =  (buf1[3] & ml)
1365                       | (tib41[3] & mr);
1366               break;
1367   }
1368
1369   out_len--;
1370
1371   return out_len;
1372 }
1373
1374 inline u32 rule_op_mangle_extract (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1375 {
1376   if (p0 >= in_len) return (in_len);
1377
1378   if ((p0 + p1) > in_len) return (in_len);
1379
1380   u32 out_len = p1;
1381
1382   lshift_block_N (buf0, buf1, buf0, buf1, p0);
1383
1384   truncate_right (buf0, buf1, out_len);
1385
1386   return out_len;
1387 }
1388
1389 inline u32 rule_op_mangle_omit (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1390 {
1391   if (p0 >= in_len) return (in_len);
1392
1393   if ((p0 + p1) > in_len) return (in_len);
1394
1395   u32 out_len = in_len;
1396
1397   u32 tib40[4];
1398   u32 tib41[4];
1399
1400   tib40[0] = 0;
1401   tib40[1] = 0;
1402   tib40[2] = 0;
1403   tib40[3] = 0;
1404   tib41[0] = 0;
1405   tib41[1] = 0;
1406   tib41[2] = 0;
1407   tib41[3] = 0;
1408
1409   lshift_block_N (buf0, buf1, tib40, tib41, p1);
1410
1411   const u32 ml = (1 << ((p0 & 3) * 8)) - 1;
1412   const u32 mr = ~ml;
1413
1414   switch (p0 / 4)
1415   {
1416     case  0:  buf0[0] =  (buf0[0] & ml)
1417                       | (tib40[0] & mr);
1418               buf0[1] =  tib40[1];
1419               buf0[2] =  tib40[2];
1420               buf0[3] =  tib40[3];
1421               buf1[0] =  tib41[0];
1422               buf1[1] =  tib41[1];
1423               buf1[2] =  tib41[2];
1424               buf1[3] =  tib41[3];
1425               break;
1426     case  1:  buf0[1] =  (buf0[1] & ml)
1427                       | (tib40[1] & mr);
1428               buf0[2] =  tib40[2];
1429               buf0[3] =  tib40[3];
1430               buf1[0] =  tib41[0];
1431               buf1[1] =  tib41[1];
1432               buf1[2] =  tib41[2];
1433               buf1[3] =  tib41[3];
1434               break;
1435     case  2:  buf0[2] =  (buf0[2] & ml)
1436                       | (tib40[2] & mr);
1437               buf0[3] =  tib40[3];
1438               buf1[0] =  tib41[0];
1439               buf1[1] =  tib41[1];
1440               buf1[2] =  tib41[2];
1441               buf1[3] =  tib41[3];
1442               break;
1443     case  3:  buf0[3] =  (buf0[3] & ml)
1444                       | (tib40[3] & mr);
1445               buf1[0] =  tib41[0];
1446               buf1[1] =  tib41[1];
1447               buf1[2] =  tib41[2];
1448               buf1[3] =  tib41[3];
1449               break;
1450     case  4:  buf1[0] =  (buf1[0] & ml)
1451                       | (tib41[0] & mr);
1452               buf1[1] =  tib41[1];
1453               buf1[2] =  tib41[2];
1454               buf1[3] =  tib41[3];
1455               break;
1456     case  5:  buf1[1] =  (buf1[1] & ml)
1457                       | (tib41[1] & mr);
1458               buf1[2] =  tib41[2];
1459               buf1[3] =  tib41[3];
1460               break;
1461     case  6:  buf1[2] =  (buf1[2] & ml)
1462                       | (tib41[2] & mr);
1463               buf1[3] =  tib41[3];
1464               break;
1465     case  7:  buf1[3] =  (buf1[3] & ml)
1466                       | (tib41[3] & mr);
1467               break;
1468   }
1469
1470   out_len -= p1;
1471
1472   return out_len;
1473 }
1474
1475 inline u32 rule_op_mangle_insert (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1476 {
1477   if (p0 > in_len) return (in_len);
1478
1479   if ((in_len + 1) >= 32) return (in_len);
1480
1481   u32 out_len = in_len;
1482
1483   u32 tib40[4];
1484   u32 tib41[4];
1485
1486   rshift_block (buf0, buf1, tib40, tib41);
1487
1488   const u32 p1n = p1 << ((p0 & 3) * 8);
1489
1490   const u32 ml = (1 << ((p0 & 3) * 8)) - 1;
1491
1492   const u32 mr = 0xffffff00 << ((p0 & 3) * 8);
1493
1494   switch (p0 / 4)
1495   {
1496     case  0:  buf0[0] =  (buf0[0] & ml) | p1n | (tib40[0] & mr);
1497               buf0[1] =  tib40[1];
1498               buf0[2] =  tib40[2];
1499               buf0[3] =  tib40[3];
1500               buf1[0] =  tib41[0];
1501               buf1[1] =  tib41[1];
1502               buf1[2] =  tib41[2];
1503               buf1[3] =  tib41[3];
1504               break;
1505     case  1:  buf0[1] =  (buf0[1] & ml) | p1n | (tib40[1] & mr);
1506               buf0[2] =  tib40[2];
1507               buf0[3] =  tib40[3];
1508               buf1[0] =  tib41[0];
1509               buf1[1] =  tib41[1];
1510               buf1[2] =  tib41[2];
1511               buf1[3] =  tib41[3];
1512               break;
1513     case  2:  buf0[2] =  (buf0[2] & ml) | p1n | (tib40[2] & mr);
1514               buf0[3] =  tib40[3];
1515               buf1[0] =  tib41[0];
1516               buf1[1] =  tib41[1];
1517               buf1[2] =  tib41[2];
1518               buf1[3] =  tib41[3];
1519               break;
1520     case  3:  buf0[3] =  (buf0[3] & ml) | p1n | (tib40[3] & mr);
1521               buf1[0] =  tib41[0];
1522               buf1[1] =  tib41[1];
1523               buf1[2] =  tib41[2];
1524               buf1[3] =  tib41[3];
1525               break;
1526     case  4:  buf1[0] =  (buf1[0] & ml) | p1n | (tib41[0] & mr);
1527               buf1[1] =  tib41[1];
1528               buf1[2] =  tib41[2];
1529               buf1[3] =  tib41[3];
1530               break;
1531     case  5:  buf1[1] =  (buf1[1] & ml) | p1n | (tib41[1] & mr);
1532               buf1[2] =  tib41[2];
1533               buf1[3] =  tib41[3];
1534               break;
1535     case  6:  buf1[2] =  (buf1[2] & ml) | p1n | (tib41[2] & mr);
1536               buf1[3] =  tib41[3];
1537               break;
1538     case  7:  buf1[3] =  (buf1[3] & ml) | p1n | (tib41[3] & mr);
1539               break;
1540   }
1541
1542   out_len++;
1543
1544   return out_len;
1545 }
1546
1547 inline u32 rule_op_mangle_overstrike (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1548 {
1549   if (p0 >= in_len) return (in_len);
1550
1551   const u32 p1n = p1 << ((p0 & 3) * 8);
1552
1553   const u32 m = ~(0xffu << ((p0 & 3) * 8));
1554
1555   switch (p0 / 4)
1556   {
1557     case  0: buf0[0] = (buf0[0] & m) | p1n; break;
1558     case  1: buf0[1] = (buf0[1] & m) | p1n; break;
1559     case  2: buf0[2] = (buf0[2] & m) | p1n; break;
1560     case  3: buf0[3] = (buf0[3] & m) | p1n; break;
1561     case  4: buf1[0] = (buf1[0] & m) | p1n; break;
1562     case  5: buf1[1] = (buf1[1] & m) | p1n; break;
1563     case  6: buf1[2] = (buf1[2] & m) | p1n; break;
1564     case  7: buf1[3] = (buf1[3] & m) | p1n; break;
1565   }
1566
1567   return in_len;
1568 }
1569
1570 inline u32 rule_op_mangle_truncate_at (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1571 {
1572   if (p0 >= in_len) return (in_len);
1573
1574   truncate_right (buf0, buf1, p0);
1575
1576   return p0;
1577 }
1578
1579 inline u32 rule_op_mangle_replace (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1580 {
1581   const uchar4 tmp0 = (uchar4) (p0);
1582   const uchar4 tmp1 = (uchar4) (p1);
1583
1584   uchar4 tmp;
1585
1586   tmp = as_uchar4 (buf0[0]); tmp = select (tmp, tmp1, tmp == tmp0); buf0[0] = as_uint (tmp);
1587   tmp = as_uchar4 (buf0[1]); tmp = select (tmp, tmp1, tmp == tmp0); buf0[1] = as_uint (tmp);
1588   tmp = as_uchar4 (buf0[2]); tmp = select (tmp, tmp1, tmp == tmp0); buf0[2] = as_uint (tmp);
1589   tmp = as_uchar4 (buf0[3]); tmp = select (tmp, tmp1, tmp == tmp0); buf0[3] = as_uint (tmp);
1590   tmp = as_uchar4 (buf1[0]); tmp = select (tmp, tmp1, tmp == tmp0); buf1[0] = as_uint (tmp);
1591   tmp = as_uchar4 (buf1[1]); tmp = select (tmp, tmp1, tmp == tmp0); buf1[1] = as_uint (tmp);
1592   tmp = as_uchar4 (buf1[2]); tmp = select (tmp, tmp1, tmp == tmp0); buf1[2] = as_uint (tmp);
1593   tmp = as_uchar4 (buf1[3]); tmp = select (tmp, tmp1, tmp == tmp0); buf1[3] = as_uint (tmp);
1594
1595   return in_len;
1596 }
1597
1598 inline u32 rule_op_mangle_purgechar (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1599 {
1600   u32 out_len = 0;
1601
1602   u32 buf_in[8];
1603
1604   buf_in[0] = buf0[0];
1605   buf_in[1] = buf0[1];
1606   buf_in[2] = buf0[2];
1607   buf_in[3] = buf0[3];
1608   buf_in[4] = buf1[0];
1609   buf_in[5] = buf1[1];
1610   buf_in[6] = buf1[2];
1611   buf_in[7] = buf1[3];
1612
1613   u32 buf_out[8] = { 0 };
1614
1615   u8 *in  = (u8 *) buf_in;
1616   u8 *out = (u8 *) buf_out;
1617
1618   for (u32 pos = 0; pos < in_len; pos++)
1619   {
1620     if (in[pos] == (u8) p0) continue;
1621
1622     out[out_len] = in[pos];
1623
1624     out_len++;
1625   }
1626
1627   buf0[0] = buf_out[0];
1628   buf0[1] = buf_out[1];
1629   buf0[2] = buf_out[2];
1630   buf0[3] = buf_out[3];
1631   buf1[0] = buf_out[4];
1632   buf1[1] = buf_out[5];
1633   buf1[2] = buf_out[6];
1634   buf1[3] = buf_out[7];
1635
1636   return out_len;
1637 }
1638
1639 inline u32 rule_op_mangle_togglecase_rec (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1640 {
1641   // TODO
1642   return in_len;
1643 }
1644
1645 inline u32 rule_op_mangle_dupechar_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1646 {
1647   if ( in_len       ==  0) return (in_len);
1648   if ((in_len + p0) >= 32) return (in_len);
1649
1650   u32 out_len = in_len;
1651
1652   const u32 tmp = buf0[0] & 0xFF;
1653
1654   rshift_block_N (buf0, buf1, buf0, buf1, p0);
1655
1656   switch (p0)
1657   {
1658     case  1:  buf0[0] |= tmp <<  0;
1659               break;
1660     case  2:  buf0[0] |= tmp <<  0 | tmp << 8;
1661               break;
1662     case  3:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16;
1663               break;
1664     case  4:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1665               break;
1666     case  5:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1667               buf0[1] |= tmp <<  0;
1668               break;
1669     case  6:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1670               buf0[1] |= tmp <<  0 | tmp << 8;
1671               break;
1672     case  7:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1673               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16;
1674               break;
1675     case  8:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1676               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1677               break;
1678     case  9:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1679               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1680               buf0[2] |= tmp <<  0;
1681               break;
1682     case 10:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1683               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1684               buf0[2] |= tmp <<  0 | tmp << 8;
1685               break;
1686     case 11:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1687               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1688               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16;
1689               break;
1690     case 12:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1691               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1692               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1693               break;
1694     case 13:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1695               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1696               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1697               buf0[3] |= tmp <<  0;
1698               break;
1699     case 14:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1700               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1701               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1702               buf0[3] |= tmp <<  0 | tmp << 8;
1703               break;
1704     case 15:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1705               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1706               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1707               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16;
1708               break;
1709     case 16:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1710               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1711               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1712               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1713               break;
1714     case 17:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1715               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1716               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1717               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1718               buf1[0] |= tmp <<  0;
1719               break;
1720     case 18:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1721               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1722               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1723               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1724               buf1[0] |= tmp <<  0 | tmp << 8;
1725               break;
1726     case 19:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1727               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1728               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1729               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1730               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16;
1731               break;
1732     case 20:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1733               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1734               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1735               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1736               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1737               break;
1738     case 21:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1739               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1740               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1741               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1742               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1743               buf1[1] |= tmp <<  0;
1744               break;
1745     case 22:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1746               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1747               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1748               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1749               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1750               buf1[1] |= tmp <<  0 | tmp << 8;
1751               break;
1752     case 23:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1753               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1754               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1755               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1756               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1757               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16;
1758               break;
1759     case 24:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1760               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1761               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1762               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1763               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1764               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1765               break;
1766     case 25:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1767               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1768               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1769               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1770               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1771               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1772               buf1[2] |= tmp <<  0;
1773               break;
1774     case 26:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1775               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1776               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1777               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1778               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1779               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1780               buf1[2] |= tmp <<  0 | tmp << 8;
1781               break;
1782     case 27:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1783               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1784               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1785               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1786               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1787               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1788               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16;
1789               break;
1790     case 28:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1791               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1792               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1793               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1794               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1795               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1796               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1797               break;
1798     case 29:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1799               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1800               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1801               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1802               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1803               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1804               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1805               buf1[3] |= tmp <<  0;
1806               break;
1807     case 30:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1808               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1809               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1810               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1811               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1812               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1813               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1814               buf1[3] |= tmp <<  0 | tmp << 8;
1815               break;
1816     case 31:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1817               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1818               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1819               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1820               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1821               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1822               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1823               buf1[3] |= tmp <<  0 | tmp << 8 | tmp << 16;
1824               break;
1825   }
1826
1827   out_len += p0;
1828
1829   return out_len;
1830 }
1831
1832 inline u32 rule_op_mangle_dupechar_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1833 {
1834   if ( in_len       ==  0) return (in_len);
1835   if ((in_len + p0) >= 32) return (in_len);
1836
1837   const u32 in_len1 = in_len - 1;
1838
1839   const u32 sh = (in_len1 & 3) * 8;
1840
1841   u32 tmp = 0;
1842
1843   switch (in_len1 / 4)
1844   {
1845     case  0:  tmp = (buf0[0] >> sh) & 0xff; break;
1846     case  1:  tmp = (buf0[1] >> sh) & 0xff; break;
1847     case  2:  tmp = (buf0[2] >> sh) & 0xff; break;
1848     case  3:  tmp = (buf0[3] >> sh) & 0xff; break;
1849     case  4:  tmp = (buf1[0] >> sh) & 0xff; break;
1850     case  5:  tmp = (buf1[1] >> sh) & 0xff; break;
1851     case  6:  tmp = (buf1[2] >> sh) & 0xff; break;
1852     case  7:  tmp = (buf1[3] >> sh) & 0xff; break;
1853   }
1854
1855   u32 out_len = in_len;
1856
1857   for (u32 i = 0; i < p0; i++)
1858   {
1859     append_block1 (out_len, buf0, buf1, tmp);
1860
1861     out_len++;
1862   }
1863
1864   return out_len;
1865 }
1866
1867 inline u32 rule_op_mangle_dupechar_all (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1868 {
1869   if ( in_len           ==  0) return (in_len);
1870   if ((in_len + in_len) >= 32) return (in_len);
1871
1872   u32 out_len = in_len;
1873
1874   u32 tib40[4];
1875   u32 tib41[4];
1876
1877   tib40[0] = ((buf0[0] & 0x000000FF) <<  0) | ((buf0[0] & 0x0000FF00) <<  8);
1878   tib40[1] = ((buf0[0] & 0x00FF0000) >> 16) | ((buf0[0] & 0xFF000000) >>  8);
1879   tib40[2] = ((buf0[1] & 0x000000FF) <<  0) | ((buf0[1] & 0x0000FF00) <<  8);
1880   tib40[3] = ((buf0[1] & 0x00FF0000) >> 16) | ((buf0[1] & 0xFF000000) >>  8);
1881   tib41[0] = ((buf0[2] & 0x000000FF) <<  0) | ((buf0[2] & 0x0000FF00) <<  8);
1882   tib41[1] = ((buf0[2] & 0x00FF0000) >> 16) | ((buf0[2] & 0xFF000000) >>  8);
1883   tib41[2] = ((buf0[3] & 0x000000FF) <<  0) | ((buf0[3] & 0x0000FF00) <<  8);
1884   tib41[3] = ((buf0[3] & 0x00FF0000) >> 16) | ((buf0[3] & 0xFF000000) >>  8);
1885
1886   buf0[0] = tib40[0] | (tib40[0] <<  8);
1887   buf0[1] = tib40[1] | (tib40[1] <<  8);
1888   buf0[2] = tib40[2] | (tib40[2] <<  8);
1889   buf0[3] = tib40[3] | (tib40[3] <<  8);
1890   buf1[0] = tib41[0] | (tib41[0] <<  8);
1891   buf1[1] = tib41[1] | (tib41[1] <<  8);
1892   buf1[2] = tib41[2] | (tib41[2] <<  8);
1893   buf1[3] = tib41[3] | (tib41[3] <<  8);
1894
1895   out_len = out_len + out_len;
1896
1897   return out_len;
1898 }
1899
1900 inline u32 rule_op_mangle_switch_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1901 {
1902   if (in_len < 2) return (in_len);
1903
1904   buf0[0] = (buf0[0] & 0xFFFF0000) | ((buf0[0] << 8) & 0x0000FF00) | ((buf0[0] >> 8) & 0x000000FF);
1905
1906   return in_len;
1907 }
1908
1909 inline u32 rule_op_mangle_switch_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1910 {
1911   if (in_len < 2) return (in_len);
1912
1913   switch (in_len)
1914   {
1915     case  2:  buf0[0] = ((buf0[0] << 8) & 0x0000FF00) | ((buf0[0] >> 8) & 0x000000FF);
1916               break;
1917     case  3:  buf0[0] =  (buf0[0] & 0x000000FF) | ((buf0[0] <<  8) & 0x00FF0000) | ((buf0[0] >>  8) & 0x0000FF00);
1918               break;
1919     case  4:  buf0[0] =  (buf0[0] & 0x0000FFFF) | ((buf0[0] <<  8) & 0xFF000000) | ((buf0[0] >>  8) & 0x00FF0000);
1920               break;
1921     case  5:  buf0[1] =  (buf0[0] & 0xFF000000) |   buf0[1];
1922               buf0[0] =  (buf0[0] & 0x00FFFFFF) |  (buf0[1] << 24);
1923               buf0[1] =  (buf0[1] >> 24);
1924               break;
1925     case  6:  buf0[1] = ((buf0[1] << 8) & 0x0000FF00) | ((buf0[1] >> 8) & 0x000000FF);
1926               break;
1927     case  7:  buf0[1] =  (buf0[1] & 0x000000FF) | ((buf0[1] <<  8) & 0x00FF0000) | ((buf0[1] >>  8) & 0x0000FF00);
1928               break;
1929     case  8:  buf0[1] =  (buf0[1] & 0x0000FFFF) | ((buf0[1] <<  8) & 0xFF000000) | ((buf0[1] >>  8) & 0x00FF0000);
1930               break;
1931     case  9:  buf0[2] =  (buf0[1] & 0xFF000000) |   buf0[2];
1932               buf0[1] =  (buf0[1] & 0x00FFFFFF) |  (buf0[2] << 24);
1933               buf0[2] =  (buf0[2] >> 24);
1934               break;
1935     case 10:  buf0[2] = ((buf0[2] << 8) & 0x0000FF00) | ((buf0[2] >> 8) & 0x000000FF);
1936               break;
1937     case 11:  buf0[2] =  (buf0[2] & 0x000000FF) | ((buf0[2] <<  8) & 0x00FF0000) | ((buf0[2] >>  8) & 0x0000FF00);
1938               break;
1939     case 12:  buf0[2] =  (buf0[2] & 0x0000FFFF) | ((buf0[2] <<  8) & 0xFF000000) | ((buf0[2] >>  8) & 0x00FF0000);
1940               break;
1941     case 13:  buf0[3] =  (buf0[2] & 0xFF000000) |   buf0[3];
1942               buf0[2] =  (buf0[2] & 0x00FFFFFF) |  (buf0[3] << 24);
1943               buf0[3] =  (buf0[3] >> 24);
1944               break;
1945     case 14:  buf0[3] = ((buf0[3] << 8) & 0x0000FF00) | ((buf0[3] >> 8) & 0x000000FF);
1946               break;
1947     case 15:  buf0[3] =  (buf0[3] & 0x000000FF) |  ((buf0[3] <<  8) & 0x00FF0000) | ((buf0[3] >>  8) & 0x0000FF00);
1948               break;
1949     case 16:  buf0[3] =  (buf0[3] & 0x0000FFFF) | ((buf0[3] <<  8) & 0xFF000000) | ((buf0[3] >>  8) & 0x00FF0000);
1950               break;
1951     case 17:  buf1[0] =  (buf0[3] & 0xFF000000) |   buf1[0];
1952               buf0[3] =  (buf0[3] & 0x00FFFFFF) |  (buf1[0] << 24);
1953               buf1[0] =  (buf1[0] >> 24);
1954               break;
1955     case 18:  buf1[0] = ((buf1[0] << 8) & 0x0000FF00) | ((buf1[0] >> 8) & 0x000000FF);
1956               break;
1957     case 19:  buf1[0] =  (buf1[0] & 0x000000FF) | ((buf1[0] <<  8) & 0x00FF0000) | ((buf1[0] >>  8) & 0x0000FF00);
1958               break;
1959     case 20:  buf1[0] =  (buf1[0] & 0x0000FFFF) | ((buf1[0] <<  8) & 0xFF000000) | ((buf1[0] >>  8) & 0x00FF0000);
1960               break;
1961     case 21:  buf1[1] =  (buf1[0] & 0xFF000000) |   buf1[1];
1962               buf1[0] =  (buf1[0] & 0x00FFFFFF) |  (buf1[1] << 24);
1963               buf1[1] =  (buf1[1] >> 24);
1964               break;
1965     case 22:  buf1[1] = ((buf1[1] << 8) & 0x0000FF00) | ((buf1[1] >> 8) & 0x000000FF);
1966               break;
1967     case 23:  buf1[1] =  (buf1[1] & 0x000000FF) | ((buf1[1] <<  8) & 0x00FF0000) | ((buf1[1] >>  8) & 0x0000FF00);
1968               break;
1969     case 24:  buf1[1] =  (buf1[1] & 0x0000FFFF) | ((buf1[1] <<  8) & 0xFF000000) | ((buf1[1] >>  8) & 0x00FF0000);
1970               break;
1971     case 25:  buf1[2] =  (buf1[1] & 0xFF000000) |   buf1[2];
1972               buf1[1] =  (buf1[1] & 0x00FFFFFF) |  (buf1[2] << 24);
1973               buf1[2] =  (buf1[2] >> 24);
1974               break;
1975     case 26:  buf1[2] = ((buf1[2] << 8) & 0x0000FF00) | ((buf1[2] >> 8) & 0x000000FF);
1976               break;
1977     case 27:  buf1[2] =  (buf1[2] & 0x000000FF) | ((buf1[2] <<  8) & 0x00FF0000) | ((buf1[2] >>  8) & 0x0000FF00);
1978               break;
1979     case 28:  buf1[2] =  (buf1[2] & 0x0000FFFF) | ((buf1[2] <<  8) & 0xFF000000) | ((buf1[2] >>  8) & 0x00FF0000);
1980               break;
1981     case 29:  buf1[3] =  (buf1[2] & 0xFF000000) |   buf1[3];
1982               buf1[2] =  (buf1[2] & 0x00FFFFFF) |  (buf1[3] << 24);
1983               buf1[3] =  (buf1[3] >> 24);
1984               break;
1985     case 30:  buf1[3] = ((buf1[3] << 8) & 0x0000FF00) | ((buf1[3] >> 8) & 0x000000FF);
1986               break;
1987     case 31:  buf1[3] =  (buf1[3] & 0x000000FF) |  ((buf1[3] <<  8) & 0x00FF0000) | ((buf1[3] >>  8) & 0x0000FF00);
1988               break;
1989   }
1990
1991   return in_len;
1992 }
1993
1994 inline u32 rule_op_mangle_switch_at (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1995 {
1996   if (p0 >= in_len) return (in_len);
1997   if (p1 >= in_len) return (in_len);
1998
1999   u32 tmp0 = 0;
2000   u32 tmp1 = 0;
2001
2002   switch (p0)
2003   {
2004     case  0:  tmp0 = (buf0[0] >>  0) & 0xFF;
2005               break;
2006     case  1:  tmp0 = (buf0[0] >>  8) & 0xFF;
2007               break;
2008     case  2:  tmp0 = (buf0[0] >> 16) & 0xFF;
2009               break;
2010     case  3:  tmp0 = (buf0[0] >> 24) & 0xFF;
2011               break;
2012     case  4:  tmp0 = (buf0[1] >>  0) & 0xFF;
2013               break;
2014     case  5:  tmp0 = (buf0[1] >>  8) & 0xFF;
2015               break;
2016     case  6:  tmp0 = (buf0[1] >> 16) & 0xFF;
2017               break;
2018     case  7:  tmp0 = (buf0[1] >> 24) & 0xFF;
2019               break;
2020     case  8:  tmp0 = (buf0[2] >>  0) & 0xFF;
2021               break;
2022     case  9:  tmp0 = (buf0[2] >>  8) & 0xFF;
2023               break;
2024     case 10:  tmp0 = (buf0[2] >> 16) & 0xFF;
2025               break;
2026     case 11:  tmp0 = (buf0[2] >> 24) & 0xFF;
2027               break;
2028     case 12:  tmp0 = (buf0[3] >>  0) & 0xFF;
2029               break;
2030     case 13:  tmp0 = (buf0[3] >>  8) & 0xFF;
2031               break;
2032     case 14:  tmp0 = (buf0[3] >> 16) & 0xFF;
2033               break;
2034     case 15:  tmp0 = (buf0[3] >> 24) & 0xFF;
2035               break;
2036     case 16:  tmp0 = (buf1[0] >>  0) & 0xFF;
2037               break;
2038     case 17:  tmp0 = (buf1[0] >>  8) & 0xFF;
2039               break;
2040     case 18:  tmp0 = (buf1[0] >> 16) & 0xFF;
2041               break;
2042     case 19:  tmp0 = (buf1[0] >> 24) & 0xFF;
2043               break;
2044     case 20:  tmp0 = (buf1[1] >>  0) & 0xFF;
2045               break;
2046     case 21:  tmp0 = (buf1[1] >>  8) & 0xFF;
2047               break;
2048     case 22:  tmp0 = (buf1[1] >> 16) & 0xFF;
2049               break;
2050     case 23:  tmp0 = (buf1[1] >> 24) & 0xFF;
2051               break;
2052     case 24:  tmp0 = (buf1[2] >>  0) & 0xFF;
2053               break;
2054     case 25:  tmp0 = (buf1[2] >>  8) & 0xFF;
2055               break;
2056     case 26:  tmp0 = (buf1[2] >> 16) & 0xFF;
2057               break;
2058     case 27:  tmp0 = (buf1[2] >> 24) & 0xFF;
2059               break;
2060     case 28:  tmp0 = (buf1[3] >>  0) & 0xFF;
2061               break;
2062     case 29:  tmp0 = (buf1[3] >>  8) & 0xFF;
2063               break;
2064     case 30:  tmp0 = (buf1[3] >> 16) & 0xFF;
2065               break;
2066     case 31:  tmp0 = (buf1[3] >> 24) & 0xFF;
2067               break;
2068   }
2069
2070   switch (p1)
2071   {
2072     case  0:  tmp1 = (buf0[0] >>  0) & 0xff;
2073               buf0[0]  = (buf0[0] & 0xffffff00) | tmp0 <<  0;
2074               break;
2075     case  1:  tmp1 = (buf0[0] >>  8) & 0xff;
2076               buf0[0]  = (buf0[0] & 0xffff00ff) | tmp0 <<  8;
2077               break;
2078     case  2:  tmp1 = (buf0[0] >> 16) & 0xff;
2079               buf0[0]  = (buf0[0] & 0xff00ffff) | tmp0 << 16;
2080               break;
2081     case  3:  tmp1 = (buf0[0] >> 24) & 0xff;
2082               buf0[0]  = (buf0[0] & 0x00ffffff) | tmp0 << 24;
2083               break;
2084     case  4:  tmp1 = (buf0[1] >>  0) & 0xff;
2085               buf0[1]  = (buf0[1] & 0xffffff00) | tmp0 <<  0;
2086               break;
2087     case  5:  tmp1 = (buf0[1] >>  8) & 0xff;
2088               buf0[1]  = (buf0[1] & 0xffff00ff) | tmp0 <<  8;
2089               break;
2090     case  6:  tmp1 = (buf0[1] >> 16) & 0xff;
2091               buf0[1]  = (buf0[1] & 0xff00ffff) | tmp0 << 16;
2092               break;
2093     case  7:  tmp1 = (buf0[1] >> 24) & 0xff;
2094               buf0[1]  = (buf0[1] & 0x00ffffff) | tmp0 << 24;
2095               break;
2096     case  8:  tmp1 = (buf0[2] >>  0) & 0xff;
2097               buf0[2]  = (buf0[2] & 0xffffff00) | tmp0 <<  0;
2098               break;
2099     case  9:  tmp1 = (buf0[2] >>  8) & 0xff;
2100               buf0[2]  = (buf0[2] & 0xffff00ff) | tmp0 <<  8;
2101               break;
2102     case 10:  tmp1 = (buf0[2] >> 16) & 0xff;
2103               buf0[2]  = (buf0[2] & 0xff00ffff) | tmp0 << 16;
2104               break;
2105     case 11:  tmp1 = (buf0[2] >> 24) & 0xff;
2106               buf0[2]  = (buf0[2] & 0x00ffffff) | tmp0 << 24;
2107               break;
2108     case 12:  tmp1 = (buf0[3] >>  0) & 0xff;
2109               buf0[3]  = (buf0[3] & 0xffffff00) | tmp0 <<  0;
2110               break;
2111     case 13:  tmp1 = (buf0[3] >>  8) & 0xff;
2112               buf0[3]  = (buf0[3] & 0xffff00ff) | tmp0 <<  8;
2113               break;
2114     case 14:  tmp1 = (buf0[3] >> 16) & 0xff;
2115               buf0[3]  = (buf0[3] & 0xff00ffff) | tmp0 << 16;
2116               break;
2117     case 15:  tmp1 = (buf0[3] >> 24) & 0xff;
2118               buf0[3]  = (buf0[3] & 0x00ffffff) | tmp0 << 24;
2119               break;
2120     case 16:  tmp1 = (buf1[0] >>  0) & 0xff;
2121               buf1[0]  = (buf1[0] & 0xffffff00) | tmp0 <<  0;
2122               break;
2123     case 17:  tmp1 = (buf1[0] >>  8) & 0xff;
2124               buf1[0]  = (buf1[0] & 0xffff00ff) | tmp0 <<  8;
2125               break;
2126     case 18:  tmp1 = (buf1[0] >> 16) & 0xff;
2127               buf1[0]  = (buf1[0] & 0xff00ffff) | tmp0 << 16;
2128               break;
2129     case 19:  tmp1 = (buf1[0] >> 24) & 0xff;
2130               buf1[0]  = (buf1[0] & 0x00ffffff) | tmp0 << 24;
2131               break;
2132     case 20:  tmp1 = (buf1[1] >>  0) & 0xff;
2133               buf1[1]  = (buf1[1] & 0xffffff00) | tmp0 <<  0;
2134               break;
2135     case 21:  tmp1 = (buf1[1] >>  8) & 0xff;
2136               buf1[1]  = (buf1[1] & 0xffff00ff) | tmp0 <<  8;
2137               break;
2138     case 22:  tmp1 = (buf1[1] >> 16) & 0xff;
2139               buf1[1]  = (buf1[1] & 0xff00ffff) | tmp0 << 16;
2140               break;
2141     case 23:  tmp1 = (buf1[1] >> 24) & 0xff;
2142               buf1[1]  = (buf1[1] & 0x00ffffff) | tmp0 << 24;
2143               break;
2144     case 24:  tmp1 = (buf1[2] >>  0) & 0xff;
2145               buf1[2]  = (buf1[2] & 0xffffff00) | tmp0 <<  0;
2146               break;
2147     case 25:  tmp1 = (buf1[2] >>  8) & 0xff;
2148               buf1[2]  = (buf1[2] & 0xffff00ff) | tmp0 <<  8;
2149               break;
2150     case 26:  tmp1 = (buf1[2] >> 16) & 0xff;
2151               buf1[2]  = (buf1[2] & 0xff00ffff) | tmp0 << 16;
2152               break;
2153     case 27:  tmp1 = (buf1[2] >> 24) & 0xff;
2154               buf1[2]  = (buf1[2] & 0x00ffffff) | tmp0 << 24;
2155               break;
2156     case 28:  tmp1 = (buf1[3] >>  0) & 0xff;
2157               buf1[3]  = (buf1[3] & 0xffffff00) | tmp0 <<  0;
2158               break;
2159     case 29:  tmp1 = (buf1[3] >>  8) & 0xff;
2160               buf1[3]  = (buf1[3] & 0xffff00ff) | tmp0 <<  8;
2161               break;
2162     case 30:  tmp1 = (buf1[3] >> 16) & 0xff;
2163               buf1[3]  = (buf1[3] & 0xff00ffff) | tmp0 << 16;
2164               break;
2165     case 31:  tmp1 = (buf1[3] >> 24) & 0xff;
2166               buf1[3]  = (buf1[3] & 0x00ffffff) | tmp0 << 24;
2167               break;
2168   }
2169
2170   switch (p0)
2171   {
2172     case  0:  buf0[0]  = (buf0[0] & 0xffffff00) | tmp1 <<  0;
2173               break;
2174     case  1:  buf0[0]  = (buf0[0] & 0xffff00ff) | tmp1 <<  8;
2175               break;
2176     case  2:  buf0[0]  = (buf0[0] & 0xff00ffff) | tmp1 << 16;
2177               break;
2178     case  3:  buf0[0]  = (buf0[0] & 0x00ffffff) | tmp1 << 24;
2179               break;
2180     case  4:  buf0[1]  = (buf0[1] & 0xffffff00) | tmp1 <<  0;
2181               break;
2182     case  5:  buf0[1]  = (buf0[1] & 0xffff00ff) | tmp1 <<  8;
2183               break;
2184     case  6:  buf0[1]  = (buf0[1] & 0xff00ffff) | tmp1 << 16;
2185               break;
2186     case  7:  buf0[1]  = (buf0[1] & 0x00ffffff) | tmp1 << 24;
2187               break;
2188     case  8:  buf0[2]  = (buf0[2] & 0xffffff00) | tmp1 <<  0;
2189               break;
2190     case  9:  buf0[2]  = (buf0[2] & 0xffff00ff) | tmp1 <<  8;
2191               break;
2192     case 10:  buf0[2]  = (buf0[2] & 0xff00ffff) | tmp1 << 16;
2193               break;
2194     case 11:  buf0[2]  = (buf0[2] & 0x00ffffff) | tmp1 << 24;
2195               break;
2196     case 12:  buf0[3]  = (buf0[3] & 0xffffff00) | tmp1 <<  0;
2197               break;
2198     case 13:  buf0[3]  = (buf0[3] & 0xffff00ff) | tmp1 <<  8;
2199               break;
2200     case 14:  buf0[3]  = (buf0[3] & 0xff00ffff) | tmp1 << 16;
2201               break;
2202     case 15:  buf0[3]  = (buf0[3] & 0x00ffffff) | tmp1 << 24;
2203               break;
2204     case 16:  buf1[0]  = (buf1[0] & 0xffffff00) | tmp1 <<  0;
2205               break;
2206     case 17:  buf1[0]  = (buf1[0] & 0xffff00ff) | tmp1 <<  8;
2207               break;
2208     case 18:  buf1[0]  = (buf1[0] & 0xff00ffff) | tmp1 << 16;
2209               break;
2210     case 19:  buf1[0]  = (buf1[0] & 0x00ffffff) | tmp1 << 24;
2211               break;
2212     case 20:  buf1[1]  = (buf1[1] & 0xffffff00) | tmp1 <<  0;
2213               break;
2214     case 21:  buf1[1]  = (buf1[1] & 0xffff00ff) | tmp1 <<  8;
2215               break;
2216     case 22:  buf1[1]  = (buf1[1] & 0xff00ffff) | tmp1 << 16;
2217               break;
2218     case 23:  buf1[1]  = (buf1[1] & 0x00ffffff) | tmp1 << 24;
2219               break;
2220     case 24:  buf1[2]  = (buf1[2] & 0xffffff00) | tmp1 <<  0;
2221               break;
2222     case 25:  buf1[2]  = (buf1[2] & 0xffff00ff) | tmp1 <<  8;
2223               break;
2224     case 26:  buf1[2]  = (buf1[2] & 0xff00ffff) | tmp1 << 16;
2225               break;
2226     case 27:  buf1[2]  = (buf1[2] & 0x00ffffff) | tmp1 << 24;
2227               break;
2228     case 28:  buf1[3]  = (buf1[3] & 0xffffff00) | tmp1 <<  0;
2229               break;
2230     case 29:  buf1[3]  = (buf1[3] & 0xffff00ff) | tmp1 <<  8;
2231               break;
2232     case 30:  buf1[3]  = (buf1[3] & 0xff00ffff) | tmp1 << 16;
2233               break;
2234     case 31:  buf1[3]  = (buf1[3] & 0x00ffffff) | tmp1 << 24;
2235               break;
2236   }
2237
2238   return in_len;
2239 }
2240
2241 inline u32 rule_op_mangle_chr_shiftl (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2242 {
2243   if (p0 >= in_len) return (in_len);
2244
2245   const u32 mr = 0xffu << ((p0 & 3) * 8);
2246   const u32 ml = ~mr;
2247
2248   switch (p0 / 4)
2249   {
2250     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) << 1) & mr); break;
2251     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) << 1) & mr); break;
2252     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) << 1) & mr); break;
2253     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) << 1) & mr); break;
2254     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) << 1) & mr); break;
2255     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) << 1) & mr); break;
2256     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) << 1) & mr); break;
2257     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) << 1) & mr); break;
2258   }
2259
2260   return in_len;
2261 }
2262
2263 inline u32 rule_op_mangle_chr_shiftr (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2264 {
2265   if (p0 >= in_len) return (in_len);
2266
2267   const u32 mr = 0xffu << ((p0 & 3) * 8);
2268   const u32 ml = ~mr;
2269
2270   switch (p0 / 4)
2271   {
2272     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) >> 1) & mr); break;
2273     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) >> 1) & mr); break;
2274     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) >> 1) & mr); break;
2275     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) >> 1) & mr); break;
2276     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) >> 1) & mr); break;
2277     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) >> 1) & mr); break;
2278     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) >> 1) & mr); break;
2279     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) >> 1) & mr); break;
2280   }
2281
2282   return in_len;
2283 }
2284
2285 inline u32 rule_op_mangle_chr_incr (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2286 {
2287   if (p0 >= in_len) return (in_len);
2288
2289   const u32 mr = 0xffu << ((p0 & 3) * 8);
2290   const u32 ml = ~mr;
2291
2292   const u32 n = 0x01010101 & mr;
2293
2294   switch (p0 / 4)
2295   {
2296     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) + n) & mr); break;
2297     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) + n) & mr); break;
2298     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) + n) & mr); break;
2299     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) + n) & mr); break;
2300     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) + n) & mr); break;
2301     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) + n) & mr); break;
2302     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) + n) & mr); break;
2303     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) + n) & mr); break;
2304   }
2305
2306   return in_len;
2307 }
2308
2309 inline u32 rule_op_mangle_chr_decr (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2310 {
2311   if (p0 >= in_len) return (in_len);
2312
2313   const u32 mr = 0xffu << ((p0 & 3) * 8);
2314   const u32 ml = ~mr;
2315
2316   const u32 n = 0x01010101 & mr;
2317
2318   switch (p0 / 4)
2319   {
2320     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) - n) & mr); break;
2321     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) - n) & mr); break;
2322     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) - n) & mr); break;
2323     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) - n) & mr); break;
2324     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) - n) & mr); break;
2325     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) - n) & mr); break;
2326     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) - n) & mr); break;
2327     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) - n) & mr); break;
2328   }
2329
2330   return in_len;
2331 }
2332
2333 inline u32 rule_op_mangle_replace_np1 (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2334 {
2335   if ((p0 + 1) >= in_len) return (in_len);
2336
2337   u32 tib40[4];
2338   u32 tib41[4];
2339
2340   lshift_block (buf0, buf1, tib40, tib41);
2341
2342   const u32 mr = 0xffu << ((p0 & 3) * 8);
2343   const u32 ml = ~mr;
2344
2345   switch (p0 / 4)
2346   {
2347     case  0:  buf0[0] = (buf0[0] & ml) | (tib40[0] & mr); break;
2348     case  1:  buf0[1] = (buf0[1] & ml) | (tib40[1] & mr); break;
2349     case  2:  buf0[2] = (buf0[2] & ml) | (tib40[2] & mr); break;
2350     case  3:  buf0[3] = (buf0[3] & ml) | (tib40[3] & mr); break;
2351     case  4:  buf1[0] = (buf1[0] & ml) | (tib41[0] & mr); break;
2352     case  5:  buf1[1] = (buf1[1] & ml) | (tib41[1] & mr); break;
2353     case  6:  buf1[2] = (buf1[2] & ml) | (tib41[2] & mr); break;
2354     case  7:  buf1[3] = (buf1[3] & ml) | (tib41[3] & mr); break;
2355   }
2356
2357   return in_len;
2358 }
2359
2360 inline u32 rule_op_mangle_replace_nm1 (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2361 {
2362   if (p0 == 0) return (in_len);
2363
2364   if (p0 >= in_len) return (in_len);
2365
2366   u32 tib40[4];
2367   u32 tib41[4];
2368
2369   rshift_block (buf0, buf1, tib40, tib41);
2370
2371   const u32 mr = 0xffu << ((p0 & 3) * 8);
2372   const u32 ml = ~mr;
2373
2374   switch (p0 / 4)
2375   {
2376     case  0:  buf0[0] = (buf0[0] & ml) | (tib40[0] & mr); break;
2377     case  1:  buf0[1] = (buf0[1] & ml) | (tib40[1] & mr); break;
2378     case  2:  buf0[2] = (buf0[2] & ml) | (tib40[2] & mr); break;
2379     case  3:  buf0[3] = (buf0[3] & ml) | (tib40[3] & mr); break;
2380     case  4:  buf1[0] = (buf1[0] & ml) | (tib41[0] & mr); break;
2381     case  5:  buf1[1] = (buf1[1] & ml) | (tib41[1] & mr); break;
2382     case  6:  buf1[2] = (buf1[2] & ml) | (tib41[2] & mr); break;
2383     case  7:  buf1[3] = (buf1[3] & ml) | (tib41[3] & mr); break;
2384   }
2385
2386   return in_len;
2387 }
2388
2389 inline u32 rule_op_mangle_dupeblock_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2390 {
2391   if (p0 > in_len) return (in_len);
2392
2393   if ((in_len + p0) >= 32) return (in_len);
2394
2395   u32 out_len = in_len;
2396
2397   u32 tib40[4];
2398   u32 tib41[4];
2399
2400   tib40[0] = buf0[0];
2401   tib40[1] = buf0[1];
2402   tib40[2] = buf0[2];
2403   tib40[3] = buf0[3];
2404   tib41[0] = buf1[0];
2405   tib41[1] = buf1[1];
2406   tib41[2] = buf1[2];
2407   tib41[3] = buf1[3];
2408
2409   truncate_right (tib40, tib41, p0);
2410
2411   rshift_block_N (buf0, buf1, buf0, buf1, p0);
2412
2413   buf0[0] |= tib40[0];
2414   buf0[1] |= tib40[1];
2415   buf0[2] |= tib40[2];
2416   buf0[3] |= tib40[3];
2417   buf1[0] |= tib41[0];
2418   buf1[1] |= tib41[1];
2419   buf1[2] |= tib41[2];
2420   buf1[3] |= tib41[3];
2421
2422   out_len += p0;
2423
2424   return out_len;
2425 }
2426
2427 inline u32 rule_op_mangle_dupeblock_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2428 {
2429   if (p0 > in_len) return (in_len);
2430
2431   if ((in_len + p0) >= 32) return (in_len);
2432
2433   u32 out_len = in_len;
2434
2435   u32 tib40[4];
2436   u32 tib41[4];
2437
2438   rshift_block_N (buf0, buf1, tib40, tib41, p0);
2439
2440   truncate_left (tib40, tib41, out_len);
2441
2442   buf0[0] |= tib40[0];
2443   buf0[1] |= tib40[1];
2444   buf0[2] |= tib40[2];
2445   buf0[3] |= tib40[3];
2446   buf1[0] |= tib41[0];
2447   buf1[1] |= tib41[1];
2448   buf1[2] |= tib41[2];
2449   buf1[3] |= tib41[3];
2450
2451   out_len += p0;
2452
2453   return out_len;
2454 }
2455
2456 inline u32 rule_op_mangle_title (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2457 {
2458   buf0[0] |= (generate_cmask (buf0[0]));
2459   buf0[1] |= (generate_cmask (buf0[1]));
2460   buf0[2] |= (generate_cmask (buf0[2]));
2461   buf0[3] |= (generate_cmask (buf0[3]));
2462   buf1[0] |= (generate_cmask (buf1[0]));
2463   buf1[1] |= (generate_cmask (buf1[1]));
2464   buf1[2] |= (generate_cmask (buf1[2]));
2465   buf1[3] |= (generate_cmask (buf1[3]));
2466
2467   u32 tib40[4];
2468   u32 tib41[4];
2469
2470   const uchar4 tmp0 = (uchar4) (' ');
2471   const uchar4 tmp1 = (uchar4) (0x00);
2472   const uchar4 tmp2 = (uchar4) (0xff);
2473
2474   uchar4 tmp;
2475
2476   tmp = as_uchar4 (buf0[0]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[0] = as_uint (tmp);
2477   tmp = as_uchar4 (buf0[1]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[1] = as_uint (tmp);
2478   tmp = as_uchar4 (buf0[2]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[2] = as_uint (tmp);
2479   tmp = as_uchar4 (buf0[3]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[3] = as_uint (tmp);
2480   tmp = as_uchar4 (buf1[0]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[0] = as_uint (tmp);
2481   tmp = as_uchar4 (buf1[1]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[1] = as_uint (tmp);
2482   tmp = as_uchar4 (buf1[2]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[2] = as_uint (tmp);
2483   tmp = as_uchar4 (buf1[3]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[3] = as_uint (tmp);
2484
2485   rshift_block (tib40, tib41, tib40, tib41); tib40[0] |= 0xff;
2486
2487   buf0[0] &= ~(generate_cmask (buf0[0]) & tib40[0]);
2488   buf0[1] &= ~(generate_cmask (buf0[1]) & tib40[1]);
2489   buf0[2] &= ~(generate_cmask (buf0[2]) & tib40[2]);
2490   buf0[3] &= ~(generate_cmask (buf0[3]) & tib40[3]);
2491   buf1[0] &= ~(generate_cmask (buf1[0]) & tib41[0]);
2492   buf1[1] &= ~(generate_cmask (buf1[1]) & tib41[1]);
2493   buf1[2] &= ~(generate_cmask (buf1[2]) & tib41[2]);
2494   buf1[3] &= ~(generate_cmask (buf1[3]) & tib41[3]);
2495
2496   return in_len;
2497 }
2498
2499 inline u32 apply_rule (const u32 name, const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2500 {
2501   u32 out_len = in_len;
2502
2503   switch (name)
2504   {
2505     case RULE_OP_MANGLE_LREST:            out_len = rule_op_mangle_lrest            (p0, p1, buf0, buf1, out_len); break;
2506     case RULE_OP_MANGLE_UREST:            out_len = rule_op_mangle_urest            (p0, p1, buf0, buf1, out_len); break;
2507     case RULE_OP_MANGLE_LREST_UFIRST:     out_len = rule_op_mangle_lrest_ufirst     (p0, p1, buf0, buf1, out_len); break;
2508     case RULE_OP_MANGLE_UREST_LFIRST:     out_len = rule_op_mangle_urest_lfirst     (p0, p1, buf0, buf1, out_len); break;
2509     case RULE_OP_MANGLE_TREST:            out_len = rule_op_mangle_trest            (p0, p1, buf0, buf1, out_len); break;
2510     case RULE_OP_MANGLE_TOGGLE_AT:        out_len = rule_op_mangle_toggle_at        (p0, p1, buf0, buf1, out_len); break;
2511     case RULE_OP_MANGLE_REVERSE:          out_len = rule_op_mangle_reverse          (p0, p1, buf0, buf1, out_len); break;
2512     case RULE_OP_MANGLE_DUPEWORD:         out_len = rule_op_mangle_dupeword         (p0, p1, buf0, buf1, out_len); break;
2513     case RULE_OP_MANGLE_DUPEWORD_TIMES:   out_len = rule_op_mangle_dupeword_times   (p0, p1, buf0, buf1, out_len); break;
2514     case RULE_OP_MANGLE_REFLECT:          out_len = rule_op_mangle_reflect          (p0, p1, buf0, buf1, out_len); break;
2515     case RULE_OP_MANGLE_APPEND:           out_len = rule_op_mangle_append           (p0, p1, buf0, buf1, out_len); break;
2516     case RULE_OP_MANGLE_PREPEND:          out_len = rule_op_mangle_prepend          (p0, p1, buf0, buf1, out_len); break;
2517     case RULE_OP_MANGLE_ROTATE_LEFT:      out_len = rule_op_mangle_rotate_left      (p0, p1, buf0, buf1, out_len); break;
2518     case RULE_OP_MANGLE_ROTATE_RIGHT:     out_len = rule_op_mangle_rotate_right     (p0, p1, buf0, buf1, out_len); break;
2519     case RULE_OP_MANGLE_DELETE_FIRST:     out_len = rule_op_mangle_delete_first     (p0, p1, buf0, buf1, out_len); break;
2520     case RULE_OP_MANGLE_DELETE_LAST:      out_len = rule_op_mangle_delete_last      (p0, p1, buf0, buf1, out_len); break;
2521     case RULE_OP_MANGLE_DELETE_AT:        out_len = rule_op_mangle_delete_at        (p0, p1, buf0, buf1, out_len); break;
2522     case RULE_OP_MANGLE_EXTRACT:          out_len = rule_op_mangle_extract          (p0, p1, buf0, buf1, out_len); break;
2523     case RULE_OP_MANGLE_OMIT:             out_len = rule_op_mangle_omit             (p0, p1, buf0, buf1, out_len); break;
2524     case RULE_OP_MANGLE_INSERT:           out_len = rule_op_mangle_insert           (p0, p1, buf0, buf1, out_len); break;
2525     case RULE_OP_MANGLE_OVERSTRIKE:       out_len = rule_op_mangle_overstrike       (p0, p1, buf0, buf1, out_len); break;
2526     case RULE_OP_MANGLE_TRUNCATE_AT:      out_len = rule_op_mangle_truncate_at      (p0, p1, buf0, buf1, out_len); break;
2527     case RULE_OP_MANGLE_REPLACE:          out_len = rule_op_mangle_replace          (p0, p1, buf0, buf1, out_len); break;
2528     case RULE_OP_MANGLE_PURGECHAR:        out_len = rule_op_mangle_purgechar        (p0, p1, buf0, buf1, out_len); break;
2529     //case RULE_OP_MANGLE_TOGGLECASE_REC:   out_len = rule_op_mangle_togglecase_rec   (p0, p1, buf0, buf1, out_len); break;
2530     case RULE_OP_MANGLE_DUPECHAR_FIRST:   out_len = rule_op_mangle_dupechar_first   (p0, p1, buf0, buf1, out_len); break;
2531     case RULE_OP_MANGLE_DUPECHAR_LAST:    out_len = rule_op_mangle_dupechar_last    (p0, p1, buf0, buf1, out_len); break;
2532     case RULE_OP_MANGLE_DUPECHAR_ALL:     out_len = rule_op_mangle_dupechar_all     (p0, p1, buf0, buf1, out_len); break;
2533     case RULE_OP_MANGLE_SWITCH_FIRST:     out_len = rule_op_mangle_switch_first     (p0, p1, buf0, buf1, out_len); break;
2534     case RULE_OP_MANGLE_SWITCH_LAST:      out_len = rule_op_mangle_switch_last      (p0, p1, buf0, buf1, out_len); break;
2535     case RULE_OP_MANGLE_SWITCH_AT:        out_len = rule_op_mangle_switch_at        (p0, p1, buf0, buf1, out_len); break;
2536     case RULE_OP_MANGLE_CHR_SHIFTL:       out_len = rule_op_mangle_chr_shiftl       (p0, p1, buf0, buf1, out_len); break;
2537     case RULE_OP_MANGLE_CHR_SHIFTR:       out_len = rule_op_mangle_chr_shiftr       (p0, p1, buf0, buf1, out_len); break;
2538     case RULE_OP_MANGLE_CHR_INCR:         out_len = rule_op_mangle_chr_incr         (p0, p1, buf0, buf1, out_len); break;
2539     case RULE_OP_MANGLE_CHR_DECR:         out_len = rule_op_mangle_chr_decr         (p0, p1, buf0, buf1, out_len); break;
2540     case RULE_OP_MANGLE_REPLACE_NP1:      out_len = rule_op_mangle_replace_np1      (p0, p1, buf0, buf1, out_len); break;
2541     case RULE_OP_MANGLE_REPLACE_NM1:      out_len = rule_op_mangle_replace_nm1      (p0, p1, buf0, buf1, out_len); break;
2542     case RULE_OP_MANGLE_DUPEBLOCK_FIRST:  out_len = rule_op_mangle_dupeblock_first  (p0, p1, buf0, buf1, out_len); break;
2543     case RULE_OP_MANGLE_DUPEBLOCK_LAST:   out_len = rule_op_mangle_dupeblock_last   (p0, p1, buf0, buf1, out_len); break;
2544     case RULE_OP_MANGLE_TITLE:            out_len = rule_op_mangle_title            (p0, p1, buf0, buf1, out_len); break;
2545   }
2546
2547   return out_len;
2548 }
2549
2550 inline u32 apply_rules (const __global u32 *cmds, u32 buf0[4], u32 buf1[4], const u32 len)
2551 {
2552   u32 out_len = len;
2553
2554   for (u32 i = 0; cmds[i] != 0; i++)
2555   {
2556     const u32 cmd = cmds[i];
2557
2558     const u32 name = (cmd >>  0) & 0xff;
2559     const u32 p0   = (cmd >>  8) & 0xff;
2560     const u32 p1   = (cmd >> 16) & 0xff;
2561
2562     out_len = apply_rule (name, p0, p1, buf0, buf1, out_len);
2563   }
2564
2565   return out_len;
2566 }
2567
2568 inline u32x apply_rules_vect (const u32 pw_buf0[4], const u32 pw_buf1[4], const u32 pw_len, const __global kernel_rule_t *rules_buf, const u32 il_pos, u32x w0[4], u32x w1[4])
2569 {
2570   #if VECT_SIZE == 1
2571
2572   w0[0] = pw_buf0[0];
2573   w0[1] = pw_buf0[1];
2574   w0[2] = pw_buf0[2];
2575   w0[3] = pw_buf0[3];
2576   w1[0] = pw_buf1[0];
2577   w1[1] = pw_buf1[1];
2578   w1[2] = pw_buf1[2];
2579   w1[3] = pw_buf1[3];
2580
2581   return apply_rules (rules_buf[il_pos].cmds, w0, w1, pw_len);
2582
2583   #else
2584
2585   u32x out_len = 0;
2586
2587   #ifdef _unroll
2588   #pragma unroll
2589   #endif
2590   for (int i = 0; i < VECT_SIZE; i++)
2591   {
2592     u32 tmp0[4];
2593     u32 tmp1[4];
2594
2595     tmp0[0] = pw_buf0[0];
2596     tmp0[1] = pw_buf0[1];
2597     tmp0[2] = pw_buf0[2];
2598     tmp0[3] = pw_buf0[3];
2599     tmp1[0] = pw_buf1[0];
2600     tmp1[1] = pw_buf1[1];
2601     tmp1[2] = pw_buf1[2];
2602     tmp1[3] = pw_buf1[3];
2603
2604     const u32 tmp_len = apply_rules (rules_buf[il_pos + i].cmds, tmp0, tmp1, pw_len);
2605
2606     switch (i)
2607     {
2608       #if VECT_SIZE >= 2
2609       case 0:
2610         w0[0].s0 = tmp0[0];
2611         w0[1].s0 = tmp0[1];
2612         w0[2].s0 = tmp0[2];
2613         w0[3].s0 = tmp0[3];
2614         w1[0].s0 = tmp1[0];
2615         w1[1].s0 = tmp1[1];
2616         w1[2].s0 = tmp1[2];
2617         w1[3].s0 = tmp1[3];
2618         out_len.s0 = tmp_len;
2619         break;
2620
2621       case 1:
2622         w0[0].s1 = tmp0[0];
2623         w0[1].s1 = tmp0[1];
2624         w0[2].s1 = tmp0[2];
2625         w0[3].s1 = tmp0[3];
2626         w1[0].s1 = tmp1[0];
2627         w1[1].s1 = tmp1[1];
2628         w1[2].s1 = tmp1[2];
2629         w1[3].s1 = tmp1[3];
2630         out_len.s1 = tmp_len;
2631         break;
2632       #endif
2633
2634       #if VECT_SIZE >= 4
2635       case 2:
2636         w0[0].s2 = tmp0[0];
2637         w0[1].s2 = tmp0[1];
2638         w0[2].s2 = tmp0[2];
2639         w0[3].s2 = tmp0[3];
2640         w1[0].s2 = tmp1[0];
2641         w1[1].s2 = tmp1[1];
2642         w1[2].s2 = tmp1[2];
2643         w1[3].s2 = tmp1[3];
2644         out_len.s2 = tmp_len;
2645         break;
2646
2647       case 3:
2648         w0[0].s3 = tmp0[0];
2649         w0[1].s3 = tmp0[1];
2650         w0[2].s3 = tmp0[2];
2651         w0[3].s3 = tmp0[3];
2652         w1[0].s3 = tmp1[0];
2653         w1[1].s3 = tmp1[1];
2654         w1[2].s3 = tmp1[2];
2655         w1[3].s3 = tmp1[3];
2656         out_len.s3 = tmp_len;
2657         break;
2658       #endif
2659
2660       #if VECT_SIZE >= 8
2661       case 4:
2662         w0[0].s4 = tmp0[0];
2663         w0[1].s4 = tmp0[1];
2664         w0[2].s4 = tmp0[2];
2665         w0[3].s4 = tmp0[3];
2666         w1[0].s4 = tmp1[0];
2667         w1[1].s4 = tmp1[1];
2668         w1[2].s4 = tmp1[2];
2669         w1[3].s4 = tmp1[3];
2670         out_len.s4 = tmp_len;
2671         break;
2672
2673       case 5:
2674         w0[0].s5 = tmp0[0];
2675         w0[1].s5 = tmp0[1];
2676         w0[2].s5 = tmp0[2];
2677         w0[3].s5 = tmp0[3];
2678         w1[0].s5 = tmp1[0];
2679         w1[1].s5 = tmp1[1];
2680         w1[2].s5 = tmp1[2];
2681         w1[3].s5 = tmp1[3];
2682         out_len.s5 = tmp_len;
2683         break;
2684
2685       case 6:
2686         w0[0].s6 = tmp0[0];
2687         w0[1].s6 = tmp0[1];
2688         w0[2].s6 = tmp0[2];
2689         w0[3].s6 = tmp0[3];
2690         w1[0].s6 = tmp1[0];
2691         w1[1].s6 = tmp1[1];
2692         w1[2].s6 = tmp1[2];
2693         w1[3].s6 = tmp1[3];
2694         out_len.s6 = tmp_len;
2695         break;
2696
2697       case 7:
2698         w0[0].s7 = tmp0[0];
2699         w0[1].s7 = tmp0[1];
2700         w0[2].s7 = tmp0[2];
2701         w0[3].s7 = tmp0[3];
2702         w1[0].s7 = tmp1[0];
2703         w1[1].s7 = tmp1[1];
2704         w1[2].s7 = tmp1[2];
2705         w1[3].s7 = tmp1[3];
2706         out_len.s7 = tmp_len;
2707         break;
2708       #endif
2709
2710       #if VECT_SIZE >= 16
2711       case 8:
2712         w0[0].s8 = tmp0[0];
2713         w0[1].s8 = tmp0[1];
2714         w0[2].s8 = tmp0[2];
2715         w0[3].s8 = tmp0[3];
2716         w1[0].s8 = tmp1[0];
2717         w1[1].s8 = tmp1[1];
2718         w1[2].s8 = tmp1[2];
2719         w1[3].s8 = tmp1[3];
2720         out_len.s8 = tmp_len;
2721         break;
2722
2723       case 9:
2724         w0[0].s9 = tmp0[0];
2725         w0[1].s9 = tmp0[1];
2726         w0[2].s9 = tmp0[2];
2727         w0[3].s9 = tmp0[3];
2728         w1[0].s9 = tmp1[0];
2729         w1[1].s9 = tmp1[1];
2730         w1[2].s9 = tmp1[2];
2731         w1[3].s9 = tmp1[3];
2732         out_len.s9 = tmp_len;
2733         break;
2734
2735       case 10:
2736         w0[0].sa = tmp0[0];
2737         w0[1].sa = tmp0[1];
2738         w0[2].sa = tmp0[2];
2739         w0[3].sa = tmp0[3];
2740         w1[0].sa = tmp1[0];
2741         w1[1].sa = tmp1[1];
2742         w1[2].sa = tmp1[2];
2743         w1[3].sa = tmp1[3];
2744         out_len.sa = tmp_len;
2745         break;
2746
2747       case 11:
2748         w0[0].sb = tmp0[0];
2749         w0[1].sb = tmp0[1];
2750         w0[2].sb = tmp0[2];
2751         w0[3].sb = tmp0[3];
2752         w1[0].sb = tmp1[0];
2753         w1[1].sb = tmp1[1];
2754         w1[2].sb = tmp1[2];
2755         w1[3].sb = tmp1[3];
2756         out_len.sb = tmp_len;
2757         break;
2758
2759       case 12:
2760         w0[0].sc = tmp0[0];
2761         w0[1].sc = tmp0[1];
2762         w0[2].sc = tmp0[2];
2763         w0[3].sc = tmp0[3];
2764         w1[0].sc = tmp1[0];
2765         w1[1].sc = tmp1[1];
2766         w1[2].sc = tmp1[2];
2767         w1[3].sc = tmp1[3];
2768         out_len.sc = tmp_len;
2769         break;
2770
2771       case 13:
2772         w0[0].sd = tmp0[0];
2773         w0[1].sd = tmp0[1];
2774         w0[2].sd = tmp0[2];
2775         w0[3].sd = tmp0[3];
2776         w1[0].sd = tmp1[0];
2777         w1[1].sd = tmp1[1];
2778         w1[2].sd = tmp1[2];
2779         w1[3].sd = tmp1[3];
2780         out_len.sd = tmp_len;
2781         break;
2782
2783       case 14:
2784         w0[0].se = tmp0[0];
2785         w0[1].se = tmp0[1];
2786         w0[2].se = tmp0[2];
2787         w0[3].se = tmp0[3];
2788         w1[0].se = tmp1[0];
2789         w1[1].se = tmp1[1];
2790         w1[2].se = tmp1[2];
2791         w1[3].se = tmp1[3];
2792         out_len.se = tmp_len;
2793         break;
2794
2795       case 15:
2796         w0[0].sf = tmp0[0];
2797         w0[1].sf = tmp0[1];
2798         w0[2].sf = tmp0[2];
2799         w0[3].sf = tmp0[3];
2800         w1[0].sf = tmp1[0];
2801         w1[1].sf = tmp1[1];
2802         w1[2].sf = tmp1[2];
2803         w1[3].sf = tmp1[3];
2804         out_len.sf = tmp_len;
2805         break;
2806       #endif
2807     }
2808   }
2809
2810   return out_len;
2811
2812   #endif
2813 }