760eceeb2078ed632e24f1cfe6c332199e218a40
[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   // TODO
1601   return in_len;
1602 }
1603
1604 inline u32 rule_op_mangle_togglecase_rec (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1605 {
1606   // TODO
1607   return in_len;
1608 }
1609
1610 inline u32 rule_op_mangle_dupechar_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1611 {
1612   if ( in_len       ==  0) return (in_len);
1613   if ((in_len + p0) >= 32) return (in_len);
1614
1615   u32 out_len = in_len;
1616
1617   const u32 tmp = buf0[0] & 0xFF;
1618
1619   rshift_block_N (buf0, buf1, buf0, buf1, p0);
1620
1621   switch (p0)
1622   {
1623     case  1:  buf0[0] |= tmp <<  0;
1624               break;
1625     case  2:  buf0[0] |= tmp <<  0 | tmp << 8;
1626               break;
1627     case  3:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16;
1628               break;
1629     case  4:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1630               break;
1631     case  5:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1632               buf0[1] |= tmp <<  0;
1633               break;
1634     case  6:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1635               buf0[1] |= tmp <<  0 | tmp << 8;
1636               break;
1637     case  7:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1638               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16;
1639               break;
1640     case  8:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1641               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1642               break;
1643     case  9:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1644               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1645               buf0[2] |= tmp <<  0;
1646               break;
1647     case 10:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1648               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1649               buf0[2] |= tmp <<  0 | tmp << 8;
1650               break;
1651     case 11:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1652               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1653               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16;
1654               break;
1655     case 12:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1656               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1657               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1658               break;
1659     case 13:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1660               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1661               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1662               buf0[3] |= tmp <<  0;
1663               break;
1664     case 14:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1665               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1666               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1667               buf0[3] |= tmp <<  0 | tmp << 8;
1668               break;
1669     case 15:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1670               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1671               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1672               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16;
1673               break;
1674     case 16:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1675               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1676               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1677               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1678               break;
1679     case 17:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1680               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1681               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1682               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1683               buf1[0] |= tmp <<  0;
1684               break;
1685     case 18:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1686               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1687               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1688               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1689               buf1[0] |= tmp <<  0 | tmp << 8;
1690               break;
1691     case 19:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1692               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1693               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1694               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1695               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16;
1696               break;
1697     case 20:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1698               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1699               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1700               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1701               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1702               break;
1703     case 21:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1704               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1705               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1706               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1707               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1708               buf1[1] |= tmp <<  0;
1709               break;
1710     case 22:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1711               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1712               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1713               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1714               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1715               buf1[1] |= tmp <<  0 | tmp << 8;
1716               break;
1717     case 23:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1718               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1719               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1720               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1721               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1722               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16;
1723               break;
1724     case 24:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1725               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1726               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1727               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1728               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1729               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1730               break;
1731     case 25:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1732               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1733               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1734               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1735               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1736               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1737               buf1[2] |= tmp <<  0;
1738               break;
1739     case 26:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1740               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1741               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1742               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1743               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1744               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1745               buf1[2] |= tmp <<  0 | tmp << 8;
1746               break;
1747     case 27:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1748               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1749               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1750               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1751               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1752               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1753               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16;
1754               break;
1755     case 28:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1756               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1757               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1758               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1759               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1760               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1761               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1762               break;
1763     case 29:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1764               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1765               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1766               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1767               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1768               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1769               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1770               buf1[3] |= tmp <<  0;
1771               break;
1772     case 30:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1773               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1774               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1775               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1776               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1777               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1778               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1779               buf1[3] |= tmp <<  0 | tmp << 8;
1780               break;
1781     case 31:  buf0[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1782               buf0[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1783               buf0[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1784               buf0[3] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1785               buf1[0] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1786               buf1[1] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1787               buf1[2] |= tmp <<  0 | tmp << 8 | tmp << 16 | tmp << 24;
1788               buf1[3] |= tmp <<  0 | tmp << 8 | tmp << 16;
1789               break;
1790   }
1791
1792   out_len += p0;
1793
1794   return out_len;
1795 }
1796
1797 inline u32 rule_op_mangle_dupechar_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1798 {
1799   if ( in_len       ==  0) return (in_len);
1800   if ((in_len + p0) >= 32) return (in_len);
1801
1802   const u32 in_len1 = in_len - 1;
1803
1804   const u32 sh = (in_len1 & 3) * 8;
1805
1806   u32 tmp = 0;
1807
1808   switch (in_len1 / 4)
1809   {
1810     case  0:  tmp = (buf0[0] >> sh) & 0xff; break;
1811     case  1:  tmp = (buf0[1] >> sh) & 0xff; break;
1812     case  2:  tmp = (buf0[2] >> sh) & 0xff; break;
1813     case  3:  tmp = (buf0[3] >> sh) & 0xff; break;
1814     case  4:  tmp = (buf1[0] >> sh) & 0xff; break;
1815     case  5:  tmp = (buf1[1] >> sh) & 0xff; break;
1816     case  6:  tmp = (buf1[2] >> sh) & 0xff; break;
1817     case  7:  tmp = (buf1[3] >> sh) & 0xff; break;
1818   }
1819
1820   u32 out_len = in_len;
1821
1822   for (u32 i = 0; i < p0; i++)
1823   {
1824     append_block1 (out_len, buf0, buf1, tmp);
1825
1826     out_len++;
1827   }
1828
1829   return out_len;
1830 }
1831
1832 inline u32 rule_op_mangle_dupechar_all (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 + in_len) >= 32) return (in_len);
1836
1837   u32 out_len = in_len;
1838
1839   u32 tib40[4];
1840   u32 tib41[4];
1841
1842   tib40[0] = ((buf0[0] & 0x000000FF) <<  0) | ((buf0[0] & 0x0000FF00) <<  8);
1843   tib40[1] = ((buf0[0] & 0x00FF0000) >> 16) | ((buf0[0] & 0xFF000000) >>  8);
1844   tib40[2] = ((buf0[1] & 0x000000FF) <<  0) | ((buf0[1] & 0x0000FF00) <<  8);
1845   tib40[3] = ((buf0[1] & 0x00FF0000) >> 16) | ((buf0[1] & 0xFF000000) >>  8);
1846   tib41[0] = ((buf0[2] & 0x000000FF) <<  0) | ((buf0[2] & 0x0000FF00) <<  8);
1847   tib41[1] = ((buf0[2] & 0x00FF0000) >> 16) | ((buf0[2] & 0xFF000000) >>  8);
1848   tib41[2] = ((buf0[3] & 0x000000FF) <<  0) | ((buf0[3] & 0x0000FF00) <<  8);
1849   tib41[3] = ((buf0[3] & 0x00FF0000) >> 16) | ((buf0[3] & 0xFF000000) >>  8);
1850
1851   buf0[0] = tib40[0] | (tib40[0] <<  8);
1852   buf0[1] = tib40[1] | (tib40[1] <<  8);
1853   buf0[2] = tib40[2] | (tib40[2] <<  8);
1854   buf0[3] = tib40[3] | (tib40[3] <<  8);
1855   buf1[0] = tib41[0] | (tib41[0] <<  8);
1856   buf1[1] = tib41[1] | (tib41[1] <<  8);
1857   buf1[2] = tib41[2] | (tib41[2] <<  8);
1858   buf1[3] = tib41[3] | (tib41[3] <<  8);
1859
1860   out_len = out_len + out_len;
1861
1862   return out_len;
1863 }
1864
1865 inline u32 rule_op_mangle_switch_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1866 {
1867   if (in_len < 2) return (in_len);
1868
1869   buf0[0] = (buf0[0] & 0xFFFF0000) | ((buf0[0] << 8) & 0x0000FF00) | ((buf0[0] >> 8) & 0x000000FF);
1870
1871   return in_len;
1872 }
1873
1874 inline u32 rule_op_mangle_switch_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1875 {
1876   if (in_len < 2) return (in_len);
1877
1878   switch (in_len)
1879   {
1880     case  2:  buf0[0] = ((buf0[0] << 8) & 0x0000FF00) | ((buf0[0] >> 8) & 0x000000FF);
1881               break;
1882     case  3:  buf0[0] =  (buf0[0] & 0x000000FF) | ((buf0[0] <<  8) & 0x00FF0000) | ((buf0[0] >>  8) & 0x0000FF00);
1883               break;
1884     case  4:  buf0[0] =  (buf0[0] & 0x0000FFFF) | ((buf0[0] <<  8) & 0xFF000000) | ((buf0[0] >>  8) & 0x00FF0000);
1885               break;
1886     case  5:  buf0[1] =  (buf0[0] & 0xFF000000) |   buf0[1];
1887               buf0[0] =  (buf0[0] & 0x00FFFFFF) |  (buf0[1] << 24);
1888               buf0[1] =  (buf0[1] >> 24);
1889               break;
1890     case  6:  buf0[1] = ((buf0[1] << 8) & 0x0000FF00) | ((buf0[1] >> 8) & 0x000000FF);
1891               break;
1892     case  7:  buf0[1] =  (buf0[1] & 0x000000FF) | ((buf0[1] <<  8) & 0x00FF0000) | ((buf0[1] >>  8) & 0x0000FF00);
1893               break;
1894     case  8:  buf0[1] =  (buf0[1] & 0x0000FFFF) | ((buf0[1] <<  8) & 0xFF000000) | ((buf0[1] >>  8) & 0x00FF0000);
1895               break;
1896     case  9:  buf0[2] =  (buf0[1] & 0xFF000000) |   buf0[2];
1897               buf0[1] =  (buf0[1] & 0x00FFFFFF) |  (buf0[2] << 24);
1898               buf0[2] =  (buf0[2] >> 24);
1899               break;
1900     case 10:  buf0[2] = ((buf0[2] << 8) & 0x0000FF00) | ((buf0[2] >> 8) & 0x000000FF);
1901               break;
1902     case 11:  buf0[2] =  (buf0[2] & 0x000000FF) | ((buf0[2] <<  8) & 0x00FF0000) | ((buf0[2] >>  8) & 0x0000FF00);
1903               break;
1904     case 12:  buf0[2] =  (buf0[2] & 0x0000FFFF) | ((buf0[2] <<  8) & 0xFF000000) | ((buf0[2] >>  8) & 0x00FF0000);
1905               break;
1906     case 13:  buf0[3] =  (buf0[2] & 0xFF000000) |   buf0[3];
1907               buf0[2] =  (buf0[2] & 0x00FFFFFF) |  (buf0[3] << 24);
1908               buf0[3] =  (buf0[3] >> 24);
1909               break;
1910     case 14:  buf0[3] = ((buf0[3] << 8) & 0x0000FF00) | ((buf0[3] >> 8) & 0x000000FF);
1911               break;
1912     case 15:  buf0[3] =  (buf0[3] & 0x000000FF) |  ((buf0[3] <<  8) & 0x00FF0000) | ((buf0[3] >>  8) & 0x0000FF00);
1913               break;
1914     case 16:  buf0[3] =  (buf0[3] & 0x0000FFFF) | ((buf0[3] <<  8) & 0xFF000000) | ((buf0[3] >>  8) & 0x00FF0000);
1915               break;
1916     case 17:  buf1[0] =  (buf0[3] & 0xFF000000) |   buf1[0];
1917               buf0[3] =  (buf0[3] & 0x00FFFFFF) |  (buf1[0] << 24);
1918               buf1[0] =  (buf1[0] >> 24);
1919               break;
1920     case 18:  buf1[0] = ((buf1[0] << 8) & 0x0000FF00) | ((buf1[0] >> 8) & 0x000000FF);
1921               break;
1922     case 19:  buf1[0] =  (buf1[0] & 0x000000FF) | ((buf1[0] <<  8) & 0x00FF0000) | ((buf1[0] >>  8) & 0x0000FF00);
1923               break;
1924     case 20:  buf1[0] =  (buf1[0] & 0x0000FFFF) | ((buf1[0] <<  8) & 0xFF000000) | ((buf1[0] >>  8) & 0x00FF0000);
1925               break;
1926     case 21:  buf1[1] =  (buf1[0] & 0xFF000000) |   buf1[1];
1927               buf1[0] =  (buf1[0] & 0x00FFFFFF) |  (buf1[1] << 24);
1928               buf1[1] =  (buf1[1] >> 24);
1929               break;
1930     case 22:  buf1[1] = ((buf1[1] << 8) & 0x0000FF00) | ((buf1[1] >> 8) & 0x000000FF);
1931               break;
1932     case 23:  buf1[1] =  (buf1[1] & 0x000000FF) | ((buf1[1] <<  8) & 0x00FF0000) | ((buf1[1] >>  8) & 0x0000FF00);
1933               break;
1934     case 24:  buf1[1] =  (buf1[1] & 0x0000FFFF) | ((buf1[1] <<  8) & 0xFF000000) | ((buf1[1] >>  8) & 0x00FF0000);
1935               break;
1936     case 25:  buf1[2] =  (buf1[1] & 0xFF000000) |   buf1[2];
1937               buf1[1] =  (buf1[1] & 0x00FFFFFF) |  (buf1[2] << 24);
1938               buf1[2] =  (buf1[2] >> 24);
1939               break;
1940     case 26:  buf1[2] = ((buf1[2] << 8) & 0x0000FF00) | ((buf1[2] >> 8) & 0x000000FF);
1941               break;
1942     case 27:  buf1[2] =  (buf1[2] & 0x000000FF) | ((buf1[2] <<  8) & 0x00FF0000) | ((buf1[2] >>  8) & 0x0000FF00);
1943               break;
1944     case 28:  buf1[2] =  (buf1[2] & 0x0000FFFF) | ((buf1[2] <<  8) & 0xFF000000) | ((buf1[2] >>  8) & 0x00FF0000);
1945               break;
1946     case 29:  buf1[3] =  (buf1[2] & 0xFF000000) |   buf1[3];
1947               buf1[2] =  (buf1[2] & 0x00FFFFFF) |  (buf1[3] << 24);
1948               buf1[3] =  (buf1[3] >> 24);
1949               break;
1950     case 30:  buf1[3] = ((buf1[3] << 8) & 0x0000FF00) | ((buf1[3] >> 8) & 0x000000FF);
1951               break;
1952     case 31:  buf1[3] =  (buf1[3] & 0x000000FF) |  ((buf1[3] <<  8) & 0x00FF0000) | ((buf1[3] >>  8) & 0x0000FF00);
1953               break;
1954   }
1955
1956   return in_len;
1957 }
1958
1959 inline u32 rule_op_mangle_switch_at (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
1960 {
1961   if (p0 >= in_len) return (in_len);
1962   if (p1 >= in_len) return (in_len);
1963
1964   u32 tmp0 = 0;
1965   u32 tmp1 = 0;
1966
1967   switch (p0)
1968   {
1969     case  0:  tmp0 = (buf0[0] >>  0) & 0xFF;
1970               break;
1971     case  1:  tmp0 = (buf0[0] >>  8) & 0xFF;
1972               break;
1973     case  2:  tmp0 = (buf0[0] >> 16) & 0xFF;
1974               break;
1975     case  3:  tmp0 = (buf0[0] >> 24) & 0xFF;
1976               break;
1977     case  4:  tmp0 = (buf0[1] >>  0) & 0xFF;
1978               break;
1979     case  5:  tmp0 = (buf0[1] >>  8) & 0xFF;
1980               break;
1981     case  6:  tmp0 = (buf0[1] >> 16) & 0xFF;
1982               break;
1983     case  7:  tmp0 = (buf0[1] >> 24) & 0xFF;
1984               break;
1985     case  8:  tmp0 = (buf0[2] >>  0) & 0xFF;
1986               break;
1987     case  9:  tmp0 = (buf0[2] >>  8) & 0xFF;
1988               break;
1989     case 10:  tmp0 = (buf0[2] >> 16) & 0xFF;
1990               break;
1991     case 11:  tmp0 = (buf0[2] >> 24) & 0xFF;
1992               break;
1993     case 12:  tmp0 = (buf0[3] >>  0) & 0xFF;
1994               break;
1995     case 13:  tmp0 = (buf0[3] >>  8) & 0xFF;
1996               break;
1997     case 14:  tmp0 = (buf0[3] >> 16) & 0xFF;
1998               break;
1999     case 15:  tmp0 = (buf0[3] >> 24) & 0xFF;
2000               break;
2001     case 16:  tmp0 = (buf1[0] >>  0) & 0xFF;
2002               break;
2003     case 17:  tmp0 = (buf1[0] >>  8) & 0xFF;
2004               break;
2005     case 18:  tmp0 = (buf1[0] >> 16) & 0xFF;
2006               break;
2007     case 19:  tmp0 = (buf1[0] >> 24) & 0xFF;
2008               break;
2009     case 20:  tmp0 = (buf1[1] >>  0) & 0xFF;
2010               break;
2011     case 21:  tmp0 = (buf1[1] >>  8) & 0xFF;
2012               break;
2013     case 22:  tmp0 = (buf1[1] >> 16) & 0xFF;
2014               break;
2015     case 23:  tmp0 = (buf1[1] >> 24) & 0xFF;
2016               break;
2017     case 24:  tmp0 = (buf1[2] >>  0) & 0xFF;
2018               break;
2019     case 25:  tmp0 = (buf1[2] >>  8) & 0xFF;
2020               break;
2021     case 26:  tmp0 = (buf1[2] >> 16) & 0xFF;
2022               break;
2023     case 27:  tmp0 = (buf1[2] >> 24) & 0xFF;
2024               break;
2025     case 28:  tmp0 = (buf1[3] >>  0) & 0xFF;
2026               break;
2027     case 29:  tmp0 = (buf1[3] >>  8) & 0xFF;
2028               break;
2029     case 30:  tmp0 = (buf1[3] >> 16) & 0xFF;
2030               break;
2031     case 31:  tmp0 = (buf1[3] >> 24) & 0xFF;
2032               break;
2033   }
2034
2035   switch (p1)
2036   {
2037     case  0:  tmp1 = (buf0[0] >>  0) & 0xff;
2038               buf0[0]  = (buf0[0] & 0xffffff00) | tmp0 <<  0;
2039               break;
2040     case  1:  tmp1 = (buf0[0] >>  8) & 0xff;
2041               buf0[0]  = (buf0[0] & 0xffff00ff) | tmp0 <<  8;
2042               break;
2043     case  2:  tmp1 = (buf0[0] >> 16) & 0xff;
2044               buf0[0]  = (buf0[0] & 0xff00ffff) | tmp0 << 16;
2045               break;
2046     case  3:  tmp1 = (buf0[0] >> 24) & 0xff;
2047               buf0[0]  = (buf0[0] & 0x00ffffff) | tmp0 << 24;
2048               break;
2049     case  4:  tmp1 = (buf0[1] >>  0) & 0xff;
2050               buf0[1]  = (buf0[1] & 0xffffff00) | tmp0 <<  0;
2051               break;
2052     case  5:  tmp1 = (buf0[1] >>  8) & 0xff;
2053               buf0[1]  = (buf0[1] & 0xffff00ff) | tmp0 <<  8;
2054               break;
2055     case  6:  tmp1 = (buf0[1] >> 16) & 0xff;
2056               buf0[1]  = (buf0[1] & 0xff00ffff) | tmp0 << 16;
2057               break;
2058     case  7:  tmp1 = (buf0[1] >> 24) & 0xff;
2059               buf0[1]  = (buf0[1] & 0x00ffffff) | tmp0 << 24;
2060               break;
2061     case  8:  tmp1 = (buf0[2] >>  0) & 0xff;
2062               buf0[2]  = (buf0[2] & 0xffffff00) | tmp0 <<  0;
2063               break;
2064     case  9:  tmp1 = (buf0[2] >>  8) & 0xff;
2065               buf0[2]  = (buf0[2] & 0xffff00ff) | tmp0 <<  8;
2066               break;
2067     case 10:  tmp1 = (buf0[2] >> 16) & 0xff;
2068               buf0[2]  = (buf0[2] & 0xff00ffff) | tmp0 << 16;
2069               break;
2070     case 11:  tmp1 = (buf0[2] >> 24) & 0xff;
2071               buf0[2]  = (buf0[2] & 0x00ffffff) | tmp0 << 24;
2072               break;
2073     case 12:  tmp1 = (buf0[3] >>  0) & 0xff;
2074               buf0[3]  = (buf0[3] & 0xffffff00) | tmp0 <<  0;
2075               break;
2076     case 13:  tmp1 = (buf0[3] >>  8) & 0xff;
2077               buf0[3]  = (buf0[3] & 0xffff00ff) | tmp0 <<  8;
2078               break;
2079     case 14:  tmp1 = (buf0[3] >> 16) & 0xff;
2080               buf0[3]  = (buf0[3] & 0xff00ffff) | tmp0 << 16;
2081               break;
2082     case 15:  tmp1 = (buf0[3] >> 24) & 0xff;
2083               buf0[3]  = (buf0[3] & 0x00ffffff) | tmp0 << 24;
2084               break;
2085     case 16:  tmp1 = (buf1[0] >>  0) & 0xff;
2086               buf1[0]  = (buf1[0] & 0xffffff00) | tmp0 <<  0;
2087               break;
2088     case 17:  tmp1 = (buf1[0] >>  8) & 0xff;
2089               buf1[0]  = (buf1[0] & 0xffff00ff) | tmp0 <<  8;
2090               break;
2091     case 18:  tmp1 = (buf1[0] >> 16) & 0xff;
2092               buf1[0]  = (buf1[0] & 0xff00ffff) | tmp0 << 16;
2093               break;
2094     case 19:  tmp1 = (buf1[0] >> 24) & 0xff;
2095               buf1[0]  = (buf1[0] & 0x00ffffff) | tmp0 << 24;
2096               break;
2097     case 20:  tmp1 = (buf1[1] >>  0) & 0xff;
2098               buf1[1]  = (buf1[1] & 0xffffff00) | tmp0 <<  0;
2099               break;
2100     case 21:  tmp1 = (buf1[1] >>  8) & 0xff;
2101               buf1[1]  = (buf1[1] & 0xffff00ff) | tmp0 <<  8;
2102               break;
2103     case 22:  tmp1 = (buf1[1] >> 16) & 0xff;
2104               buf1[1]  = (buf1[1] & 0xff00ffff) | tmp0 << 16;
2105               break;
2106     case 23:  tmp1 = (buf1[1] >> 24) & 0xff;
2107               buf1[1]  = (buf1[1] & 0x00ffffff) | tmp0 << 24;
2108               break;
2109     case 24:  tmp1 = (buf1[2] >>  0) & 0xff;
2110               buf1[2]  = (buf1[2] & 0xffffff00) | tmp0 <<  0;
2111               break;
2112     case 25:  tmp1 = (buf1[2] >>  8) & 0xff;
2113               buf1[2]  = (buf1[2] & 0xffff00ff) | tmp0 <<  8;
2114               break;
2115     case 26:  tmp1 = (buf1[2] >> 16) & 0xff;
2116               buf1[2]  = (buf1[2] & 0xff00ffff) | tmp0 << 16;
2117               break;
2118     case 27:  tmp1 = (buf1[2] >> 24) & 0xff;
2119               buf1[2]  = (buf1[2] & 0x00ffffff) | tmp0 << 24;
2120               break;
2121     case 28:  tmp1 = (buf1[3] >>  0) & 0xff;
2122               buf1[3]  = (buf1[3] & 0xffffff00) | tmp0 <<  0;
2123               break;
2124     case 29:  tmp1 = (buf1[3] >>  8) & 0xff;
2125               buf1[3]  = (buf1[3] & 0xffff00ff) | tmp0 <<  8;
2126               break;
2127     case 30:  tmp1 = (buf1[3] >> 16) & 0xff;
2128               buf1[3]  = (buf1[3] & 0xff00ffff) | tmp0 << 16;
2129               break;
2130     case 31:  tmp1 = (buf1[3] >> 24) & 0xff;
2131               buf1[3]  = (buf1[3] & 0x00ffffff) | tmp0 << 24;
2132               break;
2133   }
2134
2135   switch (p0)
2136   {
2137     case  0:  buf0[0]  = (buf0[0] & 0xffffff00) | tmp1 <<  0;
2138               break;
2139     case  1:  buf0[0]  = (buf0[0] & 0xffff00ff) | tmp1 <<  8;
2140               break;
2141     case  2:  buf0[0]  = (buf0[0] & 0xff00ffff) | tmp1 << 16;
2142               break;
2143     case  3:  buf0[0]  = (buf0[0] & 0x00ffffff) | tmp1 << 24;
2144               break;
2145     case  4:  buf0[1]  = (buf0[1] & 0xffffff00) | tmp1 <<  0;
2146               break;
2147     case  5:  buf0[1]  = (buf0[1] & 0xffff00ff) | tmp1 <<  8;
2148               break;
2149     case  6:  buf0[1]  = (buf0[1] & 0xff00ffff) | tmp1 << 16;
2150               break;
2151     case  7:  buf0[1]  = (buf0[1] & 0x00ffffff) | tmp1 << 24;
2152               break;
2153     case  8:  buf0[2]  = (buf0[2] & 0xffffff00) | tmp1 <<  0;
2154               break;
2155     case  9:  buf0[2]  = (buf0[2] & 0xffff00ff) | tmp1 <<  8;
2156               break;
2157     case 10:  buf0[2]  = (buf0[2] & 0xff00ffff) | tmp1 << 16;
2158               break;
2159     case 11:  buf0[2]  = (buf0[2] & 0x00ffffff) | tmp1 << 24;
2160               break;
2161     case 12:  buf0[3]  = (buf0[3] & 0xffffff00) | tmp1 <<  0;
2162               break;
2163     case 13:  buf0[3]  = (buf0[3] & 0xffff00ff) | tmp1 <<  8;
2164               break;
2165     case 14:  buf0[3]  = (buf0[3] & 0xff00ffff) | tmp1 << 16;
2166               break;
2167     case 15:  buf0[3]  = (buf0[3] & 0x00ffffff) | tmp1 << 24;
2168               break;
2169     case 16:  buf1[0]  = (buf1[0] & 0xffffff00) | tmp1 <<  0;
2170               break;
2171     case 17:  buf1[0]  = (buf1[0] & 0xffff00ff) | tmp1 <<  8;
2172               break;
2173     case 18:  buf1[0]  = (buf1[0] & 0xff00ffff) | tmp1 << 16;
2174               break;
2175     case 19:  buf1[0]  = (buf1[0] & 0x00ffffff) | tmp1 << 24;
2176               break;
2177     case 20:  buf1[1]  = (buf1[1] & 0xffffff00) | tmp1 <<  0;
2178               break;
2179     case 21:  buf1[1]  = (buf1[1] & 0xffff00ff) | tmp1 <<  8;
2180               break;
2181     case 22:  buf1[1]  = (buf1[1] & 0xff00ffff) | tmp1 << 16;
2182               break;
2183     case 23:  buf1[1]  = (buf1[1] & 0x00ffffff) | tmp1 << 24;
2184               break;
2185     case 24:  buf1[2]  = (buf1[2] & 0xffffff00) | tmp1 <<  0;
2186               break;
2187     case 25:  buf1[2]  = (buf1[2] & 0xffff00ff) | tmp1 <<  8;
2188               break;
2189     case 26:  buf1[2]  = (buf1[2] & 0xff00ffff) | tmp1 << 16;
2190               break;
2191     case 27:  buf1[2]  = (buf1[2] & 0x00ffffff) | tmp1 << 24;
2192               break;
2193     case 28:  buf1[3]  = (buf1[3] & 0xffffff00) | tmp1 <<  0;
2194               break;
2195     case 29:  buf1[3]  = (buf1[3] & 0xffff00ff) | tmp1 <<  8;
2196               break;
2197     case 30:  buf1[3]  = (buf1[3] & 0xff00ffff) | tmp1 << 16;
2198               break;
2199     case 31:  buf1[3]  = (buf1[3] & 0x00ffffff) | tmp1 << 24;
2200               break;
2201   }
2202
2203   return in_len;
2204 }
2205
2206 inline u32 rule_op_mangle_chr_shiftl (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2207 {
2208   if (p0 >= in_len) return (in_len);
2209
2210   const u32 mr = 0xffu << ((p0 & 3) * 8);
2211   const u32 ml = ~mr;
2212
2213   switch (p0 / 4)
2214   {
2215     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) << 1) & mr); break;
2216     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) << 1) & mr); break;
2217     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) << 1) & mr); break;
2218     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) << 1) & mr); break;
2219     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) << 1) & mr); break;
2220     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) << 1) & mr); break;
2221     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) << 1) & mr); break;
2222     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) << 1) & mr); break;
2223   }
2224
2225   return in_len;
2226 }
2227
2228 inline u32 rule_op_mangle_chr_shiftr (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2229 {
2230   if (p0 >= in_len) return (in_len);
2231
2232   const u32 mr = 0xffu << ((p0 & 3) * 8);
2233   const u32 ml = ~mr;
2234
2235   switch (p0 / 4)
2236   {
2237     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) >> 1) & mr); break;
2238     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) >> 1) & mr); break;
2239     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) >> 1) & mr); break;
2240     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) >> 1) & mr); break;
2241     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) >> 1) & mr); break;
2242     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) >> 1) & mr); break;
2243     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) >> 1) & mr); break;
2244     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) >> 1) & mr); break;
2245   }
2246
2247   return in_len;
2248 }
2249
2250 inline u32 rule_op_mangle_chr_incr (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2251 {
2252   if (p0 >= in_len) return (in_len);
2253
2254   const u32 mr = 0xffu << ((p0 & 3) * 8);
2255   const u32 ml = ~mr;
2256
2257   const u32 n = 0x01010101 & mr;
2258
2259   switch (p0 / 4)
2260   {
2261     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) + n) & mr); break;
2262     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) + n) & mr); break;
2263     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) + n) & mr); break;
2264     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) + n) & mr); break;
2265     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) + n) & mr); break;
2266     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) + n) & mr); break;
2267     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) + n) & mr); break;
2268     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) + n) & mr); break;
2269   }
2270
2271   return in_len;
2272 }
2273
2274 inline u32 rule_op_mangle_chr_decr (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2275 {
2276   if (p0 >= in_len) return (in_len);
2277
2278   const u32 mr = 0xffu << ((p0 & 3) * 8);
2279   const u32 ml = ~mr;
2280
2281   const u32 n = 0x01010101 & mr;
2282
2283   switch (p0 / 4)
2284   {
2285     case  0:  buf0[0] = (buf0[0] & ml) | (((buf0[0] & mr) - n) & mr); break;
2286     case  1:  buf0[1] = (buf0[1] & ml) | (((buf0[1] & mr) - n) & mr); break;
2287     case  2:  buf0[2] = (buf0[2] & ml) | (((buf0[2] & mr) - n) & mr); break;
2288     case  3:  buf0[3] = (buf0[3] & ml) | (((buf0[3] & mr) - n) & mr); break;
2289     case  4:  buf1[0] = (buf1[0] & ml) | (((buf1[0] & mr) - n) & mr); break;
2290     case  5:  buf1[1] = (buf1[1] & ml) | (((buf1[1] & mr) - n) & mr); break;
2291     case  6:  buf1[2] = (buf1[2] & ml) | (((buf1[2] & mr) - n) & mr); break;
2292     case  7:  buf1[3] = (buf1[3] & ml) | (((buf1[3] & mr) - n) & mr); break;
2293   }
2294
2295   return in_len;
2296 }
2297
2298 inline u32 rule_op_mangle_replace_np1 (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2299 {
2300   if ((p0 + 1) >= in_len) return (in_len);
2301
2302   u32 tib40[4];
2303   u32 tib41[4];
2304
2305   lshift_block (buf0, buf1, tib40, tib41);
2306
2307   const u32 mr = 0xffu << ((p0 & 3) * 8);
2308   const u32 ml = ~mr;
2309
2310   switch (p0 / 4)
2311   {
2312     case  0:  buf0[0] = (buf0[0] & ml) | (tib40[0] & mr); break;
2313     case  1:  buf0[1] = (buf0[1] & ml) | (tib40[1] & mr); break;
2314     case  2:  buf0[2] = (buf0[2] & ml) | (tib40[2] & mr); break;
2315     case  3:  buf0[3] = (buf0[3] & ml) | (tib40[3] & mr); break;
2316     case  4:  buf1[0] = (buf1[0] & ml) | (tib41[0] & mr); break;
2317     case  5:  buf1[1] = (buf1[1] & ml) | (tib41[1] & mr); break;
2318     case  6:  buf1[2] = (buf1[2] & ml) | (tib41[2] & mr); break;
2319     case  7:  buf1[3] = (buf1[3] & ml) | (tib41[3] & mr); break;
2320   }
2321
2322   return in_len;
2323 }
2324
2325 inline u32 rule_op_mangle_replace_nm1 (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2326 {
2327   if (p0 == 0) return (in_len);
2328
2329   if (p0 >= in_len) return (in_len);
2330
2331   u32 tib40[4];
2332   u32 tib41[4];
2333
2334   rshift_block (buf0, buf1, tib40, tib41);
2335
2336   const u32 mr = 0xffu << ((p0 & 3) * 8);
2337   const u32 ml = ~mr;
2338
2339   switch (p0 / 4)
2340   {
2341     case  0:  buf0[0] = (buf0[0] & ml) | (tib40[0] & mr); break;
2342     case  1:  buf0[1] = (buf0[1] & ml) | (tib40[1] & mr); break;
2343     case  2:  buf0[2] = (buf0[2] & ml) | (tib40[2] & mr); break;
2344     case  3:  buf0[3] = (buf0[3] & ml) | (tib40[3] & mr); break;
2345     case  4:  buf1[0] = (buf1[0] & ml) | (tib41[0] & mr); break;
2346     case  5:  buf1[1] = (buf1[1] & ml) | (tib41[1] & mr); break;
2347     case  6:  buf1[2] = (buf1[2] & ml) | (tib41[2] & mr); break;
2348     case  7:  buf1[3] = (buf1[3] & ml) | (tib41[3] & mr); break;
2349   }
2350
2351   return in_len;
2352 }
2353
2354 inline u32 rule_op_mangle_dupeblock_first (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2355 {
2356   if (p0 > in_len) return (in_len);
2357
2358   if ((in_len + p0) >= 32) return (in_len);
2359
2360   u32 out_len = in_len;
2361
2362   u32 tib40[4];
2363   u32 tib41[4];
2364
2365   tib40[0] = buf0[0];
2366   tib40[1] = buf0[1];
2367   tib40[2] = buf0[2];
2368   tib40[3] = buf0[3];
2369   tib41[0] = buf1[0];
2370   tib41[1] = buf1[1];
2371   tib41[2] = buf1[2];
2372   tib41[3] = buf1[3];
2373
2374   truncate_right (tib40, tib41, p0);
2375
2376   rshift_block_N (buf0, buf1, buf0, buf1, p0);
2377
2378   buf0[0] |= tib40[0];
2379   buf0[1] |= tib40[1];
2380   buf0[2] |= tib40[2];
2381   buf0[3] |= tib40[3];
2382   buf1[0] |= tib41[0];
2383   buf1[1] |= tib41[1];
2384   buf1[2] |= tib41[2];
2385   buf1[3] |= tib41[3];
2386
2387   out_len += p0;
2388
2389   return out_len;
2390 }
2391
2392 inline u32 rule_op_mangle_dupeblock_last (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2393 {
2394   if (p0 > in_len) return (in_len);
2395
2396   if ((in_len + p0) >= 32) return (in_len);
2397
2398   u32 out_len = in_len;
2399
2400   u32 tib40[4];
2401   u32 tib41[4];
2402
2403   rshift_block_N (buf0, buf1, tib40, tib41, p0);
2404
2405   truncate_left (tib40, tib41, out_len);
2406
2407   buf0[0] |= tib40[0];
2408   buf0[1] |= tib40[1];
2409   buf0[2] |= tib40[2];
2410   buf0[3] |= tib40[3];
2411   buf1[0] |= tib41[0];
2412   buf1[1] |= tib41[1];
2413   buf1[2] |= tib41[2];
2414   buf1[3] |= tib41[3];
2415
2416   out_len += p0;
2417
2418   return out_len;
2419 }
2420
2421 inline u32 rule_op_mangle_title (const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2422 {
2423   buf0[0] |= (generate_cmask (buf0[0]));
2424   buf0[1] |= (generate_cmask (buf0[1]));
2425   buf0[2] |= (generate_cmask (buf0[2]));
2426   buf0[3] |= (generate_cmask (buf0[3]));
2427   buf1[0] |= (generate_cmask (buf1[0]));
2428   buf1[1] |= (generate_cmask (buf1[1]));
2429   buf1[2] |= (generate_cmask (buf1[2]));
2430   buf1[3] |= (generate_cmask (buf1[3]));
2431
2432   u32 tib40[4];
2433   u32 tib41[4];
2434
2435   const uchar4 tmp0 = (uchar4) (' ');
2436   const uchar4 tmp1 = (uchar4) (0x00);
2437   const uchar4 tmp2 = (uchar4) (0xff);
2438
2439   uchar4 tmp;
2440
2441   tmp = as_uchar4 (buf0[0]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[0] = as_uint (tmp);
2442   tmp = as_uchar4 (buf0[1]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[1] = as_uint (tmp);
2443   tmp = as_uchar4 (buf0[2]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[2] = as_uint (tmp);
2444   tmp = as_uchar4 (buf0[3]); tmp = select (tmp1, tmp2, tmp == tmp0); tib40[3] = as_uint (tmp);
2445   tmp = as_uchar4 (buf1[0]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[0] = as_uint (tmp);
2446   tmp = as_uchar4 (buf1[1]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[1] = as_uint (tmp);
2447   tmp = as_uchar4 (buf1[2]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[2] = as_uint (tmp);
2448   tmp = as_uchar4 (buf1[3]); tmp = select (tmp1, tmp2, tmp == tmp0); tib41[3] = as_uint (tmp);
2449
2450   rshift_block (tib40, tib41, tib40, tib41); tib40[0] |= 0xff;
2451
2452   buf0[0] &= ~(generate_cmask (buf0[0]) & tib40[0]);
2453   buf0[1] &= ~(generate_cmask (buf0[1]) & tib40[1]);
2454   buf0[2] &= ~(generate_cmask (buf0[2]) & tib40[2]);
2455   buf0[3] &= ~(generate_cmask (buf0[3]) & tib40[3]);
2456   buf1[0] &= ~(generate_cmask (buf1[0]) & tib41[0]);
2457   buf1[1] &= ~(generate_cmask (buf1[1]) & tib41[1]);
2458   buf1[2] &= ~(generate_cmask (buf1[2]) & tib41[2]);
2459   buf1[3] &= ~(generate_cmask (buf1[3]) & tib41[3]);
2460
2461   return in_len;
2462 }
2463
2464 inline u32 apply_rule (const u32 name, const u32 p0, const u32 p1, u32 buf0[4], u32 buf1[4], const u32 in_len)
2465 {
2466   u32 out_len = in_len;
2467
2468   switch (name)
2469   {
2470     case RULE_OP_MANGLE_LREST:            out_len = rule_op_mangle_lrest            (p0, p1, buf0, buf1, out_len); break;
2471     case RULE_OP_MANGLE_UREST:            out_len = rule_op_mangle_urest            (p0, p1, buf0, buf1, out_len); break;
2472     case RULE_OP_MANGLE_LREST_UFIRST:     out_len = rule_op_mangle_lrest_ufirst     (p0, p1, buf0, buf1, out_len); break;
2473     case RULE_OP_MANGLE_UREST_LFIRST:     out_len = rule_op_mangle_urest_lfirst     (p0, p1, buf0, buf1, out_len); break;
2474     case RULE_OP_MANGLE_TREST:            out_len = rule_op_mangle_trest            (p0, p1, buf0, buf1, out_len); break;
2475     case RULE_OP_MANGLE_TOGGLE_AT:        out_len = rule_op_mangle_toggle_at        (p0, p1, buf0, buf1, out_len); break;
2476     case RULE_OP_MANGLE_REVERSE:          out_len = rule_op_mangle_reverse          (p0, p1, buf0, buf1, out_len); break;
2477     case RULE_OP_MANGLE_DUPEWORD:         out_len = rule_op_mangle_dupeword         (p0, p1, buf0, buf1, out_len); break;
2478     case RULE_OP_MANGLE_DUPEWORD_TIMES:   out_len = rule_op_mangle_dupeword_times   (p0, p1, buf0, buf1, out_len); break;
2479     case RULE_OP_MANGLE_REFLECT:          out_len = rule_op_mangle_reflect          (p0, p1, buf0, buf1, out_len); break;
2480     case RULE_OP_MANGLE_APPEND:           out_len = rule_op_mangle_append           (p0, p1, buf0, buf1, out_len); break;
2481     case RULE_OP_MANGLE_PREPEND:          out_len = rule_op_mangle_prepend          (p0, p1, buf0, buf1, out_len); break;
2482     case RULE_OP_MANGLE_ROTATE_LEFT:      out_len = rule_op_mangle_rotate_left      (p0, p1, buf0, buf1, out_len); break;
2483     case RULE_OP_MANGLE_ROTATE_RIGHT:     out_len = rule_op_mangle_rotate_right     (p0, p1, buf0, buf1, out_len); break;
2484     case RULE_OP_MANGLE_DELETE_FIRST:     out_len = rule_op_mangle_delete_first     (p0, p1, buf0, buf1, out_len); break;
2485     case RULE_OP_MANGLE_DELETE_LAST:      out_len = rule_op_mangle_delete_last      (p0, p1, buf0, buf1, out_len); break;
2486     case RULE_OP_MANGLE_DELETE_AT:        out_len = rule_op_mangle_delete_at        (p0, p1, buf0, buf1, out_len); break;
2487     case RULE_OP_MANGLE_EXTRACT:          out_len = rule_op_mangle_extract          (p0, p1, buf0, buf1, out_len); break;
2488     case RULE_OP_MANGLE_OMIT:             out_len = rule_op_mangle_omit             (p0, p1, buf0, buf1, out_len); break;
2489     case RULE_OP_MANGLE_INSERT:           out_len = rule_op_mangle_insert           (p0, p1, buf0, buf1, out_len); break;
2490     case RULE_OP_MANGLE_OVERSTRIKE:       out_len = rule_op_mangle_overstrike       (p0, p1, buf0, buf1, out_len); break;
2491     case RULE_OP_MANGLE_TRUNCATE_AT:      out_len = rule_op_mangle_truncate_at      (p0, p1, buf0, buf1, out_len); break;
2492     case RULE_OP_MANGLE_REPLACE:          out_len = rule_op_mangle_replace          (p0, p1, buf0, buf1, out_len); break;
2493     //case RULE_OP_MANGLE_PURGECHAR:        out_len = rule_op_mangle_purgechar        (p0, p1, buf0, buf1, out_len); break;
2494     //case RULE_OP_MANGLE_TOGGLECASE_REC:   out_len = rule_op_mangle_togglecase_rec   (p0, p1, buf0, buf1, out_len); break;
2495     case RULE_OP_MANGLE_DUPECHAR_FIRST:   out_len = rule_op_mangle_dupechar_first   (p0, p1, buf0, buf1, out_len); break;
2496     case RULE_OP_MANGLE_DUPECHAR_LAST:    out_len = rule_op_mangle_dupechar_last    (p0, p1, buf0, buf1, out_len); break;
2497     case RULE_OP_MANGLE_DUPECHAR_ALL:     out_len = rule_op_mangle_dupechar_all     (p0, p1, buf0, buf1, out_len); break;
2498     case RULE_OP_MANGLE_SWITCH_FIRST:     out_len = rule_op_mangle_switch_first     (p0, p1, buf0, buf1, out_len); break;
2499     case RULE_OP_MANGLE_SWITCH_LAST:      out_len = rule_op_mangle_switch_last      (p0, p1, buf0, buf1, out_len); break;
2500     case RULE_OP_MANGLE_SWITCH_AT:        out_len = rule_op_mangle_switch_at        (p0, p1, buf0, buf1, out_len); break;
2501     case RULE_OP_MANGLE_CHR_SHIFTL:       out_len = rule_op_mangle_chr_shiftl       (p0, p1, buf0, buf1, out_len); break;
2502     case RULE_OP_MANGLE_CHR_SHIFTR:       out_len = rule_op_mangle_chr_shiftr       (p0, p1, buf0, buf1, out_len); break;
2503     case RULE_OP_MANGLE_CHR_INCR:         out_len = rule_op_mangle_chr_incr         (p0, p1, buf0, buf1, out_len); break;
2504     case RULE_OP_MANGLE_CHR_DECR:         out_len = rule_op_mangle_chr_decr         (p0, p1, buf0, buf1, out_len); break;
2505     case RULE_OP_MANGLE_REPLACE_NP1:      out_len = rule_op_mangle_replace_np1      (p0, p1, buf0, buf1, out_len); break;
2506     case RULE_OP_MANGLE_REPLACE_NM1:      out_len = rule_op_mangle_replace_nm1      (p0, p1, buf0, buf1, out_len); break;
2507     case RULE_OP_MANGLE_DUPEBLOCK_FIRST:  out_len = rule_op_mangle_dupeblock_first  (p0, p1, buf0, buf1, out_len); break;
2508     case RULE_OP_MANGLE_DUPEBLOCK_LAST:   out_len = rule_op_mangle_dupeblock_last   (p0, p1, buf0, buf1, out_len); break;
2509     case RULE_OP_MANGLE_TITLE:            out_len = rule_op_mangle_title            (p0, p1, buf0, buf1, out_len); break;
2510   }
2511
2512   return out_len;
2513 }
2514
2515 inline u32 apply_rules (const __global u32 *cmds, u32 buf0[4], u32 buf1[4], const u32 len)
2516 {
2517   u32 out_len = len;
2518
2519   for (u32 i = 0; cmds[i] != 0; i++)
2520   {
2521     const u32 cmd = cmds[i];
2522
2523     const u32 name = (cmd >>  0) & 0xff;
2524     const u32 p0   = (cmd >>  8) & 0xff;
2525     const u32 p1   = (cmd >> 16) & 0xff;
2526
2527     out_len = apply_rule (name, p0, p1, buf0, buf1, out_len);
2528   }
2529
2530   return out_len;
2531 }
2532
2533 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])
2534 {
2535   #if VECT_SIZE == 1
2536
2537   w0[0] = pw_buf0[0];
2538   w0[1] = pw_buf0[1];
2539   w0[2] = pw_buf0[2];
2540   w0[3] = pw_buf0[3];
2541   w1[0] = pw_buf1[0];
2542   w1[1] = pw_buf1[1];
2543   w1[2] = pw_buf1[2];
2544   w1[3] = pw_buf1[3];
2545
2546   return apply_rules (rules_buf[il_pos].cmds, w0, w1, pw_len);
2547
2548   #else
2549
2550   u32x out_len = 0;
2551
2552   #ifdef _unroll
2553   #pragma unroll
2554   #endif
2555   for (int i = 0; i < VECT_SIZE; i++)
2556   {
2557     u32 tmp0[4];
2558     u32 tmp1[4];
2559
2560     tmp0[0] = pw_buf0[0];
2561     tmp0[1] = pw_buf0[1];
2562     tmp0[2] = pw_buf0[2];
2563     tmp0[3] = pw_buf0[3];
2564     tmp1[0] = pw_buf1[0];
2565     tmp1[1] = pw_buf1[1];
2566     tmp1[2] = pw_buf1[2];
2567     tmp1[3] = pw_buf1[3];
2568
2569     const u32 tmp_len = apply_rules (rules_buf[il_pos + i].cmds, tmp0, tmp1, pw_len);
2570
2571     switch (i)
2572     {
2573       #if VECT_SIZE >= 2
2574       case 0:
2575         w0[0].s0 = tmp0[0];
2576         w0[1].s0 = tmp0[1];
2577         w0[2].s0 = tmp0[2];
2578         w0[3].s0 = tmp0[3];
2579         w1[0].s0 = tmp1[0];
2580         w1[1].s0 = tmp1[1];
2581         w1[2].s0 = tmp1[2];
2582         w1[3].s0 = tmp1[3];
2583         out_len.s0 = tmp_len;
2584         break;
2585
2586       case 1:
2587         w0[0].s1 = tmp0[0];
2588         w0[1].s1 = tmp0[1];
2589         w0[2].s1 = tmp0[2];
2590         w0[3].s1 = tmp0[3];
2591         w1[0].s1 = tmp1[0];
2592         w1[1].s1 = tmp1[1];
2593         w1[2].s1 = tmp1[2];
2594         w1[3].s1 = tmp1[3];
2595         out_len.s1 = tmp_len;
2596         break;
2597       #endif
2598
2599       #if VECT_SIZE >= 4
2600       case 2:
2601         w0[0].s2 = tmp0[0];
2602         w0[1].s2 = tmp0[1];
2603         w0[2].s2 = tmp0[2];
2604         w0[3].s2 = tmp0[3];
2605         w1[0].s2 = tmp1[0];
2606         w1[1].s2 = tmp1[1];
2607         w1[2].s2 = tmp1[2];
2608         w1[3].s2 = tmp1[3];
2609         out_len.s2 = tmp_len;
2610         break;
2611
2612       case 3:
2613         w0[0].s3 = tmp0[0];
2614         w0[1].s3 = tmp0[1];
2615         w0[2].s3 = tmp0[2];
2616         w0[3].s3 = tmp0[3];
2617         w1[0].s3 = tmp1[0];
2618         w1[1].s3 = tmp1[1];
2619         w1[2].s3 = tmp1[2];
2620         w1[3].s3 = tmp1[3];
2621         out_len.s3 = tmp_len;
2622         break;
2623       #endif
2624
2625       #if VECT_SIZE >= 8
2626       case 4:
2627         w0[0].s4 = tmp0[0];
2628         w0[1].s4 = tmp0[1];
2629         w0[2].s4 = tmp0[2];
2630         w0[3].s4 = tmp0[3];
2631         w1[0].s4 = tmp1[0];
2632         w1[1].s4 = tmp1[1];
2633         w1[2].s4 = tmp1[2];
2634         w1[3].s4 = tmp1[3];
2635         out_len.s4 = tmp_len;
2636         break;
2637
2638       case 5:
2639         w0[0].s5 = tmp0[0];
2640         w0[1].s5 = tmp0[1];
2641         w0[2].s5 = tmp0[2];
2642         w0[3].s5 = tmp0[3];
2643         w1[0].s5 = tmp1[0];
2644         w1[1].s5 = tmp1[1];
2645         w1[2].s5 = tmp1[2];
2646         w1[3].s5 = tmp1[3];
2647         out_len.s5 = tmp_len;
2648         break;
2649
2650       case 6:
2651         w0[0].s6 = tmp0[0];
2652         w0[1].s6 = tmp0[1];
2653         w0[2].s6 = tmp0[2];
2654         w0[3].s6 = tmp0[3];
2655         w1[0].s6 = tmp1[0];
2656         w1[1].s6 = tmp1[1];
2657         w1[2].s6 = tmp1[2];
2658         w1[3].s6 = tmp1[3];
2659         out_len.s6 = tmp_len;
2660         break;
2661
2662       case 7:
2663         w0[0].s7 = tmp0[0];
2664         w0[1].s7 = tmp0[1];
2665         w0[2].s7 = tmp0[2];
2666         w0[3].s7 = tmp0[3];
2667         w1[0].s7 = tmp1[0];
2668         w1[1].s7 = tmp1[1];
2669         w1[2].s7 = tmp1[2];
2670         w1[3].s7 = tmp1[3];
2671         out_len.s7 = tmp_len;
2672         break;
2673       #endif
2674
2675       #if VECT_SIZE >= 16
2676       case 8:
2677         w0[0].s8 = tmp0[0];
2678         w0[1].s8 = tmp0[1];
2679         w0[2].s8 = tmp0[2];
2680         w0[3].s8 = tmp0[3];
2681         w1[0].s8 = tmp1[0];
2682         w1[1].s8 = tmp1[1];
2683         w1[2].s8 = tmp1[2];
2684         w1[3].s8 = tmp1[3];
2685         out_len.s8 = tmp_len;
2686         break;
2687
2688       case 9:
2689         w0[0].s9 = tmp0[0];
2690         w0[1].s9 = tmp0[1];
2691         w0[2].s9 = tmp0[2];
2692         w0[3].s9 = tmp0[3];
2693         w1[0].s9 = tmp1[0];
2694         w1[1].s9 = tmp1[1];
2695         w1[2].s9 = tmp1[2];
2696         w1[3].s9 = tmp1[3];
2697         out_len.s9 = tmp_len;
2698         break;
2699
2700       case 10:
2701         w0[0].sa = tmp0[0];
2702         w0[1].sa = tmp0[1];
2703         w0[2].sa = tmp0[2];
2704         w0[3].sa = tmp0[3];
2705         w1[0].sa = tmp1[0];
2706         w1[1].sa = tmp1[1];
2707         w1[2].sa = tmp1[2];
2708         w1[3].sa = tmp1[3];
2709         out_len.sa = tmp_len;
2710         break;
2711
2712       case 11:
2713         w0[0].sb = tmp0[0];
2714         w0[1].sb = tmp0[1];
2715         w0[2].sb = tmp0[2];
2716         w0[3].sb = tmp0[3];
2717         w1[0].sb = tmp1[0];
2718         w1[1].sb = tmp1[1];
2719         w1[2].sb = tmp1[2];
2720         w1[3].sb = tmp1[3];
2721         out_len.sb = tmp_len;
2722         break;
2723
2724       case 12:
2725         w0[0].sc = tmp0[0];
2726         w0[1].sc = tmp0[1];
2727         w0[2].sc = tmp0[2];
2728         w0[3].sc = tmp0[3];
2729         w1[0].sc = tmp1[0];
2730         w1[1].sc = tmp1[1];
2731         w1[2].sc = tmp1[2];
2732         w1[3].sc = tmp1[3];
2733         out_len.sc = tmp_len;
2734         break;
2735
2736       case 13:
2737         w0[0].sd = tmp0[0];
2738         w0[1].sd = tmp0[1];
2739         w0[2].sd = tmp0[2];
2740         w0[3].sd = tmp0[3];
2741         w1[0].sd = tmp1[0];
2742         w1[1].sd = tmp1[1];
2743         w1[2].sd = tmp1[2];
2744         w1[3].sd = tmp1[3];
2745         out_len.sd = tmp_len;
2746         break;
2747
2748       case 14:
2749         w0[0].se = tmp0[0];
2750         w0[1].se = tmp0[1];
2751         w0[2].se = tmp0[2];
2752         w0[3].se = tmp0[3];
2753         w1[0].se = tmp1[0];
2754         w1[1].se = tmp1[1];
2755         w1[2].se = tmp1[2];
2756         w1[3].se = tmp1[3];
2757         out_len.se = tmp_len;
2758         break;
2759
2760       case 15:
2761         w0[0].sf = tmp0[0];
2762         w0[1].sf = tmp0[1];
2763         w0[2].sf = tmp0[2];
2764         w0[3].sf = tmp0[3];
2765         w1[0].sf = tmp1[0];
2766         w1[1].sf = tmp1[1];
2767         w1[2].sf = tmp1[2];
2768         w1[3].sf = tmp1[3];
2769         out_len.sf = tmp_len;
2770         break;
2771       #endif
2772     }
2773   }
2774
2775   return out_len;
2776
2777   #endif
2778 }