source: proto/u16u8/template.c @ 361

Last change on this file since 361 was 361, checked in by cameron, 10 years ago

u16u8 template file for bitstream compiler

File size: 11.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include "lib/lib_simd.h"
5
6
7typedef SIMD_type BytePack;
8typedef SIMD_type BitBlock;
9
10
11// Profiling
12
13#ifdef BUFFER_PROFILING
14#include "../Profiling/BOM_Profiler.c"
15BOM_Table * transcode_timer;
16#endif
17
18
19#define s2p_step(s0,s1,hi_mask,shift,p0,p1)  \
20{ \
21BitBlock t0,t1; \
22t0= simd_pack_16_hh(s0,s1) ; \
23t1= simd_pack_16_ll(s0,s1) ; \
24p0= simd_if(hi_mask,t0,simd_srli_16(t1,shift) ) ; \
25p1= simd_if(hi_mask,simd_slli_16(t0,shift) ,t1) ; \
26} \
27
28#define s2p_bytepack(s0,s1,s2,s3,s4,s5,s6,s7,p0,p1,p2,p3,p4,p5,p6,p7)  \
29{BitBlock bit00224466_0,bit00224466_1,bit00224466_2,bit00224466_3; \
30BitBlock bit11335577_0,bit11335577_1,bit11335577_2,bit11335577_3; \
31BitBlock bit00004444_0,bit22226666_0,bit00004444_1,bit22226666_1; \
32BitBlock bit11115555_0,bit33337777_0,bit11115555_1,bit33337777_1; \
33s2p_step(s0,s1,simd_himask_2,1,bit00224466_0,bit11335577_0)  \
34s2p_step(s2,s3,simd_himask_2,1,bit00224466_1,bit11335577_1)  \
35s2p_step(s4,s5,simd_himask_2,1,bit00224466_2,bit11335577_2)  \
36s2p_step(s6,s7,simd_himask_2,1,bit00224466_3,bit11335577_3)  \
37s2p_step(bit00224466_0,bit00224466_1,simd_himask_4,2,bit00004444_0,bit22226666_0)  \
38s2p_step(bit00224466_2,bit00224466_3,simd_himask_4,2,bit00004444_1,bit22226666_1)  \
39s2p_step(bit11335577_0,bit11335577_1,simd_himask_4,2,bit11115555_0,bit33337777_0)  \
40s2p_step(bit11335577_2,bit11335577_3,simd_himask_4,2,bit11115555_1,bit33337777_1)  \
41s2p_step(bit00004444_0,bit00004444_1,simd_himask_8,4,p0,p4)  \
42s2p_step(bit11115555_0,bit11115555_1,simd_himask_8,4,p1,p5)  \
43s2p_step(bit22226666_0,bit22226666_1,simd_himask_8,4,p2,p6)  \
44s2p_step(bit33337777_0,bit33337777_1,simd_himask_8,4,p3,p7)  \
45} \
46
47#define p2s_step(p0,p1,hi_mask,shift,s0,s1)  \
48{ \
49BitBlock t0,t1; \
50t0= simd_if(hi_mask,p0,simd_srli_16(p1,shift) ) ; \
51t1= simd_if(hi_mask,simd_slli_16(p0,shift) ,p1) ; \
52s0= simd_mergeh_8(t0,t1) ; \
53s1= simd_mergel_8(t0,t1) ; \
54} \
55
56#define p2s_bytemerge(p0,p1,p2,p3,p4,p5,p6,p7,s0,s1,s2,s3,s4,s5,s6,s7)  \
57{ \
58BitBlock bit00004444_0,bit22226666_0,bit00004444_1,bit22226666_1; \
59BitBlock bit11115555_0,bit33337777_0,bit11115555_1,bit33337777_1; \
60BitBlock bit00224466_0,bit00224466_1,bit00224466_2,bit00224466_3; \
61BitBlock bit11335577_0,bit11335577_1,bit11335577_2,bit11335577_3; \
62p2s_step(p0,p4,simd_himask_8,4,bit00004444_0,bit00004444_1)  \
63p2s_step(p1,p5,simd_himask_8,4,bit11115555_0,bit11115555_1)  \
64p2s_step(p2,p6,simd_himask_8,4,bit22226666_0,bit22226666_1)  \
65p2s_step(p3,p7,simd_himask_8,4,bit33337777_0,bit33337777_1)  \
66p2s_step(bit00004444_0,bit22226666_0,simd_himask_4,2,bit00224466_0,bit00224466_1)  \
67p2s_step(bit11115555_0,bit33337777_0,simd_himask_4,2,bit11335577_0,bit11335577_1)  \
68p2s_step(bit00004444_1,bit22226666_1,simd_himask_4,2,bit00224466_2,bit00224466_3)  \
69p2s_step(bit11115555_1,bit33337777_1,simd_himask_4,2,bit11335577_2,bit11335577_3)  \
70p2s_step(bit00224466_0,bit11335577_0,simd_himask_2,1,s0,s1)  \
71p2s_step(bit00224466_1,bit11335577_1,simd_himask_2,1,s2,s3)  \
72p2s_step(bit00224466_2,bit11335577_2,simd_himask_2,1,s4,s5)  \
73p2s_step(bit00224466_3,bit11335577_3,simd_himask_2,1,s6,s7)  \
74} \
75
76
77static inline void interleave4(BitBlock p0, BitBlock p1, BitBlock p2, BitBlock p3, 
78                               BitBlock& s0, BitBlock& s1, BitBlock& s2, BitBlock& s3);
79
80static inline void interleave4(BitBlock p0, BitBlock p1, BitBlock p2, BitBlock p3, 
81                               BitBlock& s0, BitBlock& s1, BitBlock& s2, BitBlock& s3){
82        BitBlock hpair0 = simd_mergel_1(p1, p0);
83        BitBlock hpair1 = simd_mergeh_1(p1, p0);
84        BitBlock lpair0 = simd_mergel_1(p3, p2);
85        BitBlock lpair1 = simd_mergeh_1(p3, p2);
86        s0 = simd_mergel_2(lpair0,hpair0);
87        s1 = simd_mergeh_2(lpair0,hpair0);
88        s2 = simd_mergel_2(lpair1,hpair1);
89        s3 = simd_mergeh_2(lpair1,hpair1);
90}
91
92
93
94
95#define do_right16_shifts(vec,rshift1,rshift2,rshift4,rshift8)  \
96{BitBlock s2; \
97vec= simd_sub_16(vec,simd_srli_16(simd_and(rshift1,vec) ,1) ) ; \
98s2= simd_and(rshift2,vec) ; \
99vec= simd_or(simd_srli_16(s2,2) ,simd_xor(vec,s2) ) ; \
100s2= simd_and(rshift4,vec) ; \
101vec= simd_or(simd_srli_16(s2,4) ,simd_xor(vec,s2) ) ; \
102s2= simd_and(rshift8,vec) ; \
103vec= simd_or(simd_srli_16(s2,8) ,simd_xor(vec,s2) ) ; \
104}
105
106static inline void bit_del_16(BitBlock &s, BitBlock delmask){
107        BitBlock del16_rshift1;
108        BitBlock del16_rshift2;
109        BitBlock del16_rshift4;
110        BitBlock del16_rshift8;
111       
112        BitBlock del16_trans2;
113        BitBlock del16_trans4;
114        BitBlock del16_trans8;
115        BitBlock shift_bits;
116       
117        del16_rshift1= simd_xor(simd_slli_16(delmask,1),simd_slli_16(delmask,2));
118        del16_rshift1= simd_xor(del16_rshift1,simd_slli_16(del16_rshift1,2));
119        del16_rshift1= simd_xor(del16_rshift1,simd_slli_16(del16_rshift1,4));
120        del16_rshift1= simd_xor(del16_rshift1,simd_slli_16(del16_rshift1,8));
121       
122        del16_trans2= simd_and(del16_rshift1,delmask);
123        del16_rshift2= simd_xor(simd_slli_16(del16_trans2,1),simd_slli_16(del16_trans2,2));
124        del16_rshift2= simd_xor(del16_rshift2,simd_slli_16(del16_rshift2,2));
125        del16_rshift2= simd_xor(del16_rshift2,simd_slli_16(del16_rshift2,4));
126        del16_rshift2= simd_xor(del16_rshift2,simd_slli_16(del16_rshift2,8));
127       
128        del16_trans4= simd_and(del16_rshift2,del16_trans2);
129        del16_rshift4= simd_xor(simd_slli_16(del16_trans4,1),simd_slli_16(del16_trans4,2));
130        del16_rshift4= simd_xor(del16_rshift4,simd_slli_16(del16_rshift4,2));
131        del16_rshift4= simd_xor(del16_rshift4,simd_slli_16(del16_rshift4,4));
132        del16_rshift4= simd_xor(del16_rshift4,simd_slli_16(del16_rshift4,8));
133       
134        del16_trans8= simd_and(del16_rshift4,del16_trans4);
135        del16_rshift8= simd_xor(simd_slli_16(del16_trans8,1),simd_slli_16(del16_trans8,2));
136        del16_rshift8= simd_xor(del16_rshift8,simd_slli_16(del16_rshift8,2));
137        del16_rshift8= simd_xor(del16_rshift8,simd_slli_16(del16_rshift8,4));
138        del16_rshift8= simd_xor(del16_rshift8,simd_slli_16(del16_rshift8,8));
139       
140        del16_rshift1= simd_andc(del16_rshift1,delmask);
141        del16_rshift2= simd_andc(del16_rshift2,delmask);
142        del16_rshift4= simd_andc(del16_rshift4,delmask);
143        del16_rshift8= simd_andc(del16_rshift8,delmask);
144       
145        del16_rshift2= simd_sub_16(del16_rshift2,simd_srli_16(simd_and(del16_rshift1,del16_rshift2),1));
146       
147        del16_rshift4= simd_sub_16(del16_rshift4,simd_srli_16(simd_and(del16_rshift1,del16_rshift4),1));
148        shift_bits= simd_and(del16_rshift2,del16_rshift4);
149        del16_rshift4= simd_or(simd_srli_16(shift_bits,2),simd_xor(del16_rshift4,shift_bits));
150       
151        del16_rshift8= simd_sub_16(del16_rshift8,simd_srli_16(simd_and(del16_rshift1,del16_rshift8),1));
152        shift_bits= simd_and(del16_rshift2,del16_rshift8);
153        del16_rshift8= simd_or(simd_srli_16(shift_bits,2),simd_xor(del16_rshift8,shift_bits)); 
154        shift_bits= simd_and(del16_rshift4,del16_rshift8);
155        del16_rshift8= simd_or(simd_srli_16(shift_bits,4),simd_xor(del16_rshift8,shift_bits));
156       
157        s = simd_andc(s, delmask);
158        do_right16_shifts (s, del16_rshift1, del16_rshift2, del16_rshift4,  del16_rshift8)
159
160}
161
162
163static inline void del_count(BitBlock delmask, short *u8_bytes_per_reg){
164
165BitBlock delcounts_2;
166BitBlock delcounts_4;
167BitBlock delcounts_8;
168BitBlock delcounts_16;
169
170delcounts_2 = simd_add_2_lh(delmask, delmask);
171delcounts_4 = simd_add_4_lh(delcounts_2, delcounts_2);
172delcounts_8 = simd_add_8_lh(delcounts_4, delcounts_4);
173delcounts_16 = simd_add_16_lh(delcounts_8, delcounts_8);
174sisd_store_aligned(simd_sub_16(simd_const_16(16), delcounts_16), (BytePack *) &u8_bytes_per_reg[0]);
175
176}
177
178#define double_int64_adc(x1, x2, y1, y2, rslt1, rslt2, carry) \
179  __asm__  ("sahf\n\t" \
180            "adc %[e1], %[z1]\n\t" \
181            "adc %[e2], %[z2]\n\t" \
182            "lahf\n\t" \
183         : [z1] "=r" (rslt1), [z2] "=r" (rslt2), [carry] "=a" (carry) \
184         : "[z1]" (x1), "[z2]" (x2), \
185           [e1] "r" (y1), [e2] "r" (y2), \
186           "[carry]" (carry) \
187         : "cc")
188
189static inline BitBlock adc128(BitBlock first, BitBlock second, int &carry)
190{
191  union {__m128i bitblock;
192         uint64_t int64[2];} rslt;
193
194  union {__m128i bitblock;
195         uint64_t int64[2];} x;
196
197  union {__m128i bitblock;
198         uint64_t int64[2];} y;
199
200  x.bitblock = first;
201  y.bitblock = second;
202
203  double_int64_adc(x.int64[0], x.int64[1], y.int64[0], y.int64[1], 
204                   rslt.int64[0], rslt.int64[1], carry);
205
206  return rslt.bitblock;
207}
208
209
210#define BLOCK_SIZE 128
211
212void do_process(FILE *infile, FILE *outfile) {
213
214  @decl
215
216  BytePack U16[16];
217  BytePack U16h[8];
218  BytePack U16l[8];
219
220  BitBlock doublepair[32];
221
222  BitBlock endmask;
223
224  BitBlock delmask[4];
225
226  BitBlock U8[32];
227
228  int block_pos = 0;
229  int pos = 0;
230
231  int bytes_read;
232
233  bool error_found = false;
234  int err_pos;
235//  while (bytes_read > 0) {
236  do {
237    pos = 0;
238    bytes_read = fread(&U16[0], 1, BLOCK_SIZE*2, infile);
239    if(bytes_read < BLOCK_SIZE*2){
240        endmask = sisd_sll(simd_const_1(1),sisd_from_int(bytes_read/2));
241//      ((uint16_t *) U16)[bytes_read/2] = 0;
242    }
243    else endmask = simd_const_1(0);
244
245    mask = simd_const_1(1);
246
247    for (int i=0; i< 8; i++){
248      U16h[i] = simd_pack_16_ll(U16[i*2+1],U16[i*2]);
249      U16l[i] = simd_pack_16_hh(U16[i*2+1],U16[i*2]);
250    }
251
252
253    s2p_bytepack(U16h[7], U16h[6], U16h[5], U16h[4], U16h[3], U16h[2], U16h[1], U16h[0],
254    u16h[0], u16h[1], u16h[2], u16h[3], u16h[4], u16h[5], u16h[6], u16h[7]);
255
256    s2p_bytepack(U16l[7], U16l[6], U16l[5], U16l[4], U16l[3], U16l[2], U16l[1], U16l[0],
257    u16l[0], u16l[1], u16l[2], u16l[3], u16l[4], u16l[5], u16l[6], u16l[7]);
258
259    @stmts
260
261    if (bitblock_has_bit(u16.error)) {
262       
263       err_pos = count_forward_zeroes(u16.error);
264       error_found = true;
265        if ((err_pos * 2 == bytes_read)) {
266          err_pos--;
267           fprintf(stderr, "EOF with incomplete UTF-16 sequence at position %i in source.\n", block_pos + err_pos*2);
268        }
269        else {
270          if((((unsigned char *)U16h)[err_pos]< 0xD8) || (((unsigned char *)U16h)[err_pos] >= 0xE0))
271            err_pos--;
272           fprintf(stderr, "Illegal UTF-16 sequence at position %i in source.\n", block_pos + err_pos*2);
273        }
274        endmask = sisd_sll(simd_const_1(1),sisd_from_int(err_pos));
275    }
276
277    for (int i=0; i< 8; i++){
278        interleave4(simd_const_8(0), u8_pre[i], u8_butlast[i], u8_last[i],
279                                doublepair[i*4], doublepair[i*4+1], 
280                                doublepair[i*4+2], doublepair[i*4+3]);
281    }
282        interleave4(simd_const_1(1), simd_or(endmask, simd_not(u16.utf8_3)), 
283                                simd_or(endmask, u16.ASCII), endmask,
284                                delmask[0], delmask[1], delmask[2], delmask[3]);
285
286
287     for (int i=0; i< 32; i=i+4){
288        bit_del_16(doublepair[i],delmask[0]);
289        bit_del_16(doublepair[i+1],delmask[1]);
290        bit_del_16(doublepair[i+2],delmask[2]);
291        bit_del_16(doublepair[i+3],delmask[3]);
292     }
293
294    short u8_bytes_per_reg[8];
295    char * U8_as_char = (char *) U8;
296
297    for (int i=0; i< 4; i++){
298      p2s_bytemerge(doublepair[i],doublepair[4+i],doublepair[8+i],doublepair[12+i],doublepair[16+i],doublepair[20+i],doublepair[24+i],doublepair[28+i],
299                        U8[i*8+7],U8[i*8+6],U8[i*8+5],U8[i*8+4],U8[i*8+3],U8[i*8+2],U8[i*8+1],U8[i*8]);
300       for(int k=0; k<8; k++) u8_bytes_per_reg[k] = 0;
301       del_count(delmask[i],u8_bytes_per_reg);
302//        print_bit_block("delmask",delmask[i]);
303 
304       for(int j=0; j<8; j++){
305        sisd_store_unaligned(U8[i*8+j],(SIMD_type *) &U8_as_char[pos]);
306        pos += u8_bytes_per_reg[j];
307       }
308    }
309    fwrite(U8_as_char , 1 , pos , outfile );
310
311    block_pos += BLOCK_SIZE*2;
312//     fwrite(U8_as_char , 1 , 512 , outfile );
313  } while ((bytes_read == BLOCK_SIZE * 2) && !error_found);
314    fclose(infile);
315    fclose(outfile);
316    if (error_found) {
317        exit(-1);
318    }
319
320  fclose(infile);
321  fclose(outfile);
322}
323
324
325
326
327int
328main(int argc, char * argv[]) {
329  if (argc < 2) {
330    printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
331          exit(-1);
332  }
333  char * filename = argv[1];
334#ifdef BUFFER_PROFILING
335  transcode_timer = init_BOM_timer(BUFFER_SIZE);
336#endif
337  FILE *infile, *outfile;
338  infile = fopen(filename, "rb");
339  if (!infile) {
340      fprintf(stderr, "Error: cannot open %s for input.\n", filename);
341      exit(-1);
342  }
343
344  if (argc < 3) outfile = stdout;
345  else {
346    outfile = fopen(argv[2], "wb");
347    if (!outfile) {
348      fprintf(stderr, "Error: cannot open %s for writing.\n", argv[2]);
349      exit(-1);
350    }
351  }
352
353  do_process(infile, outfile);
354
355#ifdef BUFFER_PROFILING
356  printf("Buffer conversion timing.\n");
357  dump_BOM_table(transcode_timer);
358#endif
359  return(0);
360}
Note: See TracBrowser for help on using the repository browser.