source: proto/u8u16/pablo_template.cpp @ 1821

Last change on this file since 1821 was 1821, checked in by cameron, 8 years ago

Eliminate u8 struct

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