source: proto/parabix2/template.c @ 564

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

Tag matching fixes

File size: 13.0 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#include "../lib/lib_simd.h"
7#include "../lib/block_carry.h"
8
9typedef SIMD_type BytePack;
10typedef SIMD_type BitBlock;
11
12#include "xmldecl.h"
13#include "xml_error.c"
14#include "xmldecl.c"
15#include "namechars.h"
16
17#include "../lib/perflib/perfsec.h"
18
19#ifdef BUFFER_PROFILING
20        BOM_Table * parser_timer;
21
22#elif CODE_CLOCKER
23        #define NUM_EVENTS 1
24        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
25        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
26        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
27        int cal_size = 20;
28        CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
29#else
30        void * parser_timer;
31#endif
32
33int block_base=0;
34int buffer_base=0;
35int tag_depth=0;
36int buffer_last;
37char * source;
38
39typedef long ScanBlock;
40
41static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int)) {
42        int blk;
43        int block_pos = 0;
44
45        for (blk = 0; blk < blk_count; blk++) {
46                ScanBlock s = stream[blk];
47                while(s) {
48                        int code = (ProcessPos(cfzl(s) + block_pos));
49                        if (code) return code;
50                        s = s & (s-1);  // clear rightmost bit.
51                }
52                block_pos += 8 * sizeof(ScanBlock);
53        }
54        return 0;
55} 
56
57
58
59inline bool bit_test(unsigned char * bit_Map, int codepoint) {
60        return (bit_Map[codepoint/8] >> (7 - codepoint % 8)) & 1;
61}
62
63bool is_XML10_NameStrt_codepoint(int codepoint) {
64        switch (codepoint >> 12) {
65                case 0: return bit_test(NameStrt_XML10_0000_11FF, codepoint);
66                case 1: if (codepoint <= 0x11FF)
67                                return bit_test(NameStrt_XML10_0000_11FF, codepoint);
68                        else if (codepoint < 0x1E00) return false;
69                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
70                case 2: if (codepoint > 0x2182) return false;
71                        else return bit_test(NameStrt_XML10_2000_21FF, codepoint & 0x1FF);
72                case 3: if (codepoint > 0x312C) return false;
73                        else return bit_test(NameStrt_XML10_3000_31FF, codepoint & 0x1FF);
74                case 4: return codepoint >= 0x4E00;
75                case 5: case 6: case 7: case 8: return true;
76                case 9: return codepoint <= 0x9FA5;
77                case 0xA: return codepoint >= 0xAC00;
78                case 0xB: case 0xC: return true;
79                case 0xD: return codepoint <= 0xD7A3;
80                default: return false;
81        }
82}
83
84bool is_XML10_NameChar_codepoint(int codepoint) {
85        switch (codepoint >> 12) {
86                case 0: return bit_test(NameChar_XML10_0000_11FF, codepoint);
87                case 1: if (codepoint <= 0x11FF)
88                                return bit_test(NameChar_XML10_0000_11FF, codepoint);
89                        else if (codepoint < 0x1E00) return false;
90                        else return bit_test(NameStrt_XML10_1E00_1FFF, codepoint & 0x1FF);
91                case 2: if (codepoint > 0x2182) return false;
92                        else return bit_test(NameChar_XML10_2000_21FF, codepoint & 0x1FF);
93                case 3: if (codepoint > 0x312C) return false;
94                        else return bit_test(NameChar_XML10_3000_31FF, codepoint & 0x1FF);
95                case 4: return codepoint >= 0x4E00;
96                case 5: case 6: case 7: case 8: return true;
97                case 9: return codepoint <= 0x9FA5;
98                case 0xA:       return codepoint >= 0xAC00;
99                case 0xB: case 0xC: return true;
100                case 0xD: return codepoint <= 0xD7A3;
101                default: return false;
102        }
103}
104
105inline int XML_10_UTF8_NameStrt_bytes (unsigned char bytes[]) {
106        if (bytes[0] <= 0x7F) {
107                if (bit_test(NameStrt_XML10_0000_11FF, (int) bytes[0])) return 1;
108                else return 0;
109        }
110        else if (bytes[0] <= 0xDF) {
111                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
112                if (bit_test(NameStrt_XML10_0000_11FF, codepoint)) return 2;
113                else return 0;
114        }
115        else if (bytes[0] <= 0xEF) {
116                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
117                return is_XML10_NameStrt_codepoint(codepoint) ? 3 : 0;
118        }
119        else return 0;
120}
121
122inline int XML_10_UTF8_NameChar_bytes (unsigned char bytes[]) {
123        if (bytes[0] <= 0x7F) {
124                if (bit_test(NameChar_XML10_0000_11FF, (int) bytes[0])) return 1;
125                else return 0;
126        }
127        else if (bytes[0] <= 0xDF) {
128                int codepoint = ((bytes[0] & 0x3F) << 6) | (bytes[1] & 0x3F);
129                if (bit_test(NameChar_XML10_0000_11FF, codepoint)) return 2;
130                else return 0;
131        }
132        else if (bytes[0] <= 0xEF) {
133                int codepoint = ((bytes[0] & 0x0F) << 12)| ((bytes[1] & 0x3F) << 6) | (bytes[2] & 0x3F);
134                return is_XML10_NameChar_codepoint(codepoint) ? 3 : 0;
135        }
136        else return 0;
137}
138
139
140static inline int NameStrt_check(int pos) {
141        int block_pos = block_base + pos;
142        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
143              fprintf(stderr, "name start error found at position %i\n",block_pos+buffer_base);
144              exit(-1);
145        }
146        return 0;
147}
148
149static inline int Name_check(int pos) {
150        int block_pos = block_base + pos;
151        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
152              fprintf(stderr, "name error found at position %i\n",block_pos+buffer_base);
153              exit(-1);
154        }
155        return 0;
156}
157
158static inline int Tag_match(int pos) {
159        int block_pos = block_base + pos;
160        if(source[block_pos]=='/' ){
161          tag_depth--;
162          if (tag_depth<0){
163            fprintf(stderr, "tag matching error at position %i\n",block_pos+buffer_base);
164            exit(-1);
165          }       
166        }
167        else if(source[block_pos]=='>')
168          tag_depth--;
169        else 
170          tag_depth++;
171        return 0;
172}
173
174
175#define s2p_step(s0,s1,hi_mask,shift,p0,p1)  \
176{ \
177BitBlock t0,t1; \
178t0= simd_pack_16_hh(s0,s1) ; \
179t1= simd_pack_16_ll(s0,s1) ; \
180p0= simd_if(hi_mask,t0,simd_srli_16(t1,shift) ) ; \
181p1= simd_if(hi_mask,simd_slli_16(t0,shift) ,t1) ; \
182} \
183
184#define s2p_bytepack(s0,s1,s2,s3,s4,s5,s6,s7,p0,p1,p2,p3,p4,p5,p6,p7)  \
185{BitBlock bit00224466_0,bit00224466_1,bit00224466_2,bit00224466_3; \
186BitBlock bit11335577_0,bit11335577_1,bit11335577_2,bit11335577_3; \
187BitBlock bit00004444_0,bit22226666_0,bit00004444_1,bit22226666_1; \
188BitBlock bit11115555_0,bit33337777_0,bit11115555_1,bit33337777_1; \
189s2p_step(s0,s1,simd_himask_2,1,bit00224466_0,bit11335577_0)  \
190s2p_step(s2,s3,simd_himask_2,1,bit00224466_1,bit11335577_1)  \
191s2p_step(s4,s5,simd_himask_2,1,bit00224466_2,bit11335577_2)  \
192s2p_step(s6,s7,simd_himask_2,1,bit00224466_3,bit11335577_3)  \
193s2p_step(bit00224466_0,bit00224466_1,simd_himask_4,2,bit00004444_0,bit22226666_0)  \
194s2p_step(bit00224466_2,bit00224466_3,simd_himask_4,2,bit00004444_1,bit22226666_1)  \
195s2p_step(bit11335577_0,bit11335577_1,simd_himask_4,2,bit11115555_0,bit33337777_0)  \
196s2p_step(bit11335577_2,bit11335577_3,simd_himask_4,2,bit11115555_1,bit33337777_1)  \
197s2p_step(bit00004444_0,bit00004444_1,simd_himask_8,4,p0,p4)  \
198s2p_step(bit11115555_0,bit11115555_1,simd_himask_8,4,p1,p5)  \
199s2p_step(bit22226666_0,bit22226666_1,simd_himask_8,4,p2,p6)  \
200s2p_step(bit33337777_0,bit33337777_1,simd_himask_8,4,p3,p7)  \
201} \
202
203#define p2s_step(p0,p1,hi_mask,shift,s0,s1)  \
204{ \
205BitBlock t0,t1; \
206t0= simd_if(hi_mask,p0,simd_srli_16(p1,shift) ) ; \
207t1= simd_if(hi_mask,simd_slli_16(p0,shift) ,p1) ; \
208s0= simd_mergeh_8(t0,t1) ; \
209s1= simd_mergel_8(t0,t1) ; \
210} \
211
212#define p2s_bytemerge(p0,p1,p2,p3,p4,p5,p6,p7,s0,s1,s2,s3,s4,s5,s6,s7)  \
213{ \
214BitBlock bit00004444_0,bit22226666_0,bit00004444_1,bit22226666_1; \
215BitBlock bit11115555_0,bit33337777_0,bit11115555_1,bit33337777_1; \
216BitBlock bit00224466_0,bit00224466_1,bit00224466_2,bit00224466_3; \
217BitBlock bit11335577_0,bit11335577_1,bit11335577_2,bit11335577_3; \
218p2s_step(p0,p4,simd_himask_8,4,bit00004444_0,bit00004444_1)  \
219p2s_step(p1,p5,simd_himask_8,4,bit11115555_0,bit11115555_1)  \
220p2s_step(p2,p6,simd_himask_8,4,bit22226666_0,bit22226666_1)  \
221p2s_step(p3,p7,simd_himask_8,4,bit33337777_0,bit33337777_1)  \
222p2s_step(bit00004444_0,bit22226666_0,simd_himask_4,2,bit00224466_0,bit00224466_1)  \
223p2s_step(bit11115555_0,bit33337777_0,simd_himask_4,2,bit11335577_0,bit11335577_1)  \
224p2s_step(bit00004444_1,bit22226666_1,simd_himask_4,2,bit00224466_2,bit00224466_3)  \
225p2s_step(bit11115555_1,bit33337777_1,simd_himask_4,2,bit11335577_2,bit11335577_3)  \
226p2s_step(bit00224466_0,bit11335577_0,simd_himask_2,1,s0,s1)  \
227p2s_step(bit00224466_1,bit11335577_1,simd_himask_2,1,s2,s3)  \
228p2s_step(bit00224466_2,bit11335577_2,simd_himask_2,1,s4,s5)  \
229p2s_step(bit00224466_3,bit11335577_3,simd_himask_2,1,s6,s7)  \
230} \
231
232       
233#define BUFFER_SIZE 12800   
234#define BLOCK_SIZE 128
235
236void do_process(FILE *infile, FILE *outfile) {
237
238  @decl
239
240  BytePack U8[8];
241  int buf_pos = 0;
242  int block_pos = 0;
243  int errpos = 0;
244  int chars_avail = 0;
245  int check_pos = 0;
246  char srcbuf[BUFFER_SIZE+BLOCK_SIZE];
247 
248  buffer_base = buf_pos;
249  source = srcbuf;
250 
251  EOF_mask = simd_const_1(1);
252  chars_avail = fread((void *)srcbuf, 1, BUFFER_SIZE, infile);
253
254  Entity_Info * e = new Entity_Info;
255  e->AnalyzeSignature((unsigned char *)srcbuf);
256  XML_Decl_Parser<ASCII> decl_parser((unsigned char *)srcbuf);
257
258  decl_parser.ReadXMLInfo(*e);
259
260  if (e->content_start != 0) {
261        memmove(&srcbuf[0], &srcbuf[e->content_start], chars_avail - e->content_start);
262        if (chars_avail == BUFFER_SIZE) {
263                chars_avail = BUFFER_SIZE - e->content_start + 
264                             fread(&srcbuf[BUFFER_SIZE-e->content_start], 1, e->content_start, infile);
265        }
266        else chars_avail -=e->content_start;
267  }
268 
269  @stream_stmts
270
271  while(chars_avail>0){
272
273    PERF_SEC_START(parser_timer);
274
275    block_pos = 0;
276
277    if(chars_avail < BUFFER_SIZE){
278   
279      while (block_pos < chars_avail){
280
281        int bytes = chars_avail - block_pos;   
282        block_base = block_pos;
283         
284        if(bytes < BLOCK_SIZE){
285          EOF_mask = sisd_srl(simd_const_1(1),sisd_from_int(BLOCK_SIZE-bytes));
286        }
287        BytePack * U8pack = (BytePack *) &srcbuf[block_pos];
288        U8[0] = sisd_load_unaligned(&U8pack[0]);
289        U8[1] = sisd_load_unaligned(&U8pack[1]);
290        U8[2] = sisd_load_unaligned(&U8pack[2]);
291        U8[3] = sisd_load_unaligned(&U8pack[3]);
292        U8[4] = sisd_load_unaligned(&U8pack[4]);
293        U8[5] = sisd_load_unaligned(&U8pack[5]);
294        U8[6] = sisd_load_unaligned(&U8pack[6]);
295        U8[7] = sisd_load_unaligned(&U8pack[7]); 
296       
297        s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
298        array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
299
300        array_bit__0_ = simd_and(array_bit__0_, EOF_mask);
301        array_bit__1_ = simd_and(array_bit__1_, EOF_mask);
302        array_bit__2_ = simd_and(array_bit__2_, EOF_mask);
303        array_bit__3_ = simd_and(array_bit__3_, EOF_mask);
304        array_bit__4_ = simd_and(array_bit__4_, EOF_mask);
305        array_bit__5_ = simd_and(array_bit__5_, EOF_mask);
306        array_bit__6_ = simd_and(array_bit__6_, EOF_mask);
307        array_bit__7_ = simd_and(array_bit__7_, EOF_mask);
308
309        @block_stmts
310
311
312        if (bitblock_has_bit(error_mask)) {
313          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
314          fprintf(stderr, "error found at position %i\n",errpos);
315          exit(-1);
316        }
317       
318        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
319          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
320          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
321        }
322
323        if (bitblock_has_bit(tag_marks)) {
324          StreamScan((ScanBlock *) &tag_marks, sizeof(BitBlock)/sizeof(ScanBlock), Tag_match);
325        }
326       
327        block_pos += BLOCK_SIZE;
328      }
329    }
330    else{
331      while (block_pos < chars_avail){
332       
333        block_base = block_pos;
334         
335        BytePack * U8pack = (BytePack *) &srcbuf[block_pos];
336        U8[0] = sisd_load_unaligned(&U8pack[0]);
337        U8[1] = sisd_load_unaligned(&U8pack[1]);
338        U8[2] = sisd_load_unaligned(&U8pack[2]);
339        U8[3] = sisd_load_unaligned(&U8pack[3]);
340        U8[4] = sisd_load_unaligned(&U8pack[4]);
341        U8[5] = sisd_load_unaligned(&U8pack[5]);
342        U8[6] = sisd_load_unaligned(&U8pack[6]);
343        U8[7] = sisd_load_unaligned(&U8pack[7]); 
344       
345        s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
346        array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
347
348        @block_stmts
349       
350        if (bitblock_has_bit(error_mask)) {
351          errpos = block_pos + buf_pos + count_forward_zeroes(error_mask);
352          fprintf(stderr, "error found at position %i\n",errpos);
353          exit(-1);
354        }
355       
356        if (bitblock_has_bit(simd_or(name_check,name_start_check))) {
357          StreamScan((ScanBlock *) &name_start_check, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
358          StreamScan((ScanBlock *) &name_check, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
359        }
360       
361        if (bitblock_has_bit(tag_marks)) {
362          StreamScan((ScanBlock *) &tag_marks, sizeof(BitBlock)/sizeof(ScanBlock), Tag_match);
363        }
364        block_pos += BLOCK_SIZE;
365      }
366    }
367
368    PERF_SEC_END(parser_timer, chars_avail);
369
370    buf_pos += chars_avail;
371    buffer_base = buf_pos;
372    chars_avail = fread((void *)srcbuf, 1, BUFFER_SIZE, infile);
373    buffer_last = buffer_base + chars_avail;
374  }
375  if(tag_depth!=0){
376    fprintf(stderr, "tag matching error (depth %i) at position %i\n", tag_depth, buffer_last);
377    exit(-1);
378  }       
379   
380}
381
382
383
384int
385main(int argc, char * argv[]) {
386        char * infilename, * outfilename;       
387        FILE *infile, *outfile;
388        struct stat fileinfo;
389
390        if (argc < 2) {
391                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
392                exit(-1);
393        }
394
395        infilename = argv[1];
396        stat(infilename, &fileinfo);
397        infile = fopen(infilename, "rb");
398        if (!infile) {
399                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
400                exit(-1);
401        }
402       
403        if (argc < 3) outfile = stdout;
404        else {
405                outfilename = argv[2];
406                outfile = fopen(outfilename, "wb");
407                if (!outfile) {
408                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
409                        exit(-1);
410                }
411        }
412
413//      PERF_SEC_BIND(1);
414
415        PERF_SEC_INIT(parser_timer);
416
417        do_process(infile, outfile);
418       
419        PERF_SEC_DUMP(parser_timer);
420       
421        PERF_SEC_DESTROY(parser_timer);
422
423        fclose(infile);
424        fclose(outfile);
425        return(0);
426}
Note: See TracBrowser for help on using the repository browser.