source: trunk/src/bitlex.c @ 44

Last change on this file since 44 was 42, checked in by cameron, 11 years ago

lib_simd: refactored allocation, bitstream_scan

File size: 30.7 KB
Line 
1/*  bitlex - Parabix lexical analysis common routines.
2    Copyright (c) 2007, 2008, Robert D. Cameron.
3    Licensed to the public under the Open Software License 3.0.
4    Licensed to International Characters, Inc., under the Academic
5    Free License 3.0.
6
7*/
8
9#include "bitlex.h"
10#include "../lib/lib_simd.h"
11
12
13Lexer_Interface::Lexer_Interface(XML_Buffer_Interface *b, LexicalStreamSet *l) {
14        xml_buf = b;
15        parsing_engine_data = l;
16        x8basis = (BitBlockBasis *) simd_new(BUFFER_SIZE/PACKSIZE);
17};
18
19void NoEncodingError(char * msg) {
20        printf("Error : %s\n", msg);
21        exit(-1);
22}
23
24void EncodingError(char * msg, unsigned char * enc_ptr, int lgth) {
25        printf("Error : Illegal/unsupported %s encoding of length %i: \"", msg, lgth);
26        for (int i = 0; i < lgth; i++) printf("%c", enc_ptr[i]);
27        printf("\"\n"); 
28        exit(-1);
29}
30
31template <>
32Lexer_Interface * Lexer<ASCII>::LexerFactory(XML_Buffer_Interface *b, LexicalStreamSet *l) {
33        if (!(b->has_encoding_decl)) {
34                // Must be UTF-8 or UTF-16; UTF-16 requires a ByteOrderMark.
35                if (b->code_unit_size == SingleByte) return new UTF_8_Lexer(b, l);
36                else if ((b->code_unit_size == DoubleByte))
37                        if (b->BOM_units == 1) return new UTF_16_Lexer(b, l);
38                        else NoEncodingError("UTF-16 implied but no byte order found.");
39                else NoEncodingError("UTF-32 without an encoding declaration.\n");
40        }
41        else {
42                unsigned char * enc_ptr = 
43                        &(((unsigned char *)(b->x8data))[b->encoding_start_pos]);
44                int lgth = b->encoding_lgth;
45                CodeUnit_ByteOrder order = b->byte_order;
46                switch (b->code_unit_size) {
47                case SingleByte:
48                        if ((lgth == 5) && at_UTF_8(enc_ptr))
49                                return new UTF_8_Lexer(b, l);
50                        else if ((lgth == 5) && at_ASCII(enc_ptr))
51                                return new ASCII_7_Lexer(b, l);
52                        else if ((lgth == 6)  && at_Latin1(enc_ptr))
53                                return new EASCII_8_Lexer(b, l);
54                        /* Really need a table-based lookup here */
55                        else EncodingError("8-bit", enc_ptr, lgth);
56                case DoubleByte:
57                        if (b->BOM_units == 1) 
58                                if ((lgth == 6) && at_UTF_16(enc_ptr))
59                                        return new UTF_16_Lexer(b, l);
60                                else if ((lgth == 5) && at_UCS_2(enc_ptr))
61                                        return new UCS_2_Lexer(b, l);
62                                else EncodingError("16-bit", enc_ptr, lgth);
63                        else if (order == BigEndian)
64                                if ((lgth == 8) && at_UTF_16BE(enc_ptr))
65                                        return new UTF_16_Lexer(b, l);
66                                else if ((lgth == 7) && at_UCS_2BE(enc_ptr))
67                                        return new UCS_2_Lexer(b, l);
68                                else EncodingError("16BE", enc_ptr, lgth);
69                        else /*if (order == LittleEndian)*/
70                                if ((lgth == 8) && at_UTF_16LE(enc_ptr))
71                                        return new UTF_16_Lexer(b, l);
72                                else if ((lgth == 7) && at_UCS_2LE(enc_ptr))
73                                        return new UCS_2_Lexer(b, l);
74                                else EncodingError("16LE", enc_ptr, lgth);
75                case QuadByte:
76                        if (b->BOM_units == 1) 
77                                if ((lgth == 6) && at_UTF_32(enc_ptr))
78                                        return new UTF_32_Lexer(b, l);
79                                else if ((lgth == 5) && at_UCS_4(enc_ptr))
80                                        return new UTF_32_Lexer(b, l);
81                                else EncodingError("32-bit", enc_ptr, lgth);
82                        else if (order == BigEndian)
83                                if ((lgth == 8) && at_UTF_32BE(enc_ptr))
84                                        return new UTF_32_Lexer(b, l);
85                                else if ((lgth == 7) && at_UCS_4BE(enc_ptr))
86                                        return new UTF_32_Lexer(b, l);
87                                else EncodingError("32BE", enc_ptr, lgth);
88                        else if (order == LittleEndian)
89                                if ((lgth == 8) && at_UTF_32LE(enc_ptr))
90                                        return new UTF_32_Lexer(b, l);
91                                else if ((lgth == 7) && at_UCS_4LE(enc_ptr))
92                                        return new UTF_32_Lexer(b, l);
93                                else EncodingError("32LE", enc_ptr, lgth);
94                        else EncodingError("32-bit", enc_ptr, lgth);
95                }
96        }
97}
98
99template <>
100Lexer_Interface * Lexer<EBCDIC>::LexerFactory(XML_Buffer_Interface *b, LexicalStreamSet *l) {
101        if (!(b->has_encoding_decl)) {
102                // Must be UTF-8 or UTF-16; UTF-16 requires a ByteOrderMark.
103                NoEncodingError("EBCDIC-family inferred, but no encoding declaration present.\n");
104        }
105        else {
106                unsigned char * enc_ptr = 
107                        &(((unsigned char *)(b->x8data))[b->encoding_start_pos]);
108                int lgth = b->encoding_lgth;
109
110                /* Really need a table-based lookup here */
111                if ((lgth == 6) && at_EBCDIC(enc_ptr))
112                        return new EBCDIC_Lexer(b, l);
113                else EncodingError("EBCDIC family", enc_ptr, lgth);
114        }
115}
116
117template <CodeUnit_Base C>
118Lexer<C>::Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer_Interface::Lexer_Interface(b, l) {
119}
120
121UTF_8_Lexer::UTF_8_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
122}
123
124ASCII_7_Lexer::ASCII_7_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
125}
126
127EASCII_8_Lexer::EASCII_8_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
128}
129
130U16_Lexer::U16_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
131}
132
133UTF_16_Lexer::UTF_16_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : U16_Lexer::U16_Lexer(b, l) {
134}
135
136UCS_2_Lexer::UCS_2_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : U16_Lexer::U16_Lexer(b, l) {
137}
138
139UTF_32_Lexer::UTF_32_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<ASCII>::Lexer(b, l) {
140}
141
142EBCDIC_Lexer::EBCDIC_Lexer(XML_Buffer_Interface *b, LexicalStreamSet *l) : Lexer<EBCDIC>::Lexer(b, l) {
143}
144
145template <CodeUnit_Base C>
146static inline void WS_Control_Blocks(BitBlock bit[], BitBlock& WS, BitBlock& Control);
147
148template <>
149static inline void WS_Control_Blocks<ASCII>(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
150        BitBlock temp1 = simd_or(bit[0], bit[1]);
151        BitBlock temp2 = simd_or(temp1, bit[2]);
152        Control = simd_andc(simd_const_1(1), temp2);
153        BitBlock temp3 = simd_or(bit[2], bit[3]);
154        BitBlock temp4 = simd_or(temp1, temp3);
155        BitBlock temp5 = simd_and(bit[4], bit[5]);
156        BitBlock temp6 = simd_andc(bit[7], bit[6]);
157        BitBlock temp7 = simd_and(temp5, temp6);
158        BitBlock CR = simd_andc(temp7, temp4);
159        BitBlock temp8 = simd_andc(bit[4], bit[5]);
160        BitBlock temp9 = simd_andc(bit[6], bit[7]);
161        BitBlock temp10 = simd_and(temp8, temp9);
162        BitBlock LF = simd_andc(temp10, temp4);
163        BitBlock temp11 = simd_and(temp8, temp6);
164        BitBlock HT = simd_andc(temp11, temp4);
165        BitBlock temp12 = simd_andc(bit[2], bit[3]);
166        BitBlock temp13 = simd_andc(temp12, temp1);
167        BitBlock temp14 = simd_or(bit[4], bit[5]);
168        BitBlock temp15 = simd_or(bit[6], bit[7]);
169        BitBlock temp16 = simd_or(temp14, temp15);
170        BitBlock SP = simd_andc(temp13, temp16);
171        WS = simd_or(simd_or(CR, LF), simd_or(HT, SP));
172}
173
174template <>
175static inline void WS_Control_Blocks<EBCDIC>(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
176        BitBlock temp1 = simd_or(bit[0], bit[1]);
177        BitBlock temp2 = simd_or(bit[2], bit[3]);
178        BitBlock temp3 = simd_or(temp1, temp2);
179        BitBlock temp4 = simd_or(bit[4], bit[5]);
180        BitBlock temp5 = simd_or(temp3, temp4);
181        BitBlock temp6 = simd_and(bit[2], bit[3]);
182        BitBlock temp7 = simd_andc(temp6, temp1);
183        BitBlock temp8 = simd_andc(bit[5], bit[4]);
184        BitBlock temp9 = simd_and(bit[6], bit[7]);
185        BitBlock temp10 = simd_and(temp8, temp9);
186        BitBlock temp11 = simd_and(temp7, temp10);
187        BitBlock temp12 = simd_andc(temp5, temp11);
188        BitBlock temp13 = simd_andc(bit[2], bit[3]);
189        BitBlock temp14 = simd_andc(temp13, temp1);
190        BitBlock temp15 = simd_and(bit[4], bit[5]);
191        BitBlock temp16 = simd_and(temp14, temp15);
192        BitBlock temp17 = simd_andc(bit[6], bit[7]);
193        BitBlock temp18 = simd_andc(temp16, temp17);
194        BitBlock temp19 = simd_andc(temp12, temp18);
195        BitBlock temp20 = simd_andc(bit[3], bit[2]);
196        BitBlock temp21 = simd_andc(temp20, temp1);
197        BitBlock temp22 = simd_and(temp8, temp17);
198        BitBlock temp23 = simd_and(temp21, temp22);
199        BitBlock temp24 = simd_andc(temp19, temp23);
200        BitBlock temp25 = simd_or(temp1, bit[2]);
201        BitBlock temp26 = simd_or(bit[5], temp9);
202        BitBlock temp27 = simd_and(bit[4], temp26);
203        BitBlock temp28 = simd_andc(simd_const_1(1), temp4);
204        BitBlock temp29 = simd_if(bit[3], temp27, temp28);
205        BitBlock temp30 = simd_andc(temp29, temp25);
206        BitBlock temp31 = simd_andc(temp24, temp30);
207        BitBlock temp32 = simd_andc(temp15, bit[6]);
208        BitBlock temp33 = simd_and(temp7, temp32);
209        BitBlock temp34 = simd_andc(temp31, temp33);
210        BitBlock temp35 = simd_andc(temp17, temp4);
211        BitBlock temp36 = simd_and(temp7, temp35);
212        BitBlock temp37 = simd_andc(temp34, temp36);
213        BitBlock temp38 = simd_and(temp8, bit[6]);
214        BitBlock temp39 = simd_and(temp14, temp38);
215        BitBlock temp40 = simd_andc(temp37, temp39);
216        BitBlock temp41 = simd_andc(bit[4], bit[5]);
217        BitBlock temp42 = simd_andc(temp41, bit[6]);
218        BitBlock temp43 = simd_and(temp21, temp42);
219        BitBlock temp44 = simd_andc(temp40, temp43);
220        BitBlock temp45 = simd_and(temp15, temp9);
221        BitBlock temp46 = simd_and(temp7, temp45);
222        BitBlock temp47 = simd_andc(temp44, temp46);
223        BitBlock temp48 = simd_and(temp21, temp15);
224        BitBlock temp49 = simd_andc(temp47, temp48);
225        Control = simd_andc(simd_const_1(1), temp49);
226        BitBlock temp50 = simd_andc(bit[7], bit[6]);
227        BitBlock temp51 = simd_and(temp15, temp50);
228        BitBlock CR = simd_andc(temp51, temp3);
229        BitBlock temp52 = simd_and(temp8, temp50);
230        BitBlock LF = simd_and(temp14, temp52);
231        BitBlock HT = simd_andc(temp52, temp3);
232        BitBlock temp53 = simd_andc(bit[1], bit[0]);
233        BitBlock temp54 = simd_andc(temp53, temp2);
234        BitBlock temp55 = simd_or(bit[6], bit[7]);
235        BitBlock temp56 = simd_or(temp4, temp55);
236        BitBlock SP = simd_andc(temp54, temp56);
237        WS = simd_or(simd_or(CR, LF), simd_or(HT, SP));
238}
239
240
241
242template <CodeUnit_Base C>
243void Lexer<C>::Do_XML_10_WS_Control() {
244        BitBlock Restricted = simd_const_1(0);
245        BitBlock Control = simd_const_1(0);
246        BitBlock WS = simd_const_1(0);
247        BitBlock final_block_mask;
248        for (int i = 0; i < buffer_blocks; i++) {
249                Restricted = simd_or(Restricted, simd_andc(Control, WS));
250                WS_Control_Blocks<C>(x8basis[i].bit, 
251                                     WS,
252                                     Control);
253                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
254        }
255        if ((buffer_units % BLOCKSIZE) != 0) {
256                final_block_mask = sisd_sfl(simd_const_1(1),
257                                            sisd_from_int(buffer_units % BLOCKSIZE));
258                Control = simd_andc(Control, final_block_mask);
259        }
260        Restricted = simd_or(Restricted, simd_andc(Control, WS));
261        if (bitblock_has_bit(Restricted)) {
262                printf("Restricted control character in input.\n");
263                exit(-1);
264        }
265};
266
267
268template <CodeUnit_Base C>
269static inline void ComputeLexicalItemBlocks(BitBlock bit[], BitBlock LexItem[]);
270
271/* Given the bit[] array of one BitBlock each for the 8 bits of
272   an ASCII-family character representation, compute the parallel
273   lexical item streams needed for XML parsing.
274
275   WARNING: the following is generated code by charset_compiler.py.
276   Do not edit.
277
278*/
279
280template <>
281static inline void ComputeLexicalItemBlocks<ASCII>(BitBlock bit[], BitBlock LexItem[]) {
282        BitBlock temp1 = simd_or(bit[0], bit[1]);
283        BitBlock temp2 = simd_and(bit[2], bit[3]);
284        BitBlock temp3 = simd_andc(temp2, temp1);
285        BitBlock temp4 = simd_and(bit[4], bit[5]);
286        BitBlock temp5 = simd_or(bit[6], bit[7]);
287        BitBlock temp6 = simd_andc(temp4, temp5);
288        BitBlock temp7 = simd_and(temp3, temp6);
289        BitBlock temp8 = simd_andc(bit[2], bit[3]);
290        BitBlock temp9 = simd_andc(temp8, temp1);
291        BitBlock temp10 = simd_andc(bit[5], bit[4]);
292        BitBlock temp11 = simd_andc(bit[6], bit[7]);
293        BitBlock temp12 = simd_and(temp10, temp11);
294        BitBlock temp13 = simd_and(temp9, temp12);
295        LexItem[MarkupStart] = simd_or(temp7, temp13);
296        BitBlock temp14 = simd_and(temp4, temp11);
297        BitBlock RAngle = simd_and(temp3, temp14);
298        BitBlock temp15 = simd_andc(bit[1], bit[0]);
299        BitBlock temp16 = simd_andc(bit[3], bit[2]);
300        BitBlock temp17 = simd_and(temp15, temp16);
301        BitBlock temp18 = simd_andc(bit[7], bit[6]);
302        BitBlock temp19 = simd_and(temp4, temp18);
303        BitBlock RBracket = simd_and(temp17, temp19);
304        LexItem[Hyphen] = simd_and(temp9, temp19);
305        BitBlock temp20 = simd_and(bit[6], bit[7]);
306        BitBlock temp21 = simd_and(temp4, temp20);
307        LexItem[QMark] = simd_and(temp3, temp21);
308        BitBlock temp22 = simd_or(bit[4], bit[5]);
309        BitBlock temp23 = simd_andc(temp11, temp22);
310        BitBlock temp24 = simd_and(temp10, temp20);
311        BitBlock temp25 = simd_or(temp23, temp24);
312        BitBlock temp26 = simd_and(temp9, temp25);
313        BitBlock temp27 = simd_or(temp26, temp7);
314        LexItem[Quote] = simd_or(temp27, temp13);
315        BitBlock temp28 = simd_andc(bit[4], bit[5]);
316        BitBlock temp29 = simd_and(temp28, temp20);
317        BitBlock temp30 = simd_or(temp29, temp19);
318        BitBlock temp31 = simd_and(temp3, temp30);
319        BitBlock temp32 = simd_and(temp9, temp21);
320        BitBlock temp33 = simd_or(temp31, temp32);
321        BitBlock temp34 = simd_or(temp33, RAngle);
322        LexItem[NameFollow] = simd_or(temp34, LexItem[QMark]);
323       
324        /* Mark potential occurrences of ']]>'  These are all actual
325        occurrences of ]]> as well as occurrences of ]] or ] at
326        the block end. Shifting the RBracket and RAngle streams in
327        negated forms ensures that a potential CD_End is not ruled
328        out at the block boundary. */
329        LexItem[CD_End_check] = simd_andc(RBracket, 
330                                          simd_or(sisd_sbli(simd_not(RBracket), 1),
331                                                  sisd_sbli(simd_not(RAngle), 2)));
332#ifndef OMIT_CD_End_check_In_Markup_Scan
333        LexItem[MarkupStart] = simd_or(LexItem[MarkupStart], LexItem[CD_End_check]);
334#endif
335}
336
337template <>
338static inline void ComputeLexicalItemBlocks<EBCDIC>(BitBlock bit[], BitBlock LexItem[]) {
339        BitBlock temp1 = simd_andc(bit[1], bit[0]);
340        BitBlock temp2 = simd_or(bit[2], bit[3]);
341        BitBlock temp3 = simd_andc(temp1, temp2);
342        BitBlock temp4 = simd_and(bit[4], bit[5]);
343        BitBlock temp5 = simd_or(bit[6], bit[7]);
344        BitBlock temp6 = simd_andc(temp4, temp5);
345        BitBlock temp7 = simd_and(temp3, temp6);
346        BitBlock temp8 = simd_andc(bit[3], bit[2]);
347        BitBlock temp9 = simd_and(temp1, temp8);
348        BitBlock temp10 = simd_or(bit[4], bit[5]);
349        BitBlock temp11 = simd_or(temp10, temp5);
350        BitBlock temp12 = simd_andc(temp9, temp11);
351        LexItem[MarkupStart] = simd_or(temp7, temp12);
352        BitBlock temp13 = simd_andc(bit[2], bit[3]);
353        BitBlock temp14 = simd_and(temp1, temp13);
354        BitBlock temp15 = simd_andc(bit[6], bit[7]);
355        BitBlock temp16 = simd_and(temp4, temp15);
356        BitBlock RAngle = simd_and(temp14, temp16);
357        BitBlock temp17 = simd_andc(bit[0], bit[1]);
358        BitBlock temp18 = simd_and(bit[2], bit[3]);
359        BitBlock temp19 = simd_and(temp17, temp18);
360        BitBlock temp20 = simd_andc(bit[4], bit[5]);
361        BitBlock temp21 = simd_and(bit[6], bit[7]);
362        BitBlock temp22 = simd_and(temp20, temp21);
363        BitBlock RBracket = simd_and(temp19, temp22);
364        LexItem[Hyphen] = simd_andc(temp14, temp11);
365        BitBlock temp23 = simd_and(temp4, temp21);
366        LexItem[QMark] = simd_and(temp14, temp23);
367        BitBlock temp24 = simd_and(temp1, temp18);
368        BitBlock temp25 = simd_and(temp4, bit[7]);
369        BitBlock temp26 = simd_and(temp24, temp25);
370        BitBlock temp27 = simd_or(temp26, temp7);
371        LexItem[Quote] = simd_or(temp27, temp12);
372        BitBlock temp28 = simd_and(temp1, bit[3]);
373        BitBlock temp29 = simd_and(temp16, temp28);
374        BitBlock temp30 = simd_andc(bit[7], bit[6]);
375        BitBlock temp31 = simd_andc(temp30, temp10);
376        BitBlock temp32 = simd_and(temp14, temp31);
377        BitBlock temp33 = simd_or(temp29, temp32);
378        BitBlock temp34 = simd_or(temp33, RAngle);
379        LexItem[NameFollow] = simd_or(temp34, LexItem[QMark]);
380       
381        /* Mark potential occurrences of ']]>'  These are all actual
382        occurrences of ]]> as well as occurrences of ]] or ] at
383        the block end. Shifting the RBracket and RAngle streams in
384        negated forms ensures that a potential CD_End is not ruled
385        out at the block boundary. */
386        LexItem[CD_End_check] = simd_andc(RBracket, 
387                                          simd_or(sisd_sbli(simd_not(RBracket), 1),
388                                                  sisd_sbli(simd_not(RAngle), 2)));
389#ifndef OMIT_CD_End_check_In_Markup_Scan
390        LexItem[MarkupStart] = simd_or(LexItem[MarkupStart], LexItem[CD_End_check]);
391#endif
392}
393
394
395/* A temporary structure for internal use in ComputeLexicalItemStreams. */
396typedef struct {
397        BitBlock LexicalItems[LexicalItemCount];
398} LexicalItemBlock;
399
400
401
402
403template <CodeUnit_Base C>
404void Lexer<C>::Do_MarkupStreams() {
405        LexicalItemBlock lx_blk[BUFFER_BLOCKS];
406        for (int i = 0; i < buffer_blocks; i++) {
407                ComputeLexicalItemBlocks<C>(x8basis[i].bit, lx_blk[i].LexicalItems);
408        }
409#ifdef BUFFER_PROFILING
410        end_BOM_interval(bitstream_timer);
411        start_BOM_interval(lextranspose_timer);
412#endif
413        for (int j = MarkupStart; j < LexicalItemCount; j++) {
414                for (int i = 0; i < buffer_blocks; i++) {
415                        parsing_engine_data->item_stream[j][i] = lx_blk[i].LexicalItems[j];
416                }
417        }
418        for (int i = 0; i < buffer_blocks; i++) {
419                parsing_engine_data->item_stream[NameFollow][i] = 
420                        simd_or(parsing_engine_data->item_stream[NameFollow][i],
421                                simd_not(parsing_engine_data->item_stream[NonWS][i]));
422        }
423#ifdef BUFFER_PROFILING
424        end_BOM_interval(lextranspose_timer);
425        start_BOM_interval(scanner_timer);
426#endif
427};
428
429
430/* Stub out Charset Validation initially. */
431
432void UTF_8_Lexer::Do_CharsetValidation() {
433        //printf("UTF_8_Lexer::Do_CharsetValidation not yet implemented; assuming OK.\n");
434};
435
436
437void ASCII_7_Lexer::Do_CharsetValidation() {
438        BitBlock Restricted = simd_const_1(0);
439        for (int blk = 0; blk < buffer_blocks; blk++) {
440                Restricted = simd_or(Restricted, x8basis[blk].bit[0]);
441        }
442        if (bitblock_has_bit(Restricted)) {
443                printf("Illegal non-ASCII character in input for ASCII document.\n");
444                exit(-1);
445        }
446};
447
448
449void EASCII_8_Lexer::Do_CharsetValidation() {
450        /* Nothing required for most charsets - but perhaps should have tables. */
451};
452
453
454void UTF_16_Lexer::Do_CharsetValidation() {
455#ifdef X16HILO_ACCESS
456        int packs = (buffer_units - 1)/PACKSIZE + 1;
457        BytePack surrogate_select;
458        BytePack hi_surrogate;
459        BytePack lo_surrogate;
460        BytePack hi_surrogate_pending = simd_const_8(0);
461        BytePack surrogate_scope;
462        BytePack u16_surrogate_accum = simd_const_8(0);
463        BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
464        BytePack u16_FFFE_FFFF;
465        for (int pk = 0; pk < packs; pk++) {
466                /* UTF-16 code units in the range D800-DBFF and DC00-DFFF are
467                   reserved for the first and second elements, respectively
468                   of surrogate pairs.  Validation requires that these values
469                   only occur in well-formed pairs. */
470                surrogate_select = simd_and(x16hi[pk], simd_const_8(0xDC));
471                hi_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xD8));
472                lo_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xDC));
473                surrogate_scope = simd_or(hi_surrogate_pending,
474                                          sisd_sfli(hi_surrogate, 8));
475                u16_surrogate_accum = simd_or(u16_surrogate_accum,
476                                              simd_xor(surrogate_scope, lo_surrogate));
477                hi_surrogate_pending = sisd_sbli(hi_surrogate, 8 * (PACKSIZE-1));
478                /* The values FFFE and FFFF are excluded. */
479                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
480                                                   simd_or(x16lo[pk], simd_const_8(1))),
481                                          simd_const_8(0xFF));
482                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
483        }
484        u16_surrogate_accum = simd_or(u16_surrogate_accum, hi_surrogate_pending);
485        if (bitblock_has_bit(simd_or(u16_surrogate_accum, u16_FFFE_FFFF_accum)))
486                printf("UTF-16 validation error.\n");
487                exit(-1);
488        }
489#endif
490#ifndef X16HILO_ACCESS
491        printf("UTF_16_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
492#endif
493};
494
495
496void UCS_2_Lexer::Do_CharsetValidation() {
497#ifdef X16HILO_ACCESS
498        int packs = (buffer_units - 1)/PACKSIZE + 1;
499        BytePack u16_surrogate_accum = simd_const_8(0);
500        BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
501        BytePack u16_FFFE_FFFF;
502        for (int pk = 0; pk < packs; pk++) {
503                /* The high byte of UCS-2 code units cannot be in the range D8-DF.
504                   This corresponds to the D800-DFFF range of illegal codepoints
505                   reserved for UTF-16 surrogate pairs. Accumulate the results.
506                   To check, 0x20 is added to each such octet, mapping the D8-DF
507                   range to F8-FF and wrapping E0-FF values around.  The max value
508                   is then accumulated.  */
509                u16_surrogate_accum =
510                        simd_max_8(u16_surrogate_accum, 
511                                   simd_add_8(x16hi[pk], simd_const_8(0x20)));
512                /* The values FFFE and FFFF are excluded. */
513                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
514                                                   simd_or(x16lo[pk], simd_const_8(1))),
515                                          simd_const_8(0xFF));
516                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
517        }
518        u16_surrogate_accum = simd_eq_8(simd_or(u16_surrogate_accum, simd_const_8(0x07)),
519                                        simd_const_8(0xFF));
520        if (bitblock_has_bit(simd_or(u16_surrogate_accum, u16_FFFE_FFFF_accum)))
521                printf("UCS-2 validation error.\n");
522                exit(-1);
523        }
524#endif
525#ifndef X16HILO_ACCESS
526        printf("UCS_2_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
527#endif
528};
529
530
531void UTF_32_Lexer::Do_CharsetValidation() {
532#ifdef X32BYTEPLEX_ACCESS
533        int packs = (buffer_units - 1)/PACKSIZE + 1;
534        BytePack u32hh_accum = simd_const_8(0);
535        BytePack u32hl_accum = simd_const_8(0);
536        BytePack u32_surrogate_accum = simd_const_8(0);
537        BytePack u32_FFFE_FFFF_accum = simd_const_8(0);
538        BytePack u32_BMP_select;
539        BytePack u32l_FFFE_FFFF;
540        for (int pk = 0; pk < packs; pk++) {
541                /* There can be no bits set in the high octet; "or" together
542                   all octet values to check for any bit set. */
543                u32hh_accum = simd_or(u32hh_accum, x32hh[pk]);
544                /* The second octet has a max value of 0x10, corresponding to the
545                   maximum Unicode code point value of 0x10FFFF.  Accumulate the
546                   maximum of all u32hl values observed. */ 
547                u32hl_accum = simd_max_8(u32hl_accum, x32hl[pk]);
548                /* The third octet cannot be in the range D8-DF if the second octet
549                   is 0.  This corresponds to the D800-DFFF range of illegal codepoints
550                   reserved for UTF-16 surrogate pairs. Accumulate the results.
551                   To check, 0x20 is added to each such octet, mapping the D8-DF
552                   range to F8-FF and wrapping E0-FF values around.  The max value
553                   is then accumulated.  */
554                u32_BMP_select = simd_eq_8(x32hl[pk], simd_const_8(0));
555                u32_surrogate_accum = 
556                        simd_max_8(u32_surrogate_accum, 
557                                   simd_and(u32_BMP_select,
558                                            simd_add_8(x32lh[pk], simd_const_8(0x20))));
559                /* The low two octets cannot have the value FFFE or FFFF if
560                   we're in the BMP (second octet is 0). */
561                u32l_FFFE_FFFF = simd_eq_8(simd_and(x32lh[pk],
562                                                    simd_or(x32ll[pk], simd_const_8(1))),
563                                           simd_const_8(0xFF));
564                u32_FFFE_FFFF_accum = simd_or(u32_FFFE_FFFF_accum,
565                                              simd_and(u32_BMP_select, u32l_FFFE_FFFF));
566        }
567        u32hl_accum = simd_gt_8(u32hl_accum, simd_const_8(0x10));
568        u32_surrogate_accum = simd_eq_8(simd_or(u32_surrogate_accum, simd_const_8(0x07)),
569                                        simd_const_8(0xFF));
570        if (bitblock_has_bit(simd_or(simd_or(u32hh_accum, u32hl_accum),
571                                         simd_or(u32_surrogate_accum, u32_FFFE_FFFF_accum)))) {
572                printf("UTF-32 validation error.\n");
573                exit(-1);
574        }
575#endif
576#ifndef X32BYTEPLEX_ACCESS
577        printf("UTF_32_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
578#endif
579};
580
581
582void EBCDIC_Lexer::Do_CharsetValidation() {
583        /* Nothing required for most cases - but perhaps should have tables. */
584};
585
586
587
588
589/* Stub out XML 1.1 routines initially. */
590
591void UTF_8_Lexer::Do_XML_11_WS_Control() {
592        printf("UTF_8_Lexer::Do_XML_11_WS_Control not yet implemented; using XML 1.0 rules.\n");
593        Do_XML_10_WS_Control();
594};
595
596
597static inline void ASCII_7_WS_Control_Blocks_11(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
598        BitBlock temp1 = simd_or(bit[0], bit[1]);
599        BitBlock temp2 = simd_or(temp1, bit[2]);
600        BitBlock temp3 = simd_andc(bit[1], bit[0]);
601        BitBlock temp4 = simd_and(bit[2], bit[3]);
602        BitBlock temp5 = simd_and(temp3, temp4);
603        BitBlock temp6 = simd_and(bit[4], bit[5]);
604        BitBlock temp7 = simd_and(bit[6], bit[7]);
605        BitBlock temp8 = simd_and(temp6, temp7);
606        BitBlock temp9 = simd_and(temp5, temp8);
607        BitBlock temp10 = simd_andc(temp2, temp9);
608        BitBlock temp11 = simd_andc(temp10, bit[0]);
609        Control = simd_andc(simd_const_1(1), temp11);
610        BitBlock temp12 = simd_or(bit[2], bit[3]);
611        BitBlock temp13 = simd_or(temp1, temp12);
612        BitBlock temp14 = simd_andc(bit[7], bit[6]);
613        BitBlock temp15 = simd_and(temp6, temp14);
614        BitBlock CR = simd_andc(temp15, temp13);
615        BitBlock temp16 = simd_andc(bit[4], bit[5]);
616        BitBlock temp17 = simd_andc(bit[6], bit[7]);
617        BitBlock temp18 = simd_and(temp16, temp17);
618        BitBlock LF = simd_andc(temp18, temp13);
619        BitBlock temp19 = simd_and(temp16, temp14);
620        BitBlock HT = simd_andc(temp19, temp13);
621        BitBlock temp20 = simd_andc(bit[2], bit[3]);
622        BitBlock temp21 = simd_andc(temp20, temp1);
623        BitBlock temp22 = simd_or(bit[4], bit[5]);
624        BitBlock temp23 = simd_or(bit[6], bit[7]);
625        BitBlock temp24 = simd_or(temp22, temp23);
626        BitBlock SP = simd_andc(temp21, temp24);
627        WS = simd_or(simd_or(CR, LF), simd_or(HT, SP));
628}
629
630
631void ASCII_7_Lexer::Do_XML_11_WS_Control() {
632        BitBlock Restricted = simd_const_1(0);
633        BitBlock Control = simd_const_1(0);
634        BitBlock WS = simd_const_1(0);
635        for (int i = 0; i < buffer_blocks; i++) {
636                Restricted = simd_or(Restricted, simd_andc(Control, WS));
637                ASCII_7_WS_Control_Blocks_11(x8basis[i].bit, WS, Control);
638                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
639        }
640        if ((buffer_units % BLOCKSIZE) != 0) 
641                Control = simd_andc(Control,
642                                    sisd_sfl(simd_const_1(1), 
643                                             sisd_from_int(buffer_units % BLOCKSIZE)));
644        Restricted = simd_or(Restricted, simd_andc(Control, WS));
645        if (bitblock_has_bit(Restricted)) {
646                printf("***Restricted control character in input.\n");
647                exit(-1);
648        }
649};
650
651static inline void EASCII_8_WS_Control_Blocks_11(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
652        BitBlock temp1 = simd_or(bit[0], bit[1]);
653        BitBlock temp2 = simd_or(temp1, bit[2]);
654        BitBlock temp3 = simd_andc(bit[1], bit[0]);
655        BitBlock temp4 = simd_and(bit[2], bit[3]);
656        BitBlock temp5 = simd_and(temp3, temp4);
657        BitBlock temp6 = simd_and(bit[4], bit[5]);
658        BitBlock temp7 = simd_and(bit[6], bit[7]);
659        BitBlock temp8 = simd_and(temp6, temp7);
660        BitBlock temp9 = simd_and(temp5, temp8);
661        BitBlock temp10 = simd_andc(temp2, temp9);
662        BitBlock temp11 = simd_andc(bit[0], bit[1]);
663        BitBlock temp12 = simd_andc(temp11, bit[2]);
664        BitBlock temp13 = simd_andc(temp10, temp12);
665        Control = simd_andc(simd_const_1(1), temp13);
666        BitBlock temp14 = simd_or(bit[2], bit[3]);
667        BitBlock temp15 = simd_or(temp1, temp14);
668        BitBlock temp16 = simd_andc(bit[7], bit[6]);
669        BitBlock temp17 = simd_and(temp6, temp16);
670        BitBlock CR = simd_andc(temp17, temp15);
671        BitBlock temp18 = simd_andc(bit[4], bit[5]);
672        BitBlock temp19 = simd_andc(bit[6], bit[7]);
673        BitBlock temp20 = simd_and(temp18, temp19);
674        BitBlock LF = simd_andc(temp20, temp15);
675        BitBlock temp21 = simd_and(temp18, temp16);
676        BitBlock HT = simd_andc(temp21, temp15);
677        BitBlock temp22 = simd_andc(bit[2], bit[3]);
678        BitBlock temp23 = simd_andc(temp22, temp1);
679        BitBlock temp24 = simd_or(bit[4], bit[5]);
680        BitBlock temp25 = simd_or(bit[6], bit[7]);
681        BitBlock temp26 = simd_or(temp24, temp25);
682        BitBlock SP = simd_andc(temp23, temp26);
683        BitBlock temp27 = simd_andc(temp11, temp14);
684        BitBlock temp28 = simd_andc(bit[5], bit[4]);
685        BitBlock temp29 = simd_and(temp28, temp16);
686        BitBlock NEL = simd_and(temp27, temp29);
687        WS = simd_or(simd_or(simd_or(CR, LF), simd_or(HT, SP)), NEL);
688}
689
690void EASCII_8_Lexer::Do_XML_11_WS_Control() {
691        BitBlock Restricted = simd_const_1(0);
692        BitBlock Control = simd_const_1(0);
693        BitBlock WS = simd_const_1(0);
694        for (int i = 0; i < buffer_blocks; i++) {
695                Restricted = simd_or(Restricted, simd_andc(Control, WS));
696                EASCII_8_WS_Control_Blocks_11(x8basis[i].bit, WS, Control);
697                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
698        }
699        if ((buffer_units % BLOCKSIZE) != 0) 
700                Control = simd_andc(Control,
701                                    sisd_sfl(simd_const_1(1), 
702                                             sisd_from_int(buffer_units % BLOCKSIZE)));
703        Restricted = simd_or(Restricted, simd_andc(Control, WS));
704        if (bitblock_has_bit(Restricted)) {
705                printf("***Restricted control character in input.\n");
706                exit(-1);
707        }
708};
709
710
711void U16_Lexer::Do_XML_11_WS_Control() {
712        printf("U16_Lexer::Do_XML_11_WS_Control not yet implemented; using XML 1.0 rules.\n");
713        Do_XML_10_WS_Control();
714};
715
716
717void UTF_32_Lexer::Do_XML_11_WS_Control() {
718        printf("UTF_32_Lexer::Do_XML_11_WS_Control not yet implemented; using XML 1.0 rules.\n");
719        Do_XML_10_WS_Control();
720};
721
722static inline void EBCDIC_WS_Control_Blocks_11(BitBlock bit[], BitBlock& WS, BitBlock& Control) {
723        BitBlock temp1 = simd_or(bit[0], bit[1]);
724        BitBlock temp2 = simd_and(bit[0], bit[1]);
725        BitBlock temp3 = simd_and(bit[2], bit[3]);
726        BitBlock temp4 = simd_and(temp2, temp3);
727        BitBlock temp5 = simd_and(bit[4], bit[5]);
728        BitBlock temp6 = simd_and(bit[6], bit[7]);
729        BitBlock temp7 = simd_and(temp5, temp6);
730        BitBlock temp8 = simd_and(temp4, temp7);
731        BitBlock temp9 = simd_andc(temp1, temp8);
732        Control = simd_andc(simd_const_1(1), temp9);
733        BitBlock temp10 = simd_or(bit[2], bit[3]);
734        BitBlock temp11 = simd_or(temp1, temp10);
735        BitBlock temp12 = simd_andc(bit[7], bit[6]);
736        BitBlock temp13 = simd_and(temp5, temp12);
737        BitBlock CR = simd_andc(temp13, temp11);
738        BitBlock temp14 = simd_andc(bit[2], bit[3]);
739        BitBlock temp15 = simd_andc(temp14, temp1);
740        BitBlock temp16 = simd_andc(bit[5], bit[4]);
741        BitBlock temp17 = simd_and(temp16, temp12);
742        BitBlock LF = simd_and(temp15, temp17);
743        BitBlock HT = simd_andc(temp17, temp11);
744        BitBlock temp18 = simd_andc(bit[1], bit[0]);
745        BitBlock temp19 = simd_andc(temp18, temp10);
746        BitBlock temp20 = simd_or(bit[4], bit[5]);
747        BitBlock temp21 = simd_or(bit[6], bit[7]);
748        BitBlock temp22 = simd_or(temp20, temp21);
749        BitBlock SP = simd_andc(temp19, temp22);
750        BitBlock temp23 = simd_andc(bit[3], bit[2]);
751        BitBlock temp24 = simd_andc(temp23, temp1);
752        BitBlock NEL = simd_and(temp24, temp17);
753        WS = simd_or(simd_or(simd_or(CR, LF), simd_or(HT, SP)), NEL);
754}
755
756void EBCDIC_Lexer::Do_XML_11_WS_Control() {
757        BitBlock Restricted = simd_const_1(0);
758        BitBlock Control = simd_const_1(0);
759        BitBlock WS = simd_const_1(0);
760        for (int i = 0; i < buffer_blocks; i++) {
761                Restricted = simd_or(Restricted, simd_andc(Control, WS));
762                EBCDIC_WS_Control_Blocks_11(x8basis[i].bit, WS, Control);
763                parsing_engine_data->item_stream[NonWS][i] = simd_not(WS);
764        }
765        if ((buffer_units % BLOCKSIZE) != 0) 
766                Control = simd_andc(Control,
767                                    sisd_sfl(simd_const_1(1), 
768                                             sisd_from_int(buffer_units % BLOCKSIZE)));
769        Restricted = simd_or(Restricted, simd_andc(Control, WS));
770        if (bitblock_has_bit(Restricted)) {
771                printf("***Restricted control character in input.\n");
772                exit(-1);
773        }
774};
775
776
777
778#include "transpose.h"
779
780void Lexer_Interface::TransposeToBitStreams() {
781        BytePack * pseudoASCII_src = &(xml_buf->x8data[lexer_base_pos/PACKSIZE]);
782        for (int blk = 0; blk < buffer_blocks; blk++) {
783                s2p_bytepack(&pseudoASCII_src[blk*8], x8basis[blk].bit);
784        }
785}
786
787void Lexer_Interface::AdvanceBuffer(int& base_pos, int& rel_pos, int& limit_pos) {
788        BitBlock final_block_mask;
789#ifdef DEBUG
790        printf("AdvanceBuffer entry.\n");
791#endif
792        int abspos = base_pos + rel_pos;
793        lexer_base_pos = abspos & (-PACKSIZE); /* align the base_position for lexer*/
794        buffer_units = xml_buf->AvailableUnits(lexer_base_pos);
795#ifdef DEBUG
796        printf("buffer_units = %i.\n", buffer_units);
797#endif
798        if (buffer_units >= BUFFER_SIZE) {
799                buffer_units = BUFFER_SIZE;
800                final_block_mask = simd_const_1(0);
801        }
802        else {
803                final_block_mask = 
804                        sisd_sfl(simd_const_1(1), sisd_from_int(buffer_units % BLOCKSIZE));
805        }
806        buffer_blocks = (buffer_units -1)/BLOCKSIZE + 1;
807#ifdef DEBUG
808        printf("Transpose for abspos = %i, lexer_base_pos= %i, buffer_blocks = %i.\n", abspos, lexer_base_pos, buffer_blocks);
809#endif
810
811        TransposeToBitStreams();
812#ifdef DEBUG
813        printf("Transposition to bit streams complete.\n");
814#endif
815        if (xml_buf->version == XML_1_1) Do_XML_11_WS_Control();
816        else Do_XML_10_WS_Control();
817        Do_MarkupStreams();
818#ifdef DEBUG
819        printf("Markup streams complete.\n");
820#endif
821        Do_CharsetValidation();
822#ifdef DEBUG
823        printf("Validation complete.\n");
824#endif
825        if (buffer_units < BUFFER_SIZE) {
826                int lastblk = buffer_units/BLOCKSIZE;
827                for (int j = minLexicalItem; j < LexicalItemCount; j++) {
828                        parsing_engine_data->item_stream[j][lastblk] =
829                                simd_or(parsing_engine_data->item_stream[j][lastblk],
830                                        final_block_mask);
831                }
832        }
833        /* Update parser control variables. */
834        base_pos = lexer_base_pos;
835        rel_pos = abspos - lexer_base_pos;
836        limit_pos = buffer_units;
837}
838
Note: See TracBrowser for help on using the repository browser.