source: proto/u8u16/pablo_template.cpp @ 1756

Last change on this file since 1756 was 1756, checked in by ksherdy, 8 years ago

Update s2p,p2s includes.

File size: 11.2 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7
8#define LocalCarryDeclare(name, count)\
9CarryArray<count> name;\
10
11#include "../lib/bitblock.hpp"
12#include "../lib/carryQ.hpp"
13
14#define minimum(x,y) ((x) <(y) ?(x) :(y) )
15#include <iostream>
16using namespace std;
17
18#include "../lib/perflib/perfsec.h"
19
20// Profiling
21#if (defined(BUFFER_PROFILING) || defined(CODE_CLOCKER))
22  #include "../lib/perflib/perfsec.h"
23#endif
24
25#ifdef BUFFER_PROFILING
26BOM_Table * transcode_timer;
27#endif
28
29#ifdef CODE_CLOCKER
30        #define NUM_EVENTS 1
31        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
32        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
33        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
34        int cal_size = 20;
35        CC * transcode_timer = new CC(Events,NUM_EVENTS,cal_size);
36#endif
37
38/*===========================================================================*/
39/* UErrorCode */
40/* Extracted from ICU */
41/*===========================================================================*/
42
43typedef enum UErrorCode {
44
45    U_ZERO_ERROR              =  0,     /**< No error, no warning. */
46    U_TRUNCATED_CHAR_FOUND    = 11,     /**< Character conversion: Incomplete input sequence. */
47    U_ILLEGAL_CHAR_FOUND      = 12,     /**< Character conversion: Illegal input sequence/combination of input units. */
48} UErrorCode;
49
50typedef  uint16_t UChar;
51
52
53#define do_right8_shifts(vec, rshift1, rshift2, rshift4) \
54do { BitBlock s2; \
55  vec = simd<8>::sub(vec, simd<16>::srli<1>(simd_and(rshift1, vec))); \
56  s2 = simd_and(rshift2, vec);\
57  vec = simd_or(simd<16>::srli<2>(s2), simd_xor(vec, s2));\
58  s2 = simd_and(rshift4, vec);\
59  vec = simd_or(simd<16>::srli<4>(s2), simd_xor(vec, s2));\
60} while(0)
61
62static inline void del_info_8(BitBlock &del8_rshift1, BitBlock &del8_rshift2, BitBlock &del8_rshift4, BitBlock delmask){
63        BitBlock del8_trans2;
64        BitBlock del8_trans4;
65        BitBlock shift_bits;
66       
67        del8_rshift1 = simd_xor(simd<8>::slli<1>(delmask), simd<8>::slli<2>(delmask));
68        del8_rshift1 = simd_xor(del8_rshift1, simd<8>::slli<2>(del8_rshift1));
69        del8_rshift1 = simd_xor(del8_rshift1, simd<8>::slli<4>(del8_rshift1));
70        /* Transition to even delcount: odd delcount to left, this one deleted. */
71        del8_trans2 = simd_and(del8_rshift1, delmask);
72        /* Odd number of transition positions to left. */
73        del8_rshift2 = simd_xor(simd<8>::slli<1>(del8_trans2), simd<8>::slli<2>(del8_trans2));
74        del8_rshift2 = simd_xor(del8_rshift2, simd<8>::slli<2>(del8_rshift2));
75        del8_rshift2 = simd_xor(del8_rshift2, simd<8>::slli<4>(del8_rshift2));
76        /* Transition positions: odd |del2count| to left, this one a transition to even. */
77        del8_trans4 = simd_and(del8_rshift2, del8_trans2);
78        del8_rshift4 = simd_xor(simd<8>::slli<1>(del8_trans4), simd<8>::slli<2>(del8_trans4));
79        del8_rshift4 = simd_xor(del8_rshift4, simd<8>::slli<2>(del8_rshift4));
80        del8_rshift4 = simd_xor(del8_rshift4, simd<8>::slli<4>(del8_rshift4));
81        /* Only move bits that are not deleted. */
82        del8_rshift1 = simd_andc(del8_rshift1, delmask);
83        del8_rshift2 = simd_andc(del8_rshift2, delmask);
84        del8_rshift4 = simd_andc(del8_rshift4, delmask);
85        /* Update |del8_rshift2| to apply after |del8_rshift1|. */
86        del8_rshift2 = simd<8>::sub(del8_rshift2, simd<16>::srli<1>(simd_and(del8_rshift1, del8_rshift2)));
87        /* Update |del8_rshift4| to apply after |del8_rshift2| and |del8_rshift1|. */
88        del8_rshift4 = simd<8>::sub(del8_rshift4, simd<16>::srli<1>(simd_and(del8_rshift1, del8_rshift4)));
89        shift_bits = simd_and(del8_rshift2, del8_rshift4);
90        del8_rshift4 = simd_or(simd<16>::srli<4>(shift_bits), simd_xor(del8_rshift4, shift_bits));
91}
92
93
94static inline void del_count(BitBlock delmask, unsigned char *u16_units_per_reg){
95
96        BitBlock delcounts_8 = simd<8>::popcount(delmask);
97        bitblock::store_unaligned((BytePack *) u16_units_per_reg, simd<8>::sub(simd<8>::constant<8>(), delcounts_8));
98}
99
100
101#define BUFFER_SIZE (BLOCK_SIZE * 100)
102
103@global
104
105void u8u16(UChar ** targetbuf, const UChar * targetlimit, char ** srcbuf, const char * srclimit, UErrorCode * err){
106
107  @decl
108
109  BitBlock u16l [8];
110  BitBlock u16h [8];
111
112
113  BytePack U16s[16];
114  BytePack U16h[8];
115  BytePack U16l[8];
116
117  BitBlock EOF_mask = simd<1>::constant<1>();
118
119
120  BitBlock bit[8];
121  BitBlock u16hi[8];
122  BitBlock u16lo[8];
123
124  int pos = 0;
125
126  bool error_found = false;
127  int err_pos;
128
129  @stream_stmts
130
131       
132    while (((*srcbuf) < srclimit) || @any_carry ){
133     
134      int u8advance = minimum(srclimit-(*srcbuf),BLOCK_SIZE);
135
136      if(u8advance < BLOCK_SIZE){
137        EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-u8advance));
138
139      }
140      else
141        EOF_mask = simd<1>::constant<1>();
142     
143      BytePack * U8pack = (BytePack *) (*srcbuf);
144      bit[0] = bitblock::load_unaligned(&U8pack[0]);
145      bit[1] = bitblock::load_unaligned(&U8pack[1]);
146      bit[2] = bitblock::load_unaligned(&U8pack[2]);
147      bit[3] = bitblock::load_unaligned(&U8pack[3]);
148      bit[4] = bitblock::load_unaligned(&U8pack[4]);
149      bit[5] = bitblock::load_unaligned(&U8pack[5]);
150      bit[6] = bitblock::load_unaligned(&U8pack[6]);
151      bit[7] = bitblock::load_unaligned(&U8pack[7]); 
152     
153      s2p(bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7],
154      bit[0], bit[1], bit[2], bit[3], bit[4], bit[5], bit[6], bit[7]);
155
156        bit[0] = simd_and(bit[0], EOF_mask);
157        bit[1] = simd_and(bit[1], EOF_mask);
158        bit[2] = simd_and(bit[2], EOF_mask);
159        bit[3] = simd_and(bit[3], EOF_mask);
160        bit[4] = simd_and(bit[4], EOF_mask);
161        bit[5] = simd_and(bit[5], EOF_mask);
162        bit[6] = simd_and(bit[6], EOF_mask);
163        bit[7] = simd_and(bit[7], EOF_mask);
164   
165      @block_stmts
166     
167      delmask |= ~EOF_mask;
168      error_found = bitblock::any(error_mask);
169      if (error_found) {
170        int errpos = count_forward_zeroes(error_mask);
171        if (errpos >= u8advance) {
172          *err = U_TRUNCATED_CHAR_FOUND;
173        }
174        else *err = U_ILLEGAL_CHAR_FOUND;
175        BitBlock cutoff_mask = bitblock::sll(simd<1>::constant<1>(), convert(errpos));
176        BitBlock errbit = simd_andc(error_mask, bitblock::slli<1>(cutoff_mask));
177        u8advance = errpos;
178        if (bitblock::any(simd_and(u8.scope44, errbit))) {
179          u8advance -= 3;
180          /* May have already first of a surrogate pair to targetbuf. */
181          if (u8advance == -3) *targetbuf -= 1;
182        }
183        else if (bitblock::any(simd_and(u8.scope43, errbit))) {
184          u8advance -= 2;
185        }
186        else if (bitblock::any(simd_and(u8.scope33, errbit))) {
187          u8advance -= 2;
188        }
189        else if (bitblock::any(simd_and(simd_or(u8.scope22, simd_or(u8.scope32, u8.scope42)), errbit))) {
190          u8advance -= 1;
191        }
192        if (u8advance <= 0) {
193          (*srcbuf) += u8advance;
194          return;
195        }
196        delmask |= bitblock::sll(simd<1>::constant<1>(), convert(u8advance));
197//      fprintf(stderr, "errpos = %i, u8advance = %i\n", errpos, u8advance);
198      }
199     
200       
201      if (bitblock::any(delmask)) {
202              BitBlock shift1, shift2, shift4;
203              del_info_8(shift1, shift2, shift4, delmask);
204              do_right8_shifts(u16lo[0], shift1, shift2, shift4);
205              do_right8_shifts(u16lo[1], shift1, shift2, shift4);
206              do_right8_shifts(u16lo[2], shift1, shift2, shift4);
207              do_right8_shifts(u16lo[3], shift1, shift2, shift4);
208              do_right8_shifts(u16lo[4], shift1, shift2, shift4);
209              do_right8_shifts(u16lo[5], shift1, shift2, shift4);
210              do_right8_shifts(u16lo[6], shift1, shift2, shift4);
211              do_right8_shifts(u16lo[7], shift1, shift2, shift4);
212              if (bitblock::any(u8.scope33 | u8surrogate)) {
213                      do_right8_shifts(u16hi[0], shift1, shift2, shift4);
214                      do_right8_shifts(u16hi[1], shift1, shift2, shift4);
215                      do_right8_shifts(u16hi[2], shift1, shift2, shift4);
216                      do_right8_shifts(u16hi[3], shift1, shift2, shift4);
217                      do_right8_shifts(u16hi[4], shift1, shift2, shift4);
218              }
219              do_right8_shifts(u16hi[5], shift1, shift2, shift4);
220              do_right8_shifts(u16hi[6], shift1, shift2, shift4);
221              do_right8_shifts(u16hi[7], shift1, shift2, shift4);
222      }
223
224      unsigned char u16_units_per_reg[16];
225     
226      p2s(u16lo[0],u16lo[1],u16lo[2],u16lo[3],u16lo[4],u16lo[5],u16lo[6],u16lo[7],
227                        U16l[0], U16l[1],U16l[2] ,U16l[3] ,U16l[4] ,U16l[5] ,U16l[6] ,U16l[7]);
228      p2s(u16hi[0],u16hi[1],u16hi[2],u16hi[3],u16hi[4],u16hi[5],u16hi[6],u16hi[7],
229                        U16h[0], U16h[1],U16h[2] ,U16h[3] ,U16h[4] ,U16h[5] ,U16h[6] ,U16h[7]);
230      for (int i=0; i<8; i++) {
231        U16s[2*i] = esimd<8>::mergel(U16l[i], U16h[i]);
232        U16s[2*i+1] = esimd<8>::mergeh(U16l[i], U16h[i]);
233      }
234       
235      for(int k=0; k<16; k++) u16_units_per_reg[k] = 0;
236      del_count(delmask,u16_units_per_reg);
237
238      for(int j=0; j<16; j++){
239        bitblock::store_unaligned((BitBlock *) (*targetbuf), U16s[j]);
240        *targetbuf += u16_units_per_reg[j];
241      }
242
243      (*srcbuf) += u8advance;
244         
245      if (error_found) return;
246    }
247    *err = U_ZERO_ERROR;
248}
249
250
251void do_process(FILE *infile, FILE *outfile) {
252
253  int buf_pos = 0;
254  int bytes_available = 0;
255  int excess_bytes, i;
256  char srcbuf[BUFFER_SIZE+BLOCK_SIZE];
257  char * srclimit;
258  UChar targetbuf[BUFFER_SIZE+BLOCK_SIZE];
259  UChar * targetlimit;
260  UChar * targetbuf_start;
261  UChar * targetbuf_ptr=targetbuf;
262  char * srcbuf_ptr=srcbuf;
263  UErrorCode status;
264 
265  bytes_available = fread((void *)srcbuf, sizeof(char), BUFFER_SIZE, infile);
266  srclimit = srcbuf + bytes_available;
267  targetbuf_start = targetbuf;
268
269  while(bytes_available>0){
270
271    PERF_SEC_START(transcode_timer);
272       
273    srcbuf_ptr=srcbuf;
274    targetbuf_ptr=targetbuf;
275
276    u8u16(&targetbuf_ptr, targetlimit, &srcbuf_ptr, srclimit, &status); 
277    excess_bytes = (int) (srclimit - srcbuf_ptr);
278    buf_pos += bytes_available - excess_bytes;
279
280    PERF_SEC_END(transcode_timer, bytes_available - excess_bytes);
281   
282   
283    fwrite(targetbuf_start , sizeof(UChar) ,  targetbuf_ptr - targetbuf_start, outfile );
284   
285    if (status == U_ILLEGAL_CHAR_FOUND) {
286            fclose(infile);
287            fclose(outfile);
288            fprintf(stderr, "Illegal UTF-8 sequence at position %lu in source.\n", (unsigned long) buf_pos);
289            exit(-1);
290    }
291    else if (status == U_TRUNCATED_CHAR_FOUND) {
292        for (i = 0; i < excess_bytes; i++) {
293          srcbuf[i] = srcbuf_ptr[i];
294        }
295        bytes_available = fread((void *) &(srcbuf[excess_bytes]), sizeof(char), BUFFER_SIZE-excess_bytes, infile);
296        if (bytes_available == 0) {
297            fclose(infile);
298            fclose(outfile);
299            fprintf(stderr, "EOF with incomplete UTF-8 sequence at position %lu in source.\n", (unsigned long) buf_pos);
300            exit(-1);
301        }
302        bytes_available += excess_bytes;
303        srclimit = srcbuf + bytes_available;
304    }
305    else {
306      bytes_available = fread((void *)srcbuf, sizeof(char), BUFFER_SIZE, infile);
307      srclimit = srcbuf + bytes_available;
308    }
309  }
310}
311
312
313
314int
315main(int argc, char * argv[]) {
316        char * infilename, * outfilename;       
317        FILE *infile, *outfile;
318
319        if (argc < 2) {
320                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
321                exit(-1);
322        }
323
324        infilename = argv[1];
325        infile = fopen(infilename, "rb");
326        if (!infile) {
327                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
328                exit(-1);
329        }
330       
331        if (argc < 3) outfile = stdout;
332        else {
333                outfilename = argv[2];
334                outfile = fopen(outfilename, "wb");
335                if (!outfile) {
336                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
337                        exit(-1);
338                }
339        }
340
341
342        PERF_SEC_INIT(transcode_timer);
343
344        do_process(infile, outfile);
345       
346        PERF_SEC_DUMP(transcode_timer);
347
348        PERF_SEC_DESTROY(transcode_timer);     
349       
350        fclose(infile);
351        fclose(outfile);
352        return(0);
353}
Note: See TracBrowser for help on using the repository browser.