source: proto/u16u8/template.c @ 620

Last change on this file since 620 was 620, checked in by cameron, 9 years ago

Use s2p instead of s2p_bytepack

File size: 12.5 KB
RevLine 
[361]1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
[366]4#include <stdint.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/stat.h>
[464]8
9#include "../lib/lib_simd.h"
10#include "../lib/block_carry.h"
11
[361]12typedef SIMD_type BytePack;
13typedef SIMD_type BitBlock;
14
15
16// Profiling
17
[609]18#include "../lib/perflib/perfsec.h"
[616]19#include "../lib/s2p.h"
20#include "../lib/p2s.h"
[609]21
[616]22
[361]23#ifdef BUFFER_PROFILING
[609]24        BOM_Table * transcode_timer;
[361]25
[609]26#elif CODE_CLOCKER
[501]27        #define NUM_EVENTS 1
28        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
29        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
30        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
31        int cal_size = 20;
[609]32        CC * transcode_timer = new CC(Events,NUM_EVENTS,cal_size);
33#else
34        void * transcode_timer;
[501]35#endif
36
[366]37/*===========================================================================*/
38/* UErrorCode */
39/* Extracted from ICU */
40/*===========================================================================*/
[361]41
[366]42typedef enum UErrorCode {
43
44    U_ZERO_ERROR              =  0,     /**< No error, no warning. */
45    U_TRUNCATED_CHAR_FOUND    = 11,     /**< Character conversion: Incomplete input sequence. */
46    U_ILLEGAL_CHAR_FOUND      = 12,     /**< Character conversion: Illegal input sequence/combination of input units. */
47} UErrorCode;
48
49typedef  uint16_t UChar;
50
[361]51static inline void interleave4(BitBlock p0, BitBlock p1, BitBlock p2, BitBlock p3, 
52                               BitBlock& s0, BitBlock& s1, BitBlock& s2, BitBlock& s3);
53
54static inline void interleave4(BitBlock p0, BitBlock p1, BitBlock p2, BitBlock p3, 
55                               BitBlock& s0, BitBlock& s1, BitBlock& s2, BitBlock& s3){
56        BitBlock hpair0 = simd_mergel_1(p1, p0);
57        BitBlock hpair1 = simd_mergeh_1(p1, p0);
58        BitBlock lpair0 = simd_mergel_1(p3, p2);
59        BitBlock lpair1 = simd_mergeh_1(p3, p2);
60        s0 = simd_mergel_2(lpair0,hpair0);
61        s1 = simd_mergeh_2(lpair0,hpair0);
62        s2 = simd_mergel_2(lpair1,hpair1);
63        s3 = simd_mergeh_2(lpair1,hpair1);
64}
65
66
67
68
69#define do_right16_shifts(vec,rshift1,rshift2,rshift4,rshift8)  \
70{BitBlock s2; \
71vec= simd_sub_16(vec,simd_srli_16(simd_and(rshift1,vec) ,1) ) ; \
72s2= simd_and(rshift2,vec) ; \
73vec= simd_or(simd_srli_16(s2,2) ,simd_xor(vec,s2) ) ; \
74s2= simd_and(rshift4,vec) ; \
75vec= simd_or(simd_srli_16(s2,4) ,simd_xor(vec,s2) ) ; \
76s2= simd_and(rshift8,vec) ; \
77vec= simd_or(simd_srli_16(s2,8) ,simd_xor(vec,s2) ) ; \
78}
79
[602]80static inline void delinfo_16(BitBlock & del16_rshift1, BitBlock & del16_rshift2, BitBlock & del16_rshift4,
81                              BitBlock & del16_rshift8, BitBlock delmask){
[361]82       
83        BitBlock del16_trans2;
84        BitBlock del16_trans4;
85        BitBlock del16_trans8;
86        BitBlock shift_bits;
87       
88        del16_rshift1= simd_xor(simd_slli_16(delmask,1),simd_slli_16(delmask,2));
89        del16_rshift1= simd_xor(del16_rshift1,simd_slli_16(del16_rshift1,2));
90        del16_rshift1= simd_xor(del16_rshift1,simd_slli_16(del16_rshift1,4));
91        del16_rshift1= simd_xor(del16_rshift1,simd_slli_16(del16_rshift1,8));
92       
93        del16_trans2= simd_and(del16_rshift1,delmask);
94        del16_rshift2= simd_xor(simd_slli_16(del16_trans2,1),simd_slli_16(del16_trans2,2));
95        del16_rshift2= simd_xor(del16_rshift2,simd_slli_16(del16_rshift2,2));
96        del16_rshift2= simd_xor(del16_rshift2,simd_slli_16(del16_rshift2,4));
97        del16_rshift2= simd_xor(del16_rshift2,simd_slli_16(del16_rshift2,8));
98       
99        del16_trans4= simd_and(del16_rshift2,del16_trans2);
100        del16_rshift4= simd_xor(simd_slli_16(del16_trans4,1),simd_slli_16(del16_trans4,2));
101        del16_rshift4= simd_xor(del16_rshift4,simd_slli_16(del16_rshift4,2));
102        del16_rshift4= simd_xor(del16_rshift4,simd_slli_16(del16_rshift4,4));
103        del16_rshift4= simd_xor(del16_rshift4,simd_slli_16(del16_rshift4,8));
104       
105        del16_trans8= simd_and(del16_rshift4,del16_trans4);
106        del16_rshift8= simd_xor(simd_slli_16(del16_trans8,1),simd_slli_16(del16_trans8,2));
107        del16_rshift8= simd_xor(del16_rshift8,simd_slli_16(del16_rshift8,2));
108        del16_rshift8= simd_xor(del16_rshift8,simd_slli_16(del16_rshift8,4));
109        del16_rshift8= simd_xor(del16_rshift8,simd_slli_16(del16_rshift8,8));
110       
111        del16_rshift1= simd_andc(del16_rshift1,delmask);
112        del16_rshift2= simd_andc(del16_rshift2,delmask);
113        del16_rshift4= simd_andc(del16_rshift4,delmask);
114        del16_rshift8= simd_andc(del16_rshift8,delmask);
115       
116        del16_rshift2= simd_sub_16(del16_rshift2,simd_srli_16(simd_and(del16_rshift1,del16_rshift2),1));
117       
118        del16_rshift4= simd_sub_16(del16_rshift4,simd_srli_16(simd_and(del16_rshift1,del16_rshift4),1));
119        shift_bits= simd_and(del16_rshift2,del16_rshift4);
120        del16_rshift4= simd_or(simd_srli_16(shift_bits,2),simd_xor(del16_rshift4,shift_bits));
121       
122        del16_rshift8= simd_sub_16(del16_rshift8,simd_srli_16(simd_and(del16_rshift1,del16_rshift8),1));
123        shift_bits= simd_and(del16_rshift2,del16_rshift8);
124        del16_rshift8= simd_or(simd_srli_16(shift_bits,2),simd_xor(del16_rshift8,shift_bits)); 
125        shift_bits= simd_and(del16_rshift4,del16_rshift8);
126        del16_rshift8= simd_or(simd_srli_16(shift_bits,4),simd_xor(del16_rshift8,shift_bits));
[602]127}
128
129static inline void bit_del_16(BitBlock &s, BitBlock del16_rshift1, BitBlock del16_rshift2, BitBlock del16_rshift4,
130                              BitBlock del16_rshift8, BitBlock delmask) {
[361]131        s = simd_andc(s, delmask);
[602]132        do_right16_shifts (s, del16_rshift1, del16_rshift2, del16_rshift4,  del16_rshift8);
[361]133}
134
135
136static inline void del_count(BitBlock delmask, short *u8_bytes_per_reg){
137
138BitBlock delcounts_2;
139BitBlock delcounts_4;
140BitBlock delcounts_8;
141BitBlock delcounts_16;
142
143delcounts_2 = simd_add_2_lh(delmask, delmask);
144delcounts_4 = simd_add_4_lh(delcounts_2, delcounts_2);
145delcounts_8 = simd_add_8_lh(delcounts_4, delcounts_4);
146delcounts_16 = simd_add_16_lh(delcounts_8, delcounts_8);
147sisd_store_aligned(simd_sub_16(simd_const_16(16), delcounts_16), (BytePack *) &u8_bytes_per_reg[0]);
148}
149
150
151
152#define BLOCK_SIZE 128
153
[366]154void u16u8(char ** targetbuf, const char * targetlimit, const UChar ** srcbuf, const UChar * srclimit, UErrorCode * err){
[361]155
156  @decl
157
[393]158SIMD_type u16l [8];
159SIMD_type u16h [8];
160
161
[366]162  BytePack * U16;
[361]163  BytePack U16h[8];
164  BytePack U16l[8];
165
166  BitBlock doublepair[32];
167
168  BitBlock endmask;
169
170  BitBlock delmask[4];
171
172  BitBlock U8[32];
173
[366]174  int target_bckup_steps = 0;
[361]175  int pos = 0;
176
[471]177  intptr_t  units_remaining  = 0;
178  intptr_t  units_read  = 0;
[361]179
180  bool error_found = false;
181  int err_pos;
[366]182
[464]183  @stream_stmts
[366]184
[361]185  do {
[475]186   
187    PERF_SEC_START(transcode_timer);
[366]188
189    U16 = (BytePack *)(*srcbuf);
[471]190    units_remaining = srclimit-(*srcbuf);
[366]191
[471]192    if(units_remaining < BLOCK_SIZE){
193        endmask = sisd_sll(simd_const_1(1),sisd_from_int((int) units_remaining));
194        units_read = units_remaining;
195
[366]196//      ((uint16_t *) U16)[units_read/2] = 0;
[361]197    }
[471]198    else {
199        endmask = simd_const_1(0);
200        units_read = BLOCK_SIZE;
201    }
[361]202
203    for (int i=0; i< 8; i++){
[366]204      U16h[i] = simd_pack_16_ll(sisd_load_unaligned(&U16[i*2+1]),sisd_load_unaligned(&U16[i*2]));
205      U16l[i] = simd_pack_16_hh(sisd_load_unaligned(&U16[i*2+1]),sisd_load_unaligned(&U16[i*2]));
[361]206    }
207
[620]208    s2p(U16h[0], U16h[1], U16h[2], U16h[3], U16h[4], U16h[5], U16h[6], U16h[7],
[361]209    u16h[0], u16h[1], u16h[2], u16h[3], u16h[4], u16h[5], u16h[6], u16h[7]);
210
[620]211    s2p(U16l[0], U16l[1], U16l[2], U16l[3], U16l[4], U16l[5], U16l[6], U16l[7],
[361]212    u16l[0], u16l[1], u16l[2], u16l[3], u16l[4], u16l[5], u16l[6], u16l[7]);
213
[393]214array_u16l__0_ = u16l [0];
215array_u16l__1_ = u16l [1];
216array_u16l__2_ = u16l [2];
217array_u16l__3_ = u16l [3];
218array_u16l__4_ = u16l [4];
219array_u16l__5_ = u16l [5];
220array_u16l__6_ = u16l [6];
221array_u16l__7_ = u16l [7];
222
223array_u16h__0_ = u16h [0];
224array_u16h__1_ = u16h [1];
225array_u16h__2_ = u16h [2];
226array_u16h__3_ = u16h [3];
227array_u16h__4_ = u16h [4];
228array_u16h__5_ = u16h [5];
229array_u16h__6_ = u16h [6];
230array_u16h__7_ = u16h [7];
231
[464]232    @block_stmts
[361]233
[393]234/* Convert flattened array values to arrays */
235SIMD_type u8_pre [8];
236u8_pre[0] = array_u8_pre__0_;
237u8_pre[1] = array_u8_pre__1_;
238u8_pre[2] = array_u8_pre__2_;
239u8_pre[3] = array_u8_pre__3_;
240u8_pre[4] = array_u8_pre__4_;
241u8_pre[5] = array_u8_pre__5_;
242u8_pre[6] = array_u8_pre__6_;
243u8_pre[7] = array_u8_pre__7_;
244
245SIMD_type u8_butlast [8];
246u8_butlast[0] = array_u8_butlast__0_;
247u8_butlast[1] = array_u8_butlast__1_;
248u8_butlast[2] = array_u8_butlast__2_;
249u8_butlast[3] = array_u8_butlast__3_;
250u8_butlast[4] = array_u8_butlast__4_;
251u8_butlast[5] = array_u8_butlast__5_;
252u8_butlast[6] = array_u8_butlast__6_;
253u8_butlast[7] = array_u8_butlast__7_;
254
255SIMD_type u8_last [8];
256u8_last[0] = array_u8_last__0_;
257u8_last[1] = array_u8_last__1_;
258u8_last[2] = array_u8_last__2_;
259u8_last[3] = array_u8_last__3_;
260u8_last[4] = array_u8_last__4_;
261u8_last[5] = array_u8_last__5_;
262u8_last[6] = array_u8_last__6_;
263u8_last[7] = array_u8_last__7_;
264
265
266    if (bitblock_has_bit(strct_u16__error_)) {
[361]267       
[393]268       err_pos = count_forward_zeroes(strct_u16__error_);
[361]269       error_found = true;
[366]270        if ((err_pos == units_read)) {
271                err_pos--;
272                *err = U_TRUNCATED_CHAR_FOUND;
273                (*srcbuf) += err_pos;
[393]274                if(err_pos<0){
275                        target_bckup_steps = 2;
276                        (*targetbuf) -= target_bckup_steps;
277                        return;
278                }               
[361]279        }
280        else {
[366]281          if((((unsigned char *)U16h)[err_pos]< 0xDC) || (((unsigned char *)U16h)[err_pos] >= 0xE0))
282                err_pos--;
283                *err = U_ILLEGAL_CHAR_FOUND;
284                (*srcbuf) += err_pos;
285                if(err_pos<0){
286                        target_bckup_steps = 2;
287                        (*targetbuf) -= target_bckup_steps;
288                        return;
289                }
[361]290        }
291        endmask = sisd_sll(simd_const_1(1),sisd_from_int(err_pos));
292    }
293
294    for (int i=0; i< 8; i++){
295        interleave4(simd_const_8(0), u8_pre[i], u8_butlast[i], u8_last[i],
296                                doublepair[i*4], doublepair[i*4+1], 
297                                doublepair[i*4+2], doublepair[i*4+3]);
298    }
[393]299
300        interleave4(simd_const_1(1), simd_or(endmask, simd_not(strct_u16__utf8_3_)), 
301                                simd_or(endmask, strct_u16__ASCII_), endmask,
[361]302                                delmask[0], delmask[1], delmask[2], delmask[3]);
303
304
[602]305
306     BitBlock shft1, shft2, shft3, shft4;
307     delinfo_16(shft1, shft2, shft3, shft4, delmask[0]);
[361]308     for (int i=0; i< 32; i=i+4){
[602]309        bit_del_16(doublepair[i],shft1, shft2, shft3, shft4, delmask[0]);
[361]310     }
[602]311     delinfo_16(shft1, shft2, shft3, shft4, delmask[1]);
312     for (int i=0; i< 32; i=i+4){
313        bit_del_16(doublepair[i+1],shft1, shft2, shft3, shft4, delmask[1]);
314     }
315     delinfo_16(shft1, shft2, shft3, shft4, delmask[2]);
316     for (int i=0; i< 32; i=i+4){
317        bit_del_16(doublepair[i+2],shft1, shft2, shft3, shft4, delmask[2]);
318     }
319     delinfo_16(shft1, shft2, shft3, shft4, delmask[3]);
320     for (int i=0; i< 32; i=i+4){
321        bit_del_16(doublepair[i+3],shft1, shft2, shft3, shft4, delmask[3]);
322     }
[361]323
324    short u8_bytes_per_reg[8];
325
326    for (int i=0; i< 4; i++){
327      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],
328                        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]);
329       for(int k=0; k<8; k++) u8_bytes_per_reg[k] = 0;
330       del_count(delmask[i],u8_bytes_per_reg);
331 
332       for(int j=0; j<8; j++){
[366]333        sisd_store_unaligned(U8[i*8+j],(SIMD_type *) (*targetbuf));
334        *targetbuf += u8_bytes_per_reg[j];
[361]335       }
336    }
337
[366]338    if(!error_found) (*srcbuf) += units_read;
[361]339
[475]340
341    PERF_SEC_END(transcode_timer, units_read*2);
342
343
[366]344    } while ((units_read == BLOCK_SIZE) && !error_found);
345
[361]346}
347
348
349
350
351int
352main(int argc, char * argv[]) {
[366]353        char * infilename, * outfilename;       
354        FILE *infile, *outfile;
355        struct stat fileinfo;
356        const UChar * srcbuf;
357        const UChar * srclimit;
358        const char * targetlimit;
359        char * targetbuf;
360        char * target_head;
361        UErrorCode status;
362        int chars_read;
[361]363
[366]364        if (argc < 2) {
365                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
366                exit(-1);
367        }
[361]368
[366]369        infilename = argv[1];
370        stat(infilename, &fileinfo);
371        infile = fopen(infilename, "rb");
372        if (!infile) {
373                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
374                exit(-1);
375        }
376       
377        if (argc < 3) outfile = stdout;
378        else {
379                outfilename = argv[2];
380                outfile = fopen(outfilename, "wb");
381                if (!outfile) {
382                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
383                        exit(-1);
384                }
385        }
[361]386
[366]387
388        srcbuf = (UChar *) malloc(fileinfo.st_size+1);
389        if (!srcbuf) {
[393]390              fprintf(stderr, "Error: buffer for %s of size %zu cannot be created.\n", infilename, fileinfo.st_size+1);
[366]391              exit(-1);
392        }
393
[475]394        PERF_SEC_INIT(transcode_timer);
395
396
[366]397        chars_read = fread((void *)srcbuf, 1, fileinfo.st_size, infile);
398
399        srclimit = srcbuf + chars_read/2;
400//      (*srcbuf)[fileinfo.st_size] = '\0';
401        fclose(infile);
402
403        targetbuf = (char *) malloc(chars_read*2);
404        targetlimit = targetbuf + chars_read*2;
405        target_head = targetbuf;
406
407        u16u8(&targetbuf, targetlimit, &srcbuf, srclimit, &status);
408        fwrite(target_head , 1 ,  targetbuf - target_head, outfile );
409
410        if (status == U_ILLEGAL_CHAR_FOUND) {
[393]411                fprintf(stderr, "Illegal UTF-16 sequence at position %lu in source.\n", chars_read-(srclimit-srcbuf)*2);
[366]412        }
413        else if (status == U_TRUNCATED_CHAR_FOUND) {
[393]414                fprintf(stderr, "EOF with incomplete UTF-16 sequence at position %lu in source.\n",chars_read-(srclimit-srcbuf)*2);
[366]415        }
416
[475]417        PERF_SEC_DUMP(transcode_timer);
418
[471]419        fclose(outfile);
[366]420
421        return(0);
[361]422}
Note: See TracBrowser for help on using the repository browser.