source: proto/xmlschema/src/xmlwf_multithreads.cpp @ 2234

Last change on this file since 2234 was 2234, checked in by shiyangy, 7 years ago
File size: 49.5 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 <pthread.h>
7#include "../lib/lib_simd.h"
8#define BLOCK_SIZE 128
9#define SEGMENT_BLOCKS 128
10#define SEGMENT_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
11#define OVERLAP_BUFSIZE 16
12
13#include "../lib/carryQ.h"
14#include "xmldecl.h"
15#include "xml_error.c"
16#include "xmldecl.c"
17#include "namechars.h"
18
19#include "../lib/perflib/perfsec.h"
20#include "../lib/s2p.h"
21
22#include "TagMatcher.h"
23#include "LineColTracker.h"
24BitBlock EOF_mask = simd_const_1(1);
25
26#ifdef BUFFER_PROFILING
27        BOM_Table * parser_timer;
28#endif
29LineColTracker tracker;
30TagMatcher matcher;
31
32int block_base=0;
33int buffer_base=0;
34char * source;
35
36static inline int StreamScan(ScanBlock * stream, int blk_count, int ProcessPos(int)) {
37        int blk;
38        int block_pos = 0;
39
40        for (blk = 0; blk < blk_count; blk++) {
41                ScanBlock s = stream[blk];
42                while(s) {
43                        int code = (ProcessPos(cfzl(s) + block_pos));
44                        if (code) return code;
45                        s = s & (s-1);  // clear rightmost bit.
46                }
47                block_pos += 8 * sizeof(ScanBlock);
48        }
49
50        return 0;
51}
52
53static inline void ReportError(const char * error_msg, int error_pos_in_block) {
54  int error_line, error_column;
55  tracker.get_Line_and_Column(error_pos_in_block, error_line, error_column);
56  fprintf(stderr, "%s at line %i, column %i\n", error_msg, error_line, error_column);
57}
58
59
60static inline int NameStrt_check(int pos) {
61        int block_pos = block_base + pos;
62        if(XML_10_UTF8_NameStrt_bytes((unsigned char*)&source[block_pos]) == 0){
63              ReportError("name start error", pos);
64              exit(-1);
65        }
66        return 0;
67}
68
69static inline int Name_check(int pos) {
70        int block_pos = block_base + pos;
71        if(XML_10_UTF8_NameChar_bytes((unsigned char*)&source[block_pos]) == 0){
72              ReportError("name error", pos);
73              exit(-1);
74        }
75        return 0;
76}
77
78static inline int PIName_check(int pos) {
79        int block_pos = block_base + pos;
80        int file_pos = block_pos+buffer_base;
81        if (at_XxMmLll<ASCII>((unsigned char*)&source[block_pos]) && (source[block_pos+3]=='?' || source[block_pos+3]<= ' ')) {
82              // "<?xml" legal at start of file.
83              if ((file_pos == 2) && at_XmlDecl_start<ASCII>((unsigned char*)&source[0])) return 0;
84              ReportError("[Xx][Mm][Ll] illegal as PI name", pos);
85              exit(-1);
86        }
87        return 0;
88}
89
90static inline int CD_check(int pos) {
91        int block_pos = block_base + pos;
92        if (!at_CDATA1<ASCII>((unsigned char*)&source[block_pos])){
93              ReportError("CDATA error", pos);
94              exit(-1);
95        }
96        return 0;
97}
98
99static inline int GenRef_check(int pos) {
100        int block_pos = block_base + pos;
101        unsigned char* s = (unsigned char*)&source[block_pos];
102        if (!(at_Ref_gt<ASCII>(s)||at_Ref_lt<ASCII>(s)||at_Ref_amp<ASCII>(s)||at_Ref_quot<ASCII>(s)||at_Ref_apos<ASCII>(s))){
103              ReportError("Undefined reference", pos);
104              exit(-1);
105        }
106        return 0;
107}
108
109static inline int HexRef_check(int pos) {
110        int block_pos = block_base + pos;
111        unsigned char* s = (unsigned char*)&source[block_pos];
112        int ch_val = 0;
113        while(at_HexDigit<ASCII>(s)){
114          ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
115          if (ch_val> 0x10FFFF ){
116            ReportError("Illegal character reference", pos);
117            exit(-1);
118          }
119          s++;
120        }
121        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
122          ReportError("Illegal character reference", pos);
123          exit(-1);
124        }
125        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
126          ReportError("Illegal XML 1.0 character reference", pos);
127          exit(-1);
128        }
129        return 0;
130}
131
132static inline int DecRef_check(int pos) {
133        int block_pos = block_base + pos;
134        unsigned char* s = (unsigned char*)&source[block_pos];
135        int ch_val = 0;
136        while(at_HexDigit<ASCII>(s)){
137          ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
138          if (ch_val> 0x10FFFF ){
139            ReportError("Illegal character reference", pos);
140            exit(-1);
141          }
142          s++;
143        }
144        if ((ch_val == 0x0) || ((ch_val | 0x7FF) == 0xDFFF)|| ((ch_val | 0x1) == 0xFFFF)){
145          ReportError("Illegal character reference", pos);
146          exit(-1);
147        }
148        else if (((ch_val < 0x20) && (ch_val != 0x9) && (ch_val != 0xD) && (ch_val != 0xA))){
149          ReportError("Illegal XML 1.0 character reference", pos);
150          exit(-1);
151        }
152        return 0;
153}
154
155static inline int AttRef_check(int pos) {
156        int block_pos = block_base + pos;
157        unsigned char* s = (unsigned char*)&source[block_pos];
158        int ch_val = 0;
159        if(s[0]=='#'){
160          s++;
161          if(s[0]=='x' || s[0]=='X'){
162            s++;
163            while(at_HexDigit<ASCII>(s)){
164              ch_val = HexVal<ASCII>(s[0]) + (ch_val<<4);
165              s++;
166            }
167          }
168          else{
169            while(at_HexDigit<ASCII>(s)){
170              ch_val = DigitVal<ASCII>(s[0]) + ch_val*10;
171              s++;
172            }
173          }
174          if (ch_val==60){
175            ReportError("Attribute values contain '<' characters after reference expansion", pos);
176            exit(-1);
177          }
178        }
179        else if(at_Ref_lt<ASCII>(s)){
180          ReportError("Attribute values contain '<' characters after reference expansion", pos);
181          exit(-1);
182        }
183        return 0;
184}
185
186  struct U8 {
187  BitBlock unibyte;
188  BitBlock prefix;
189  BitBlock prefix2;
190  BitBlock prefix3;
191  BitBlock prefix4;
192  BitBlock suffix;
193  BitBlock badprefix;
194  BitBlock xE0;
195  BitBlock xED;
196  BitBlock xF0;
197  BitBlock xF4;
198  BitBlock xA0_xBF;
199  BitBlock x80_x9F;
200  BitBlock x90_xBF;
201  BitBlock x80_x8F;
202  BitBlock xEF;
203  BitBlock xBF;
204  BitBlock xBE;
205  BitBlock scope22;
206  BitBlock scope32;
207  BitBlock scope33;
208  BitBlock scope42;
209  BitBlock scope43;
210  BitBlock scope44;
211  BitBlock xE0_scope;
212  BitBlock xED_scope;
213  BitBlock xF0_scope;
214  BitBlock xF4_scope;
215  BitBlock xEF_scope;
216  BitBlock FFFE_FFFF;
217  BitBlock error;
218};
219
220  struct Lex {
221  BitBlock CR;
222  BitBlock LF;
223  BitBlock HT;
224  BitBlock SP;
225  BitBlock CRLF;
226  BitBlock RefStart;
227  BitBlock Semicolon;
228  BitBlock Colon;
229  BitBlock LAngle;
230  BitBlock RAngle;
231  BitBlock LBracket;
232  BitBlock RBracket;
233  BitBlock Exclam;
234  BitBlock QMark;
235  BitBlock Hyphen;
236  BitBlock Equals;
237  BitBlock SQuote;
238  BitBlock DQuote;
239  BitBlock Slash;
240  BitBlock Hash;
241  BitBlock x;
242  BitBlock ASCII_name_start;
243  BitBlock ASCII_name_char;
244  BitBlock NameScan;
245  BitBlock Digit;
246  BitBlock Hex;
247  BitBlock WS;
248  BitBlock error;
249};
250
251  struct Scope1 {
252  BitBlock RefStart;
253  BitBlock LAngle;
254  BitBlock Hyphen;
255  BitBlock QMark;
256  BitBlock RBracket;
257};
258
259  struct CtCDPI_Callouts {
260  BitBlock CD_end;
261  BitBlock Ct_starts;
262  BitBlock Ct_ends;
263  BitBlock CD_starts;
264  BitBlock CD_ends;
265  BitBlock PI_starts;
266  BitBlock PI_name_starts;
267  BitBlock PI_name_ends;
268  BitBlock PI_ends;
269  BitBlock CtCDPI_mask;
270  BitBlock error;
271};
272
273  struct Ref_Callouts {
274  BitBlock GenRef_starts;
275  BitBlock GenRef_ends;
276  BitBlock DecRef_starts;
277  BitBlock DecRef_ends;
278  BitBlock HexRef_starts;
279  BitBlock HexRef_ends;
280  BitBlock error;
281};
282
283  struct Tag_Callouts {
284  BitBlock ElemName_starts;
285  BitBlock ElemName_ends;
286  BitBlock AttName_starts;
287  BitBlock AttName_ends;
288  BitBlock AttVal_starts;
289  BitBlock AttVal_ends;
290  BitBlock AttVal_spans;
291  BitBlock EmptyTag_marks;
292  BitBlock EndTag_marks;
293  BitBlock LAngleFollow;
294  BitBlock error;
295};
296
297  struct Basis_bits {
298  BitBlock bit_0;
299  BitBlock bit_1;
300  BitBlock bit_2;
301  BitBlock bit_3;
302  BitBlock bit_4;
303  BitBlock bit_5;
304  BitBlock bit_6;
305  BitBlock bit_7;
306};
307
308  struct Check_streams {
309  BitBlock misc_mask;
310  BitBlock non_ascii_name_starts;
311  BitBlock non_ascii_names;
312  BitBlock tag_marks;
313  BitBlock name_follows;
314  BitBlock att_refs;
315  BitBlock error_mask;
316};
317
318  struct Xml_names {
319  BitBlock namespace_error;
320};
321
322  struct Parse_refs {
323  Parse_refs() { CarryInit(carryQ, 6); }
324  void do_block(Lex & lex, Scope1 & scope1, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts) {
325                BitBlock Ref1, NumRef2, NumRef3, HexRef3, ref_error1, ref_error2, ref_ends;
326                BitBlock ref_error3;
327
328
329        ref_Callouts.GenRef_starts = simd_const_1(0);
330        ref_Callouts.GenRef_ends = simd_const_1(0);
331        ref_Callouts.DecRef_starts = simd_const_1(0);
332        ref_Callouts.DecRef_ends = simd_const_1(0);
333        ref_Callouts.HexRef_starts = simd_const_1(0);
334        ref_Callouts.HexRef_ends = simd_const_1(0);
335        ref_Callouts.error = simd_const_1(0);
336        Ref1 = simd_andc(lex.RefStart, ctCDPI_Callouts.CtCDPI_mask);
337        if ((bitblock_has_bit(Ref1) || CarryTest(carryQ, 0, 6))) {
338          scope1.RefStart = BitBlock_advance_ci_co(Ref1, carryQ, 0);
339          NumRef2 = simd_and(scope1.RefStart, lex.Hash);
340          ref_Callouts.GenRef_starts = simd_andc(scope1.RefStart, lex.Hash);
341          NumRef3 = BitBlock_advance_ci_co(NumRef2, carryQ, 1);
342          HexRef3 = simd_and(NumRef3, lex.x);
343          ref_Callouts.DecRef_starts = simd_andc(NumRef3, lex.x);
344          ref_Callouts.HexRef_starts = BitBlock_advance_ci_co(HexRef3, carryQ, 2);
345          ref_Callouts.GenRef_ends = BitBlock_scanthru_ci_co(ref_Callouts.GenRef_starts, lex.NameScan, carryQ, 3);
346          ref_Callouts.DecRef_ends = BitBlock_scanthru_ci_co(ref_Callouts.DecRef_starts, lex.Digit, carryQ, 4);
347          ref_Callouts.HexRef_ends = BitBlock_scanthru_ci_co(ref_Callouts.HexRef_starts, lex.Hex, carryQ, 5);
348          ref_error1 = simd_andc(ref_Callouts.DecRef_starts, lex.Digit);
349          ref_error2 = simd_andc(ref_Callouts.HexRef_starts, lex.Hex);
350          ref_ends = simd_or(simd_or(ref_Callouts.GenRef_ends, ref_Callouts.DecRef_ends), ref_Callouts.HexRef_ends);
351          ref_error3 = simd_andc(ref_ends, lex.Semicolon);
352          ref_Callouts.error = simd_or(simd_or(ref_error1, ref_error2), ref_error3);
353        }
354        else {
355          CarryDequeueEnqueue(carryQ, 0, 6);
356        }
357        CarryQ_Adjust(carryQ, 6);
358  }
359  void do_segment(Lex lex[], Scope1 scope1[], CtCDPI_Callouts ctCDPI_Callouts[], Ref_Callouts ref_Callouts[]) {
360  for (int i = 0; i < SEGMENT_BLOCKS; i++)
361    do_block(lex[i], scope1[i], ctCDPI_Callouts[i], ref_Callouts[i]);
362  }
363  CarryDeclare(carryQ, 6);
364  };
365
366  struct Parse_tags {
367  Parse_tags() { CarryInit(carryQ, 13); }
368  void do_block(Lex & lex, Scope1 & scope1, CtCDPI_Callouts & ctCDPI_Callouts, Tag_Callouts & tag_Callouts) {
369                BitBlock DQuoteDelim, SQuoteDelim, AttListDelim, ParseError, EqToCheck;
370                BitBlock AttValEnds, AfterWS, AttListEnd, AttNameStart, AttNameFollow;
371                BitBlock EqExpected, AttValPos, DQuoteAttVal, SQuoteAttVal, DQuoteAttEnd;
372                BitBlock SQuoteAttEnd, AttValEnd, AttValFollow, STagEnds, EndTagEnds;
373
374
375        DQuoteDelim = simd_or(lex.DQuote, lex.LAngle);
376        SQuoteDelim = simd_or(lex.SQuote, lex.LAngle);
377        AttListDelim = simd_or(lex.Slash, lex.RAngle);
378        tag_Callouts.LAngleFollow = simd_andc(scope1.LAngle, ctCDPI_Callouts.CtCDPI_mask);
379        tag_Callouts.ElemName_starts = simd_andc(tag_Callouts.LAngleFollow, lex.Slash);
380        tag_Callouts.EndTag_marks = simd_and(tag_Callouts.LAngleFollow, lex.Slash);
381        tag_Callouts.ElemName_ends = BitBlock_scanthru_ci_co(tag_Callouts.ElemName_starts, lex.NameScan, carryQ, 0);
382        ParseError = simd_and(tag_Callouts.ElemName_starts, tag_Callouts.ElemName_ends);
383        tag_Callouts.AttName_starts = simd_const_1(0);
384        tag_Callouts.AttName_ends = simd_const_1(0);
385        EqToCheck = simd_const_1(0);
386        tag_Callouts.AttVal_starts = simd_const_1(0);
387        AttValEnds = simd_const_1(0);
388        tag_Callouts.AttVal_ends = simd_const_1(0);
389        AfterWS = BitBlock_scanthru_ci_co(tag_Callouts.ElemName_ends, lex.WS, carryQ, 1);
390        AttListEnd = simd_and(AfterWS, AttListDelim);
391        AttNameStart = simd_andc(AfterWS, AttListDelim);
392        ParseError = simd_or(ParseError, simd_and(tag_Callouts.ElemName_ends, AttNameStart));
393        if ((bitblock_has_bit(AttNameStart) || CarryTest(carryQ, 2, 7))) {
394          tag_Callouts.AttName_starts = simd_or(tag_Callouts.AttName_starts, AttNameStart);
395          AttNameFollow = BitBlock_scanthru_ci_co(AttNameStart, lex.NameScan, carryQ, 2);
396          tag_Callouts.AttName_ends = simd_or(tag_Callouts.AttName_ends, AttNameFollow);
397          EqExpected = BitBlock_scanthru_ci_co(AttNameFollow, lex.WS, carryQ, 3);
398          EqToCheck = simd_or(EqToCheck, EqExpected);
399          AttValPos = BitBlock_scanthru_ci_co(EqExpected, simd_or(EqExpected, lex.WS), carryQ, 4);
400          tag_Callouts.AttVal_starts = simd_or(tag_Callouts.AttVal_starts, AttValPos);
401          DQuoteAttVal = simd_and(AttValPos, lex.DQuote);
402          SQuoteAttVal = simd_and(AttValPos, lex.SQuote);
403          DQuoteAttEnd = BitBlock_scanto_ci_co(DQuoteAttVal, simd_andc(DQuoteDelim, DQuoteAttVal), carryQ, 5);
404          SQuoteAttEnd = BitBlock_scanto_ci_co(SQuoteAttVal, simd_andc(SQuoteDelim, SQuoteAttVal), carryQ, 6);
405          AttValEnd = simd_or(DQuoteAttEnd, SQuoteAttEnd);
406          AttValEnds = simd_or(AttValEnds, AttValEnd);
407          AttValFollow = BitBlock_advance_ci_co(AttValEnd, carryQ, 7);
408          tag_Callouts.AttVal_ends = simd_or(tag_Callouts.AttVal_ends, AttValFollow);
409          AfterWS = BitBlock_scanthru_ci_co(AttValFollow, lex.WS, carryQ, 8);
410          AttListEnd = simd_or(AttListEnd, simd_and(AfterWS, AttListDelim));
411          AttNameStart = simd_andc(AfterWS, AttListDelim);
412          while (bitblock_has_bit(AttNameStart)) {
413            CarryDeclare(subcarryQ, 7);
414            CarryInit(subcarryQ, 7);
415            tag_Callouts.AttName_starts = simd_or(tag_Callouts.AttName_starts, AttNameStart);
416            AttNameFollow = BitBlock_scanthru_co(AttNameStart, lex.NameScan, subcarryQ, 0);
417            tag_Callouts.AttName_ends = simd_or(tag_Callouts.AttName_ends, AttNameFollow);
418            EqExpected = BitBlock_scanthru_co(AttNameFollow, lex.WS, subcarryQ, 1);
419            EqToCheck = simd_or(EqToCheck, EqExpected);
420            AttValPos = BitBlock_scanthru_co(EqExpected, simd_or(EqExpected, lex.WS), subcarryQ, 2);
421            tag_Callouts.AttVal_starts = simd_or(tag_Callouts.AttVal_starts, AttValPos);
422            DQuoteAttVal = simd_and(AttValPos, lex.DQuote);
423            SQuoteAttVal = simd_and(AttValPos, lex.SQuote);
424            DQuoteAttEnd = BitBlock_scanto_co(DQuoteAttVal, simd_andc(DQuoteDelim, DQuoteAttVal), subcarryQ, 3);
425            SQuoteAttEnd = BitBlock_scanto_co(SQuoteAttVal, simd_andc(SQuoteDelim, SQuoteAttVal), subcarryQ, 4);
426            AttValEnd = simd_or(DQuoteAttEnd, SQuoteAttEnd);
427            AttValEnds = simd_or(AttValEnds, AttValEnd);
428            AttValFollow = BitBlock_advance_co(AttValEnd, subcarryQ, 5);
429            tag_Callouts.AttVal_ends = simd_or(tag_Callouts.AttVal_ends, AttValFollow);
430            AfterWS = BitBlock_scanthru_co(AttValFollow, lex.WS, subcarryQ, 6);
431            AttListEnd = simd_or(AttListEnd, simd_and(AfterWS, AttListDelim));
432            AttNameStart = simd_andc(AfterWS, AttListDelim);
433            CarryCombine(carryQ, subcarryQ, 2, 7);
434          }
435        }
436        else {
437          CarryDequeueEnqueue(carryQ, 2, 7);
438        }
439        STagEnds = simd_and(AttListEnd, lex.RAngle);
440        tag_Callouts.EmptyTag_marks = BitBlock_advance_ci_co(simd_and(AttListEnd, lex.Slash), carryQ, 9);
441        ParseError = simd_or(ParseError, simd_and(tag_Callouts.AttVal_ends, tag_Callouts.AttName_starts));
442        ParseError = simd_or(ParseError, simd_and(tag_Callouts.AttName_starts, tag_Callouts.AttName_ends));
443        ParseError = simd_or(ParseError, simd_andc(EqToCheck, lex.Equals));
444        ParseError = simd_or(ParseError, simd_andc(tag_Callouts.AttVal_starts, simd_or(lex.DQuote, lex.SQuote)));
445        ParseError = simd_or(ParseError, simd_andc(AttValEnds, simd_or(lex.DQuote, lex.SQuote)));
446        ParseError = simd_or(ParseError, simd_andc(tag_Callouts.EmptyTag_marks, lex.RAngle));
447        EndTagEnds = BitBlock_scanthru_ci_co(BitBlock_scanthru_ci_co(tag_Callouts.EndTag_marks, simd_or(tag_Callouts.EndTag_marks, lex.NameScan), carryQ, 10), lex.WS, carryQ, 11);
448        ParseError = simd_or(ParseError, simd_andc(EndTagEnds, lex.RAngle));
449        tag_Callouts.error = ParseError;
450        tag_Callouts.AttVal_spans = BitBlock_sub_ci_co(tag_Callouts.AttVal_ends, tag_Callouts.AttVal_starts, carryQ, 12);
451        CarryQ_Adjust(carryQ, 13);
452  }
453  void do_segment(Lex lex[], Scope1 scope1[], CtCDPI_Callouts ctCDPI_Callouts[], Tag_Callouts tag_Callouts[]) {
454  for (int i = 0; i < SEGMENT_BLOCKS; i++)
455    do_block(lex[i], scope1[i], ctCDPI_Callouts[i], tag_Callouts[i]);
456  }
457  CarryDeclare(carryQ, 13);
458  };
459
460  struct Classify_bytes_Validate_utf8 {
461  Classify_bytes_Validate_utf8() { CarryInit(carryQ, 12); }
462  void do_block(Basis_bits & basis_bits, Lex & lex, U8 & u8) {
463                BitBlock temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10;
464                BitBlock temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
465                BitBlock temp19, temp20, temp21, temp22, temp23, temp24, temp25, temp26;
466                BitBlock temp27, temp28, temp29, temp30, temp31, temp32, temp33, temp34;
467                BitBlock temp35, temp36, temp37, temp38, temp39, temp40, temp41, temp42;
468                BitBlock temp43, temp44, temp45, temp46, temp47, temp48, x00_x1F, temp49;
469                BitBlock temp50, temp51, temp52, temp53, temp54, temp55, temp56, temp57;
470                BitBlock temp58, temp59, temp60, temp61, temp62, temp63, temp64, temp65;
471                BitBlock u8anyscope, temp66, temp67, temp68, temp69, temp70, temp71, xE0, xED;
472                BitBlock xF0, temp72, xF4, xEF, temp73, u8lastscope, u8error1, u8error2;
473                BitBlock u8error3, u8error4, EF_BF_pending, u8mismatch;
474
475
476        temp1 = simd_or(basis_bits.bit_0, basis_bits.bit_1);
477        temp2 = simd_andc(basis_bits.bit_2, basis_bits.bit_3);
478        temp3 = simd_andc(temp2, temp1);
479        temp4 = simd_andc(basis_bits.bit_5, basis_bits.bit_4);
480        temp5 = simd_andc(basis_bits.bit_6, basis_bits.bit_7);
481        temp6 = simd_and(temp4, temp5);
482        lex.RefStart = simd_and(temp3, temp6);
483        temp7 = simd_and(basis_bits.bit_2, basis_bits.bit_3);
484        temp8 = simd_andc(temp7, temp1);
485        temp9 = simd_andc(basis_bits.bit_4, basis_bits.bit_5);
486        temp10 = simd_and(basis_bits.bit_6, basis_bits.bit_7);
487        temp11 = simd_and(temp9, temp10);
488        lex.Semicolon = simd_and(temp8, temp11);
489        temp12 = simd_and(basis_bits.bit_4, basis_bits.bit_5);
490        temp13 = simd_or(basis_bits.bit_6, basis_bits.bit_7);
491        temp14 = simd_andc(temp12, temp13);
492        lex.LAngle = simd_and(temp8, temp14);
493        temp15 = simd_and(temp12, temp5);
494        lex.RAngle = simd_and(temp8, temp15);
495        temp16 = simd_andc(basis_bits.bit_1, basis_bits.bit_0);
496        temp17 = simd_andc(basis_bits.bit_3, basis_bits.bit_2);
497        temp18 = simd_and(temp16, temp17);
498        lex.LBracket = simd_and(temp18, temp11);
499        temp19 = simd_andc(basis_bits.bit_7, basis_bits.bit_6);
500        temp20 = simd_and(temp12, temp19);
501        lex.RBracket = simd_and(temp18, temp20);
502        temp21 = simd_or(basis_bits.bit_4, basis_bits.bit_5);
503        temp22 = simd_andc(temp19, temp21);
504        lex.Exclam = simd_and(temp3, temp22);
505        temp23 = simd_and(temp12, temp10);
506        lex.QMark = simd_and(temp8, temp23);
507        lex.Hyphen = simd_and(temp3, temp20);
508        lex.Equals = simd_and(temp8, temp20);
509        temp24 = simd_and(temp4, temp10);
510        lex.SQuote = simd_and(temp3, temp24);
511        temp25 = simd_andc(temp5, temp21);
512        lex.DQuote = simd_and(temp3, temp25);
513        lex.Slash = simd_and(temp3, temp23);
514        temp26 = simd_andc(temp10, temp21);
515        lex.Hash = simd_and(temp3, temp26);
516        temp27 = simd_and(temp16, temp7);
517        temp28 = simd_andc(temp9, temp13);
518        lex.x = simd_and(temp27, temp28);
519        temp29 = simd_and(temp9, temp5);
520        lex.Colon = simd_and(temp8, temp29);
521        temp30 = simd_and(temp18, temp23);
522        temp31 = simd_or(temp30, lex.Colon);
523        temp32 = simd_andc(temp16, basis_bits.bit_2);
524        temp33 = simd_or(basis_bits.bit_5, temp10);
525        temp34 = simd_and(basis_bits.bit_4, temp33);
526        temp35 = simd_not(temp34);
527        temp36 = simd_or(temp21, temp13);
528        temp37 = simd_or(simd_and(basis_bits.bit_3, temp35), simd_andc(temp36, basis_bits.bit_3));
529        temp38 = simd_and(temp32, temp37);
530        temp39 = simd_or(temp31, temp38);
531        temp40 = simd_and(temp16, basis_bits.bit_2);
532        temp41 = simd_and(temp40, temp37);
533        lex.ASCII_name_start = simd_or(temp39, temp41);
534        temp42 = simd_or(temp30, lex.Hyphen);
535        temp43 = simd_and(temp3, temp15);
536        temp44 = simd_or(temp42, temp43);
537        temp45 = simd_andc(temp8, temp34);
538        temp46 = simd_or(temp44, temp45);
539        temp47 = simd_or(temp46, temp38);
540        lex.ASCII_name_char = simd_or(temp47, temp41);
541        lex.NameScan = simd_or(lex.ASCII_name_char, basis_bits.bit_0);
542        temp48 = simd_or(temp1, basis_bits.bit_2);
543        x00_x1F = simd_not(temp48);
544        temp49 = simd_or(basis_bits.bit_2, basis_bits.bit_3);
545        temp50 = simd_or(temp1, temp49);
546        lex.CR = simd_andc(temp20, temp50);
547        lex.LF = simd_andc(temp29, temp50);
548        temp51 = simd_and(temp9, temp19);
549        lex.HT = simd_andc(temp51, temp50);
550        lex.SP = simd_andc(temp3, temp36);
551        temp52 = simd_or(temp20, temp29);
552        temp53 = simd_or(temp52, temp51);
553        temp54 = simd_andc(temp53, temp50);
554        lex.WS = simd_or(temp54, lex.SP);
555        temp55 = simd_or(basis_bits.bit_5, basis_bits.bit_6);
556        temp56 = simd_and(basis_bits.bit_4, temp55);
557        lex.Digit = simd_andc(temp8, temp56);
558        temp57 = simd_andc(temp16, temp49);
559        temp58 = simd_andc(temp57, basis_bits.bit_4);
560        temp59 = simd_not(temp10);
561        temp60 = simd_or(simd_and(basis_bits.bit_5, temp59), simd_andc(temp13, basis_bits.bit_5));
562        temp61 = simd_and(temp58, temp60);
563        temp62 = simd_or(lex.Digit, temp61);
564        temp63 = simd_and(temp16, temp2);
565        temp64 = simd_andc(temp63, basis_bits.bit_4);
566        temp65 = simd_and(temp64, temp60);
567        lex.Hex = simd_or(temp62, temp65);
568        lex.error = simd_andc(x00_x1F, lex.WS);
569        u8.unibyte = simd_not(basis_bits.bit_0);
570        u8.suffix = simd_const_1(0);
571        u8.error = simd_const_1(0);
572        u8.FFFE_FFFF = simd_const_1(0);
573        u8anyscope = simd_const_1(0);
574        if ((bitblock_has_bit(basis_bits.bit_0) || CarryTest(carryQ, 0, 12))) {
575          u8.prefix = simd_and(basis_bits.bit_0, basis_bits.bit_1);
576          u8.prefix2 = simd_andc(u8.prefix, basis_bits.bit_2);
577          u8.prefix3 = simd_and(u8.prefix, temp2);
578          u8.prefix4 = simd_and(u8.prefix, temp7);
579          u8.suffix = simd_andc(basis_bits.bit_0, basis_bits.bit_1);
580          temp66 = simd_andc(u8.prefix, temp49);
581          temp67 = simd_or(temp21, basis_bits.bit_6);
582          temp68 = simd_andc(temp66, temp67);
583          temp69 = simd_and(basis_bits.bit_5, temp13);
584          temp70 = simd_or(basis_bits.bit_4, temp69);
585          temp71 = simd_and(u8.prefix4, temp70);
586          u8.badprefix = simd_or(temp68, temp71);
587          u8.error = u8.badprefix;
588          u8.scope22 = BitBlock_advance_ci_co(u8.prefix2, carryQ, 0);
589          u8anyscope = u8.scope22;
590          if ((bitblock_has_bit(simd_or(u8.prefix3, u8.prefix4)) || CarryTest(carryQ, 1, 11))) {
591            xE0 = simd_andc(u8.prefix3, temp36);
592            xED = simd_and(u8.prefix3, temp20);
593            xF0 = simd_andc(u8.prefix4, temp36);
594            temp72 = simd_andc(temp4, temp13);
595            xF4 = simd_and(u8.prefix4, temp72);
596            u8.xA0_xBF = simd_and(u8.suffix, basis_bits.bit_2);
597            u8.x80_x9F = simd_andc(u8.suffix, basis_bits.bit_2);
598            u8.x90_xBF = simd_and(u8.suffix, temp49);
599            u8.x80_x8F = simd_andc(u8.suffix, temp49);
600            xEF = simd_and(u8.prefix3, temp23);
601            temp73 = simd_and(u8.suffix, temp7);
602            u8.xBF = simd_and(temp73, temp23);
603            u8.xBE = simd_and(temp73, temp15);
604            u8.xE0_scope = BitBlock_advance_ci_co(xE0, carryQ, 1);
605            u8.xED_scope = BitBlock_advance_ci_co(xED, carryQ, 2);
606            u8.xF0_scope = BitBlock_advance_ci_co(xF0, carryQ, 3);
607            u8.xF4_scope = BitBlock_advance_ci_co(xF4, carryQ, 4);
608            u8.xEF_scope = BitBlock_advance_ci_co(xEF, carryQ, 5);
609            u8.scope32 = BitBlock_advance_ci_co(u8.prefix3, carryQ, 6);
610            u8.scope33 = BitBlock_advance_ci_co(u8.scope32, carryQ, 7);
611            u8.scope42 = BitBlock_advance_ci_co(u8.prefix4, carryQ, 8);
612            u8.scope43 = BitBlock_advance_ci_co(u8.scope42, carryQ, 9);
613            u8.scope44 = BitBlock_advance_ci_co(u8.scope43, carryQ, 10);
614            u8lastscope = simd_or(simd_or(u8.scope22, u8.scope33), u8.scope44);
615            u8anyscope = simd_or(simd_or(simd_or(u8lastscope, u8.scope32), u8.scope42), u8.scope43);
616            u8error1 = simd_and(u8.xE0_scope, u8.x80_x9F);
617            u8error2 = simd_and(u8.xED_scope, u8.xA0_xBF);
618            u8error3 = simd_and(u8.xF0_scope, u8.x80_x8F);
619            u8error4 = simd_and(u8.xF4_scope, u8.x90_xBF);
620            u8.error = simd_or(u8.error, simd_or(simd_or(simd_or(u8error1, u8error2), u8error3), u8error4));
621            EF_BF_pending = BitBlock_advance_ci_co(simd_and(u8.xEF_scope, u8.xBF), carryQ, 11);
622            u8.FFFE_FFFF = simd_and(EF_BF_pending, simd_or(u8.xBE, u8.xBF));
623          }
624          else {
625            CarryDequeueEnqueue(carryQ, 1, 11);
626          }
627        }
628        else {
629          CarryDequeueEnqueue(carryQ, 0, 12);
630        }
631        u8mismatch = simd_xor(u8anyscope, u8.suffix);
632        u8.error = simd_or(u8.error, u8mismatch);
633        CarryQ_Adjust(carryQ, 12);
634  }
635  void do_segment(Basis_bits basis_bits[], Lex lex[], U8 u8[]) {
636  for (int i = 0; i < SEGMENT_BLOCKS; i++)
637    do_block(basis_bits[i], lex[i], u8[i]);
638  }
639  CarryDeclare(carryQ, 12);
640  };
641
642  struct Parse_CtCDPI {
643  Parse_CtCDPI() { CarryInit(carryQ, 19); }
644  void do_block(CtCDPI_Callouts & ctCDPI_Callouts, Lex & lex, Scope1 & scope1, Check_streams & check_streams) {
645                BitBlock CtCDPI_starts, Ct_errors, PI_start, CtCD_start, CtCDPI_start;
646                BitBlock DoubleHyphen, PI_end, CtCDPI_Cursor, PI_Cursor, CD_Ct_Cursor;
647                BitBlock CD_Cursor, Ct_Cursor, PI_name_end;
648
649  CtCDPI_Cursor = sisd_from_int(1);
650
651        ctCDPI_Callouts.CD_end = simd_const_1(0);
652        ctCDPI_Callouts.Ct_starts = simd_const_1(0);
653        ctCDPI_Callouts.Ct_ends = simd_const_1(0);
654        ctCDPI_Callouts.CD_starts = simd_const_1(0);
655        ctCDPI_Callouts.CD_ends = simd_const_1(0);
656        ctCDPI_Callouts.PI_starts = simd_const_1(0);
657        ctCDPI_Callouts.PI_name_starts = simd_const_1(0);
658        ctCDPI_Callouts.PI_name_ends = simd_const_1(0);
659        ctCDPI_Callouts.PI_ends = simd_const_1(0);
660        ctCDPI_Callouts.CtCDPI_mask = simd_const_1(0);
661        ctCDPI_Callouts.error = simd_const_1(0);
662        CtCDPI_starts = simd_const_1(0);
663        Ct_errors = simd_const_1(0);
664        if ((bitblock_has_bit(lex.RBracket) || CarryTest(carryQ, 0, 2))) {
665          scope1.RBracket = BitBlock_advance_ci_co(lex.RBracket, carryQ, 0);
666          ctCDPI_Callouts.CD_end = simd_and(BitBlock_advance_ci_co(simd_and(scope1.RBracket, lex.RBracket), carryQ, 1), lex.RAngle);
667        }
668        else {
669          CarryDequeueEnqueue(carryQ, 0, 2);
670        }
671        PI_start = simd_and(scope1.LAngle, lex.QMark);
672        CtCD_start = simd_and(scope1.LAngle, lex.Exclam);
673        CtCDPI_start = simd_or(PI_start, CtCD_start);
674        DoubleHyphen = simd_and(scope1.Hyphen, lex.Hyphen);
675        PI_end = simd_and(scope1.QMark, lex.RAngle);
676        CtCDPI_Cursor = BitBlock_scanto_ci_co(CtCDPI_Cursor, CtCDPI_start, carryQ, 2);
677        CtCDPI_Cursor = simd_and(CtCDPI_Cursor, EOF_mask);
678        if ((bitblock_has_bit(CtCDPI_Cursor) || CarryTest(carryQ, 3, 14))) {
679          CtCDPI_starts = simd_or(CtCDPI_starts, CtCDPI_Cursor);
680          PI_Cursor = simd_and(CtCDPI_Cursor, PI_start);
681          CD_Ct_Cursor = BitBlock_advance_ci_co(simd_andc(CtCDPI_Cursor, PI_Cursor), carryQ, 3);
682          CD_Cursor = simd_and(CD_Ct_Cursor, lex.LBracket);
683          Ct_Cursor = simd_and(CD_Ct_Cursor, lex.Hyphen);
684          ctCDPI_Callouts.PI_starts = simd_or(ctCDPI_Callouts.PI_starts, PI_Cursor);
685          ctCDPI_Callouts.CD_starts = simd_or(ctCDPI_Callouts.CD_starts, CD_Cursor);
686          ctCDPI_Callouts.Ct_starts = simd_or(ctCDPI_Callouts.Ct_starts, Ct_Cursor);
687          Ct_Cursor = BitBlock_advance_ci_co(Ct_Cursor, carryQ, 4);
688          Ct_errors = simd_or(Ct_errors, simd_andc(Ct_Cursor, lex.Hyphen));
689          Ct_Cursor = BitBlock_advance_ci_co(BitBlock_advance_ci_co(Ct_Cursor, carryQ, 5), carryQ, 6);
690          PI_Cursor = BitBlock_advance_ci_co(PI_Cursor, carryQ, 7);
691          ctCDPI_Callouts.PI_name_starts = simd_or(ctCDPI_Callouts.PI_name_starts, PI_Cursor);
692          PI_name_end = BitBlock_scanthru_ci_co(PI_Cursor, lex.NameScan, carryQ, 8);
693          ctCDPI_Callouts.PI_name_ends = simd_or(ctCDPI_Callouts.PI_name_ends, PI_name_end);
694          PI_Cursor = BitBlock_scanto_ci_co(PI_name_end, PI_end, carryQ, 9);
695          CD_Cursor = BitBlock_scanto_ci_co(CD_Cursor, ctCDPI_Callouts.CD_end, carryQ, 10);
696          Ct_Cursor = BitBlock_advance_ci_co(BitBlock_scanto_ci_co(Ct_Cursor, DoubleHyphen, carryQ, 11), carryQ, 12);
697          ctCDPI_Callouts.PI_ends = simd_or(ctCDPI_Callouts.PI_ends, PI_Cursor);
698          ctCDPI_Callouts.CD_ends = simd_or(ctCDPI_Callouts.CD_ends, CD_Cursor);
699          ctCDPI_Callouts.Ct_ends = simd_or(ctCDPI_Callouts.Ct_ends, Ct_Cursor);
700          CtCDPI_Cursor = simd_or(simd_or(PI_Cursor, CD_Cursor), Ct_Cursor);
701          CtCDPI_Cursor = BitBlock_scanto_ci_co(CtCDPI_Cursor, CtCDPI_start, carryQ, 13);
702          CtCDPI_Cursor = simd_and(CtCDPI_Cursor, EOF_mask);
703          ctCDPI_Callouts.CtCDPI_mask = BitBlock_sub_ci_co(BitBlock_advance_ci_co(simd_or(simd_or(ctCDPI_Callouts.CD_ends, ctCDPI_Callouts.Ct_ends), ctCDPI_Callouts.PI_ends), carryQ, 14), CtCDPI_starts, carryQ, 15);
704          ctCDPI_Callouts.error = simd_or(Ct_errors, simd_andc(ctCDPI_Callouts.Ct_ends, lex.RAngle));
705          ctCDPI_Callouts.error = simd_or(ctCDPI_Callouts.error, simd_andc(BitBlock_advance_ci_co(simd_andc(ctCDPI_Callouts.PI_name_ends, lex.WS), carryQ, 16), PI_end));
706          ctCDPI_Callouts.error = simd_or(ctCDPI_Callouts.error, simd_and(ctCDPI_Callouts.PI_name_starts, ctCDPI_Callouts.PI_name_ends));
707          ctCDPI_Callouts.error = simd_or(ctCDPI_Callouts.error, simd_andc(ctCDPI_Callouts.CtCDPI_mask, EOF_mask));
708          while (bitblock_has_bit(CtCDPI_Cursor)) {
709            CarryDeclare(subcarryQ, 14);
710            CarryInit(subcarryQ, 14);
711            CtCDPI_starts = simd_or(CtCDPI_starts, CtCDPI_Cursor);
712            PI_Cursor = simd_and(CtCDPI_Cursor, PI_start);
713            CD_Ct_Cursor = BitBlock_advance_co(simd_andc(CtCDPI_Cursor, PI_Cursor), subcarryQ, 0);
714            CD_Cursor = simd_and(CD_Ct_Cursor, lex.LBracket);
715            Ct_Cursor = simd_and(CD_Ct_Cursor, lex.Hyphen);
716            ctCDPI_Callouts.PI_starts = simd_or(ctCDPI_Callouts.PI_starts, PI_Cursor);
717            ctCDPI_Callouts.CD_starts = simd_or(ctCDPI_Callouts.CD_starts, CD_Cursor);
718            ctCDPI_Callouts.Ct_starts = simd_or(ctCDPI_Callouts.Ct_starts, Ct_Cursor);
719            Ct_Cursor = BitBlock_advance_co(Ct_Cursor, subcarryQ, 1);
720            Ct_errors = simd_or(Ct_errors, simd_andc(Ct_Cursor, lex.Hyphen));
721            Ct_Cursor = BitBlock_advance_co(BitBlock_advance_co(Ct_Cursor, subcarryQ, 2), subcarryQ, 3);
722            PI_Cursor = BitBlock_advance_co(PI_Cursor, subcarryQ, 4);
723            ctCDPI_Callouts.PI_name_starts = simd_or(ctCDPI_Callouts.PI_name_starts, PI_Cursor);
724            PI_name_end = BitBlock_scanthru_co(PI_Cursor, lex.NameScan, subcarryQ, 5);
725            ctCDPI_Callouts.PI_name_ends = simd_or(ctCDPI_Callouts.PI_name_ends, PI_name_end);
726            PI_Cursor = BitBlock_scanto_co(PI_name_end, PI_end, subcarryQ, 6);
727            CD_Cursor = BitBlock_scanto_co(CD_Cursor, ctCDPI_Callouts.CD_end, subcarryQ, 7);
728            Ct_Cursor = BitBlock_advance_co(BitBlock_scanto_co(Ct_Cursor, DoubleHyphen, subcarryQ, 8), subcarryQ, 9);
729            ctCDPI_Callouts.PI_ends = simd_or(ctCDPI_Callouts.PI_ends, PI_Cursor);
730            ctCDPI_Callouts.CD_ends = simd_or(ctCDPI_Callouts.CD_ends, CD_Cursor);
731            ctCDPI_Callouts.Ct_ends = simd_or(ctCDPI_Callouts.Ct_ends, Ct_Cursor);
732            CtCDPI_Cursor = simd_or(simd_or(PI_Cursor, CD_Cursor), Ct_Cursor);
733            CtCDPI_Cursor = BitBlock_scanto_co(CtCDPI_Cursor, CtCDPI_start, subcarryQ, 10);
734            CtCDPI_Cursor = simd_and(CtCDPI_Cursor, EOF_mask);
735            ctCDPI_Callouts.CtCDPI_mask = BitBlock_sub_co(BitBlock_advance_co(simd_or(simd_or(ctCDPI_Callouts.CD_ends, ctCDPI_Callouts.Ct_ends), ctCDPI_Callouts.PI_ends), subcarryQ, 11), CtCDPI_starts, subcarryQ, 12);
736            ctCDPI_Callouts.error = simd_or(Ct_errors, simd_andc(ctCDPI_Callouts.Ct_ends, lex.RAngle));
737            ctCDPI_Callouts.error = simd_or(ctCDPI_Callouts.error, simd_andc(BitBlock_advance_co(simd_andc(ctCDPI_Callouts.PI_name_ends, lex.WS), subcarryQ, 13), PI_end));
738            ctCDPI_Callouts.error = simd_or(ctCDPI_Callouts.error, simd_and(ctCDPI_Callouts.PI_name_starts, ctCDPI_Callouts.PI_name_ends));
739            ctCDPI_Callouts.error = simd_or(ctCDPI_Callouts.error, simd_andc(ctCDPI_Callouts.CtCDPI_mask, EOF_mask));
740            CarryCombine(carryQ, subcarryQ, 3, 14);
741          }
742        }
743        else {
744          CarryDequeueEnqueue(carryQ, 3, 14);
745        }
746        check_streams.misc_mask = simd_and(simd_or(simd_or(simd_or(lex.WS, lex.LAngle), BitBlock_sub_ci_co(BitBlock_advance_ci_co(simd_or(ctCDPI_Callouts.Ct_ends, ctCDPI_Callouts.PI_ends), carryQ, 17), simd_or(ctCDPI_Callouts.Ct_starts, ctCDPI_Callouts.PI_starts), carryQ, 18)), CtCDPI_starts), EOF_mask);
747        CarryQ_Adjust(carryQ, 19);
748  }
749  void do_segment(CtCDPI_Callouts ctCDPI_Callouts[], Lex lex[], Scope1 scope1[], Check_streams check_streams[]) {
750  for (int i = 0; i < SEGMENT_BLOCKS; i++)
751    do_block(ctCDPI_Callouts[i], lex[i], scope1[i], check_streams[i]);
752  }
753  CarryDeclare(carryQ, 19);
754  };
755
756  struct Do_check_streams {
757
758  void do_block(CtCDPI_Callouts & ctCDPI_Callouts, Tag_Callouts & tag_Callouts, Lex & lex, U8 & u8, Scope1 & scope1, Ref_Callouts & ref_Callouts, Xml_names & xml_names, Check_streams & check_streams) {
759                BitBlock CD_end_error;
760
761
762        CD_end_error = simd_andc(ctCDPI_Callouts.CD_end, simd_or(ctCDPI_Callouts.CtCDPI_mask, tag_Callouts.AttVal_spans));
763        check_streams.error_mask = simd_or(simd_or(simd_or(simd_or(simd_or(simd_or(simd_or(simd_and(lex.error, EOF_mask), u8.error), u8.FFFE_FFFF), ctCDPI_Callouts.error), tag_Callouts.error), CD_end_error), ref_Callouts.error), xml_names.namespace_error);
764        check_streams.tag_marks = simd_or(simd_or(tag_Callouts.EmptyTag_marks, tag_Callouts.LAngleFollow), tag_Callouts.AttName_starts);
765        check_streams.name_follows = simd_or(tag_Callouts.ElemName_ends, tag_Callouts.AttName_ends);
766        check_streams.att_refs = simd_and(tag_Callouts.AttVal_spans, scope1.RefStart);
767  }
768  void do_segment(CtCDPI_Callouts ctCDPI_Callouts[], Tag_Callouts tag_Callouts[], Lex lex[], U8 u8[], Scope1 scope1[], Ref_Callouts ref_Callouts[], Xml_names xml_names[], Check_streams check_streams[]) {
769  for (int i = 0; i < SEGMENT_BLOCKS; i++)
770    do_block(ctCDPI_Callouts[i], tag_Callouts[i], lex[i], u8[i], scope1[i], ref_Callouts[i], xml_names[i], check_streams[i]);
771  }
772
773  };
774
775  struct Validate_xml_names {
776  Validate_xml_names() { CarryInit(carryQ, 9); }
777  void do_block(CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Tag_Callouts & tag_Callouts, Lex & lex, U8 & u8, Xml_names & xml_names, Check_streams & check_streams) {
778                BitBlock PI_names, GenRefs, ElemNames, AttNames, qname_stream, ncname_stream;
779                BitBlock name_stream, name_start, name_cursor, void_prefix_err, namespace_sep;
780                BitBlock local_part_start, local_part_err, colon2_err, ncname_err;
781
782
783        PI_names = BitBlock_sub_ci_co(ctCDPI_Callouts.PI_name_ends, ctCDPI_Callouts.PI_name_starts, carryQ, 0);
784        GenRefs = BitBlock_sub_ci_co(ref_Callouts.GenRef_ends, ref_Callouts.GenRef_starts, carryQ, 1);
785        ElemNames = BitBlock_sub_ci_co(tag_Callouts.ElemName_ends, tag_Callouts.ElemName_starts, carryQ, 2);
786        AttNames = BitBlock_sub_ci_co(tag_Callouts.AttName_ends, tag_Callouts.AttName_starts, carryQ, 3);
787        qname_stream = simd_or(ElemNames, AttNames);
788        ncname_stream = simd_or(PI_names, GenRefs);
789        name_stream = simd_or(qname_stream, ncname_stream);
790        name_start = simd_andc(name_stream, BitBlock_advance_ci_co(name_stream, carryQ, 4));
791        name_cursor = simd_andc(name_stream, BitBlock_advance_ci_co(name_stream, carryQ, 5));
792        void_prefix_err = simd_and(name_cursor, lex.Colon);
793        namespace_sep = simd_and(BitBlock_scanthru_ci_co(name_cursor, simd_andc(lex.NameScan, lex.Colon), carryQ, 6), lex.Colon);
794        local_part_start = BitBlock_advance_ci_co(namespace_sep, carryQ, 7);
795        local_part_err = simd_andc(local_part_start, lex.NameScan);
796        colon2_err = simd_and(BitBlock_scanthru_ci_co(local_part_start, simd_andc(lex.NameScan, lex.Colon), carryQ, 8), lex.Colon);
797        ncname_err = simd_and(ncname_stream, lex.Colon);
798        xml_names.namespace_error = simd_or(simd_or(simd_or(void_prefix_err, local_part_err), colon2_err), ncname_err);
799        check_streams.non_ascii_name_starts = simd_andc(name_start, lex.ASCII_name_start);
800        check_streams.non_ascii_names = simd_andc(simd_andc(simd_andc(name_stream, name_start), lex.ASCII_name_char), u8.suffix);
801        CarryQ_Adjust(carryQ, 9);
802  }
803  void do_segment(CtCDPI_Callouts ctCDPI_Callouts[], Ref_Callouts ref_Callouts[], Tag_Callouts tag_Callouts[], Lex lex[], U8 u8[], Xml_names xml_names[], Check_streams check_streams[]) {
804  for (int i = 0; i < SEGMENT_BLOCKS; i++)
805    do_block(ctCDPI_Callouts[i], ref_Callouts[i], tag_Callouts[i], lex[i], u8[i], xml_names[i], check_streams[i]);
806  }
807  CarryDeclare(carryQ, 9);
808  };
809
810  struct Add_scope_streams {
811  Add_scope_streams() { CarryInit(carryQ, 2); }
812  void do_block(Lex & lex, Scope1 & scope1) {
813                BitBlock v, w, v1, w1;
814
815
816        v = simd_or(lex.LAngle, lex.Hyphen);
817        w = simd_or(lex.Hyphen, lex.QMark);
818        v1 = BitBlock_advance_ci_co(v, carryQ, 0);
819        w1 = BitBlock_advance_ci_co(w, carryQ, 1);
820        scope1.LAngle = simd_andc(v1, w1);
821        scope1.Hyphen = simd_and(v1, w1);
822        scope1.QMark = simd_andc(w1, v1);
823        CarryQ_Adjust(carryQ, 2);
824  }
825  void do_segment(Lex lex[], Scope1 scope1[]) {
826  for (int i = 0; i < SEGMENT_BLOCKS; i++)
827    do_block(lex[i], scope1[i]);
828  }
829  CarryDeclare(carryQ, 2);
830  };
831
832
833static inline void s2p_do_block(BytePack U8[], Basis_bits & basis_bits) {
834  s2p(U8[0], U8[1], U8[2], U8[3], U8[4], U8[5], U8[6], U8[7],
835        basis_bits.bit_0, basis_bits.bit_1, basis_bits.bit_2, basis_bits.bit_3, basis_bits.bit_4, basis_bits.bit_5, basis_bits.bit_6, basis_bits.bit_7);
836}
837
838static inline void s2p_do_final_block(BytePack U8[], Basis_bits & basis_bits, BitBlock EOF_mask) {
839  s2p_do_block(U8, basis_bits);
840  basis_bits.bit_0 = simd_and(basis_bits.bit_0, EOF_mask);
841  basis_bits.bit_1 = simd_and(basis_bits.bit_1, EOF_mask);
842  basis_bits.bit_2 = simd_and(basis_bits.bit_2, EOF_mask);
843  basis_bits.bit_3 = simd_and(basis_bits.bit_3, EOF_mask);
844  basis_bits.bit_4 = simd_and(basis_bits.bit_4, EOF_mask);
845  basis_bits.bit_5 = simd_and(basis_bits.bit_5, EOF_mask);
846  basis_bits.bit_6 = simd_and(basis_bits.bit_6, EOF_mask);
847  basis_bits.bit_7 = simd_and(basis_bits.bit_7, EOF_mask);
848}
849
850static inline void s2p_do_segment(BytePack U8[], Basis_bits basis_bits[]) {
851  for (int i = 0; i < SEGMENT_BLOCKS; i++)
852           s2p_do_block(&U8[8*i], basis_bits[i]);
853}
854
855static inline void postprocess_do_block(Lex & lex, CtCDPI_Callouts & ctCDPI_Callouts, Ref_Callouts & ref_Callouts, Check_streams & check_streams, int chars_avail){
856            tracker.StoreNewlines(lex.LF);
857
858                if (bitblock_has_bit(simd_or(check_streams.non_ascii_name_starts, check_streams.non_ascii_names))) {
859                  StreamScan((ScanBlock *) &check_streams.non_ascii_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), NameStrt_check);
860                  StreamScan((ScanBlock *) &check_streams.non_ascii_names, sizeof(BitBlock)/sizeof(ScanBlock), Name_check);
861                }
862
863                if (bitblock_has_bit(ctCDPI_Callouts.PI_name_starts)){
864                  StreamScan((ScanBlock *) &ctCDPI_Callouts.PI_name_starts, sizeof(BitBlock)/sizeof(ScanBlock), PIName_check);
865                }
866
867                if (bitblock_has_bit(ctCDPI_Callouts.CD_starts)){
868                  StreamScan((ScanBlock *) &ctCDPI_Callouts.CD_starts, sizeof(BitBlock)/sizeof(ScanBlock), CD_check);
869                }
870
871                if (bitblock_has_bit(ref_Callouts.GenRef_starts)){
872                  StreamScan((ScanBlock *) &ref_Callouts.GenRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), GenRef_check);
873                }
874
875                if (bitblock_has_bit(ref_Callouts.DecRef_starts)){
876                  StreamScan((ScanBlock *) &ref_Callouts.DecRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), DecRef_check);
877                }
878
879                if (bitblock_has_bit(ref_Callouts.HexRef_starts)){
880                  StreamScan((ScanBlock *) &ref_Callouts.HexRef_starts, sizeof(BitBlock)/sizeof(ScanBlock), HexRef_check);
881                }
882
883                if (bitblock_has_bit(check_streams.att_refs)){
884                  StreamScan((ScanBlock *) &check_streams.att_refs, sizeof(BitBlock)/sizeof(ScanBlock), AttRef_check);
885                }
886
887                if (bitblock_has_bit(check_streams.error_mask)) {
888                  int errpos = count_forward_zeroes(check_streams.error_mask);
889                  ReportError("error found", errpos);
890              exit(-1);
891                }
892
893                matcher.store_streams(check_streams.tag_marks, check_streams.name_follows, check_streams.misc_mask, chars_avail);
894                tracker.AdvanceBlock();
895}
896
897static inline void postprocess_do_segment(Lex lex[], CtCDPI_Callouts ctCDPI_Callouts[], Ref_Callouts ref_Callouts[], Check_streams check_streams[]){
898
899  for (int i = 0; i < SEGMENT_BLOCKS; i++){
900           postprocess_do_block(lex[i], ctCDPI_Callouts[i], ref_Callouts[i], check_streams[i], SEGMENT_SIZE);
901           block_base += BLOCK_SIZE;
902  }
903
904        matcher.StreamScan(SEGMENT_SIZE);
905        matcher.Advance_segment();
906        tracker.Advance_buffer();
907}
908
909struct Para_data{
910
911          char srcbuf[BLOCK_SIZE * (SEGMENT_BLOCKS+1) + OVERLAP_BUFSIZE*2];
912
913          struct U8 u8[SEGMENT_BLOCKS];
914
915          struct Lex lex[SEGMENT_BLOCKS];
916
917          struct Scope1 scope1[SEGMENT_BLOCKS];
918
919          struct CtCDPI_Callouts ctCDPI_Callouts[SEGMENT_BLOCKS];
920
921          struct Ref_Callouts ref_Callouts[SEGMENT_BLOCKS];
922
923          struct Tag_Callouts tag_Callouts[SEGMENT_BLOCKS];
924
925          struct Basis_bits basis_bits[SEGMENT_BLOCKS];
926
927          struct Check_streams check_streams[SEGMENT_BLOCKS];
928
929          struct Xml_names xml_names[SEGMENT_BLOCKS];
930};
931
932Parse_refs parse_refs;
933Parse_tags parse_tags;
934Classify_bytes_Validate_utf8 classify_bytes_Validate_utf8;
935Parse_CtCDPI parse_CtCDPI;
936Do_check_streams do_check_streams;
937Validate_xml_names validate_xml_names;
938Add_scope_streams add_scope_streams;
939
940int file_segs=0;
941FILE *infile;
942FILE *outfile;
943// load with 'consume' (data-dependent) memory ordering
944template<typename T>
945T load_consume(T const* addr)
946{
947  // hardware fence is implicit on x86
948  T v = *const_cast<T const volatile*>(addr);
949#ifdef GCC
950 __sync_synchronize(); // compiler fence
951#endif
952#ifdef ICC
953 __memory_barrier(); // compiler fence
954#endif
955  return v;
956}
957
958// store with 'release' memory ordering
959template<typename T>
960void store_release(T* addr, T v)
961{
962  // hardware fence is implicit on x86
963#ifdef GCC
964 __sync_synchronize(); // compiler fence
965#endif
966#ifdef ICC
967 __memory_barrier(); // compiler fence
968#endif
969  *const_cast<T volatile*>(addr) = v;
970}
971
972// cache line size on modern x86 processors (in bytes)
973size_t const cache_line_size = 64;
974
975// single-producer/single-consumer queue
976template<typename T>
977class spsc_queue
978{
979public:
980  spsc_queue()
981  {
982      node* n = new node;
983      n->next_ = 0;
984      overlap_bytes = 0;
985      tail_ = head1_ = head2_ = head3_ = first_= tail_copy_ = n;
986      count=0;
987  }
988
989  ~spsc_queue()
990  {
991      node* n = first_;
992      do
993      {
994          node* next = n->next_;
995          delete n;
996          n = next;
997      }
998      while (n);
999  }
1000
1001  void pass1()
1002  {
1003      node* n = alloc_node();
1004      n->next_ = 0;
1005      //do pass1
1006      char * srcptr = n->para_data.srcbuf + OVERLAP_BUFSIZE;
1007      memmove(n->para_data.srcbuf, overlap_buffer, 2*overlap_bytes);
1008      int chars_read = fread(&srcptr[overlap_bytes], 1, SEGMENT_SIZE + OVERLAP_BUFSIZE - overlap_bytes, infile);
1009      memmove(overlap_buffer, &srcptr[SEGMENT_SIZE-OVERLAP_BUFSIZE], 2*OVERLAP_BUFSIZE);
1010      overlap_bytes = OVERLAP_BUFSIZE;
1011      s2p_do_segment((BytePack *) srcptr, n->para_data.basis_bits);
1012      classify_bytes_Validate_utf8.do_segment(n->para_data.basis_bits, n->para_data.lex, n->para_data.u8);
1013
1014      store_release(&head1_->next_, n);
1015      head1_ = n;
1016  }
1017  bool pass2()
1018  {
1019          if(load_consume(&head2_->next_))
1020          {
1021              //do pass2
1022
1023                  add_scope_streams.do_segment(head2_->next_->para_data.lex, head2_->next_->para_data.scope1);
1024                  parse_CtCDPI.do_segment(head2_->next_->para_data.ctCDPI_Callouts, head2_->next_->para_data.lex, head2_->next_->para_data.scope1, head2_->next_->para_data.check_streams);
1025                  parse_refs.do_segment(head2_->next_->para_data.lex, head2_->next_->para_data.scope1, head2_->next_->para_data.ctCDPI_Callouts, head2_->next_->para_data.ref_Callouts);
1026
1027                  store_release(&head2_, head2_->next_);
1028                  return true;
1029          }
1030      else
1031      {
1032          return false;
1033      }
1034  }
1035
1036  bool pass3()
1037  {
1038      if ((head3_!= head2_) && load_consume(&head3_->next_))
1039      {
1040          //do pass3
1041          parse_tags.do_segment(head3_->next_->para_data.lex, head3_->next_->para_data.scope1, head3_->next_->para_data.ctCDPI_Callouts, head3_->next_->para_data.tag_Callouts);
1042                  validate_xml_names.do_segment(head3_->next_->para_data.ctCDPI_Callouts, head3_->next_->para_data.ref_Callouts, head3_->next_->para_data.tag_Callouts, head3_->next_->para_data.lex, head3_->next_->para_data.u8, head3_->next_->para_data.xml_names, head3_->next_->para_data.check_streams);
1043                  do_check_streams.do_segment(head3_->next_->para_data.ctCDPI_Callouts, head3_->next_->para_data.tag_Callouts, head3_->next_->para_data.lex, head3_->next_->para_data.u8, head3_->next_->para_data.scope1, head3_->next_->para_data.ref_Callouts, head3_->next_->para_data.xml_names, head3_->next_->para_data.check_streams);
1044
1045          store_release(&head3_, head3_->next_);
1046          return true;
1047      }
1048      else
1049      {
1050          return false;
1051      }
1052  }
1053
1054  bool pass4()
1055  {
1056      if ((tail_!= head3_)  && load_consume(&tail_->next_))
1057      {
1058          //do pass4
1059          source = tail_->next_->para_data.srcbuf+OVERLAP_BUFSIZE;
1060          matcher.setSrc(source);
1061          postprocess_do_segment(tail_->next_->para_data.lex, tail_->next_->para_data.ctCDPI_Callouts, tail_->next_->para_data.ref_Callouts, tail_->next_->para_data.check_streams);
1062          block_base = 0;
1063          store_release(&tail_, tail_->next_);
1064          return true;
1065      }
1066      else
1067      {
1068          return false;
1069      }
1070  }
1071
1072  int count;
1073private:
1074  // internal node structure
1075  struct node
1076  {
1077      node* next_;
1078      T para_data;
1079  };
1080
1081  // consumer part
1082  // accessed mainly by consumer, infrequently be producer
1083  node* tail_; // tail of the queue
1084
1085  // delimiter between consumer part and producer part,
1086  // so that they situated on different cache lines
1087  char cache_line_pad_ [cache_line_size];
1088
1089  int overlap_bytes;
1090
1091  char overlap_buffer[2*OVERLAP_BUFSIZE];
1092
1093  // producer part
1094  // accessed only by producer
1095  node* head1_; // head of the queue
1096  node* head2_;
1097  node* head3_;
1098  node* first_; // last unused node (tail of node cache)
1099  node* tail_copy_; // helper (points somewhere between first_ and tail_)
1100
1101
1102  node* alloc_node()
1103  {
1104      // first tries to allocate node from internal node cache,
1105      // if attempt fails, allocates node via ::operator new()
1106while(1){
1107      if (first_ != tail_copy_)
1108      {
1109          node* n = first_;
1110          first_ = first_->next_;
1111          return n;
1112      }
1113      tail_copy_ = load_consume(&tail_);
1114      if (first_ != tail_copy_)
1115      {
1116          node* n = first_;
1117          first_ = first_->next_;
1118          return n;
1119      }
1120      node* n = new node;
1121      if(count>8)
1122        continue;
1123      else
1124        count++;
1125      return n;
1126}
1127  }
1128
1129  spsc_queue(spsc_queue const&);
1130  spsc_queue& operator = (spsc_queue const&);
1131};
1132
1133
1134spsc_queue<struct Para_data> q;
1135
1136void *stageOne(void *threadid)
1137{
1138   long tid = (long)threadid;
1139   for(int i=0;i<file_segs;i++){
1140           q.pass1();
1141//         printf("thread %ld: %i\n",tid,i);
1142   }
1143   pthread_exit(NULL);
1144}
1145void *stageTwo(void *threadid)
1146{
1147   long tid = (long)threadid;
1148   for(int i=0;i<file_segs;i++){
1149           while(!q.pass2());
1150//         printf("thread %ld: %i\n",tid,i);
1151   }
1152   pthread_exit(NULL);
1153}
1154
1155void *stageThree(void *threadid)
1156{
1157   long tid = (long)threadid;
1158   for(int i=0;i<file_segs;i++){
1159           while(!q.pass3());
1160//         printf("thread %ld: %i\n",tid,i);
1161   }
1162   pthread_exit(NULL);
1163}
1164void *stageFour(void *threadid)
1165{
1166   long tid = (long)threadid;
1167   for(int i=0;i<file_segs;i++){
1168           while(!q.pass4());
1169//         printf("thread %ld: %i\n",tid,i);
1170   }
1171   pthread_exit(NULL);
1172}
1173
1174#define NUM_THREADS 4
1175
1176int
1177main(int argc, char * argv[]) {
1178        char * infilename, * outfilename;
1179        FILE *tmpinfile, *tmpoutfile;
1180        struct stat fileinfo;
1181
1182    pthread_t threads[NUM_THREADS];
1183    int rc;
1184    long t=0;
1185    void *status;
1186
1187        if (argc < 2) {
1188                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
1189                exit(-1);
1190        }
1191
1192        infilename = argv[1];
1193        stat(infilename, &fileinfo);
1194        file_segs = fileinfo.st_size/SEGMENT_SIZE;
1195        infile = fopen(infilename, "rb");
1196        if (!infile) {
1197                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
1198                exit(-1);
1199        }
1200
1201        if (argc < 3) outfile = stdout;
1202        else {
1203                outfilename = argv[2];
1204                outfile = fopen(outfilename, "wb");
1205                if (!outfile) {
1206                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
1207                        exit(-1);
1208                }
1209        }
1210
1211        PERF_SEC_INIT(parser_timer);
1212
1213        PERF_SEC_START(parser_timer);
1214
1215
1216          rc = pthread_create(&threads[t], NULL, stageOne, (void *)t);
1217          if (rc){
1218                  printf("ERROR; return code from pthread_create() is %d\n", rc);
1219                  exit(-1);
1220          }
1221          t++;
1222          rc = pthread_create(&threads[t], NULL, stageTwo, (void *)t);
1223          if (rc){
1224                  printf("ERROR; return code from pthread_create() is %d\n", rc);
1225                  exit(-1);
1226          }
1227
1228          t++;
1229          rc = pthread_create(&threads[t], NULL, stageThree, (void *)t);
1230          if (rc){
1231                  printf("ERROR; return code from pthread_create() is %d\n", rc);
1232                  exit(-1);
1233          }
1234
1235          t++;
1236          rc = pthread_create(&threads[t], NULL, stageFour, (void *)t);
1237          if (rc){
1238                  printf("ERROR; return code from pthread_create() is %d\n", rc);
1239                  exit(-1);
1240          }
1241
1242          for(t=0; t<NUM_THREADS; t++) {
1243             rc = pthread_join(threads[t], &status);
1244             if (rc) {
1245                printf("ERROR; return code from pthread_join() is %d\n", rc);
1246                exit(-1);
1247             }
1248//           printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
1249          }
1250
1251
1252        PERF_SEC_END(parser_timer, fileinfo.st_size/SEGMENT_SIZE*SEGMENT_SIZE);
1253
1254        PERF_SEC_DUMP(parser_timer);
1255
1256        PERF_SEC_DESTROY(parser_timer);
1257
1258//      printf("count = %i\n", q.count);
1259
1260        pthread_exit(NULL);
1261
1262        fclose(infile);
1263        fclose(outfile);
1264        return(0);
1265}
Note: See TracBrowser for help on using the repository browser.