source: proto/u8u16/pablo_template.c @ 1814

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

Revert s2p 128,256.

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