source: OGRE/trunk/ogrenew/RenderSystems/GL/src/nvparse/vs1.0_inst.cpp @ 692

Revision 692, 44.0 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1#ifdef WIN32
2#pragma warning(disable:4786)
3#endif
4#include "vs1.0_inst.h"
5#include <stdio.h>
6#include <string>
7#include <map>
8#include "nvparse_errors.h"
9#include "nvparse_externs.h"
10
11std::string vs10_transstring;
12
13#if 0
14VS10Reg::VS10Reg()
15{
16    type = 0;
17    index = 0;
18        sign = 0;
19    mask = 0;
20}
21
22VS10Reg::VS10Reg(const VS10Reg &r)
23{
24    type = r.type;
25    index = r.index;
26        sign = r.sign;
27    mask = r.mask;
28}
29
30VS10Reg& VS10Reg::operator=(const VS10Reg &r)
31{
32    if ( this != &r )
33    {
34        type = r.type;
35        index = r.index;
36                sign = r.sign;
37        mask = r.mask;
38    }
39    return *this;
40}
41#endif
42
43void VS10Reg::Init()
44{
45    type = 0;
46    index = -1;
47    sign = 0;
48    mask[0] = 'j';
49    mask[1] = 'j';
50    mask[2] = 'j';
51    mask[3] = 'j';
52}
53
54int VS10Reg::ValidateIndex()
55{
56    switch( type )
57    {
58    case TYPE_TEMPORARY_REG:
59        if ( index < 0 || index > 11 ) return 0;
60        else return 1;
61        break;
62    case TYPE_VERTEX_ATTRIB_REG:
63        if ( index < 0 || index > 15 ) return 0;
64        else return 1;
65        break;
66    case TYPE_ADDRESS_REG:       
67        if ( index != 0 ) return 0;
68        else return 1;
69        break;
70    case TYPE_CONSTANT_MEM_REG:
71        if ( index < 0 || index > 95 ) return 0;
72        else return 1;
73        break;
74    case TYPE_CONSTANT_A0_REG:
75    case TYPE_CONSTANT_A0_OFFSET_REG:
76        return 1;
77        break;
78    case TYPE_POSITION_RESULT_REG:
79        return 1;
80        break;
81    case TYPE_COLOR_RESULT_REG:
82        if ( index < 0 || index > 1 ) return 0;
83        else return 1;
84        break;
85    case TYPE_TEXTURE_RESULT_REG:
86        if ( index < 0 || index > 3 ) return 0;
87        else return 1;
88        break;
89    case TYPE_FOG_RESULT_REG:
90        return 1;
91        break;
92    case TYPE_POINTS_RESULT_REG:
93        return 1;
94        break;
95    default:
96        errors.set( "VS10Reg::ValidateIndex() Internal Error: unknown register type\n" );
97        return 1;
98    }
99}
100
101void VS10Reg::Translate()
102{
103    char str[16];
104
105    if ( sign == -1 )
106        vs10_transstring.append( "-" );
107   
108    switch ( type )
109    {
110    case TYPE_TEMPORARY_REG:
111        sprintf( str, "R%d", index );
112        vs10_transstring.append( str );
113        break;
114    case TYPE_VERTEX_ATTRIB_REG:
115        sprintf( str, "v[%d]", index );
116        vs10_transstring.append( str );
117        break;
118    case TYPE_ADDRESS_REG:       
119        sprintf( str, "A%d", index );
120        vs10_transstring.append( str );
121        break;
122    case TYPE_CONSTANT_MEM_REG:
123        sprintf( str, "c[%d]", index );
124        vs10_transstring.append( str );
125        break;
126    case TYPE_CONSTANT_A0_REG:
127        vs10_transstring.append( "c[ A0.x ]" );
128        break;
129    case TYPE_CONSTANT_A0_OFFSET_REG:
130        sprintf( str, "c[ A0.x + %d ]", index );
131        vs10_transstring.append( str );
132        break;
133    case TYPE_POSITION_RESULT_REG:
134        vs10_transstring.append( "o[HPOS]" );
135        break;
136    case TYPE_COLOR_RESULT_REG:
137        sprintf( str, "o[COL%d]", index );
138        vs10_transstring.append( str );
139        break;
140    case TYPE_TEXTURE_RESULT_REG:
141        sprintf( str, "o[TEX%d]", index );
142        vs10_transstring.append( str );
143        break;
144    case TYPE_FOG_RESULT_REG:
145        vs10_transstring.append( "o[FOGC]" );
146        break;
147    case TYPE_POINTS_RESULT_REG:
148        vs10_transstring.append( "o[PSIZ]" );
149        break;
150    default:
151        errors.set( "VS10Reg::Translate() Internal Error: unknown register type\n" );
152    }
153
154    if ( mask[0] != 0 )
155    {
156        str[0] = '.';
157        strncpy( str+1, mask, 4 );
158        str[5] = 0;
159        vs10_transstring.append( str );
160    }
161}
162
163VS10Inst::~VS10Inst()
164{
165    if (comment != NULL ) delete [] comment;
166}
167
168VS10Inst::VS10Inst()
169{
170    line = -1;
171    instid = -1;
172    dst.Init();
173    src[0].Init();
174    src[1].Init();
175    src[2].Init();
176    comment = NULL;
177}
178
179VS10Inst::VS10Inst( int currline )
180{
181    line = currline;
182    instid = -1;
183    dst.Init();
184    src[0].Init();
185    src[1].Init();
186    src[2].Init();
187    comment = NULL;
188}
189
190VS10Inst::VS10Inst( const VS10Inst &inst )
191{
192    line = inst.line;
193    instid = inst.instid;
194    dst = inst.dst;
195    src[0] = inst.src[0];
196    src[1] = inst.src[1];
197    src[2] = inst.src[2];
198    if ( inst.comment == NULL )
199        comment = NULL;
200    else
201    {
202        comment = new char[strlen(inst.comment)+1];
203        strcpy( comment, inst.comment );
204    }
205}
206
207VS10Inst& VS10Inst::operator=(const VS10Inst &inst)
208{
209    if ( this != &inst )
210    {
211        line = inst.line;
212        instid = inst.instid;
213        dst = inst.dst;
214        src[0] = inst.src[0];
215        src[1] = inst.src[1];
216        src[2] = inst.src[2];
217        if ( inst.comment == NULL )
218            comment = NULL;
219        else
220        {
221            comment = new char[strlen(inst.comment)+1];
222            strcpy( comment, inst.comment );
223        }
224    }
225    return *this;
226}
227
228
229VS10Inst::VS10Inst(int currline, int inst)
230{
231    line = currline;
232    instid = inst;
233    dst.Init();
234    src[0].Init();
235    src[1].Init();
236    src[2].Init();
237    comment = NULL;
238}
239
240VS10Inst::VS10Inst(int currline, int inst, char *cmt)
241{
242    line = currline;
243    instid = inst;
244    dst.Init();
245    src[0].Init();
246    src[1].Init();
247    src[2].Init();
248    comment = cmt;
249}
250
251VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0)
252{
253    line = currline;
254        instid = inst;
255        dst = dreg;
256    src[0] = src0;
257    src[1].Init();
258    src[2].Init();
259    comment = NULL;
260}
261
262VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1)
263{
264    line = currline;
265        instid = inst;
266        dst = dreg;
267    src[0] = src0;
268    src[1] = src1;
269    src[2].Init();
270    comment = NULL;
271}
272
273VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2)
274{
275    line = currline;
276        instid = inst;
277        dst = dreg;
278    src[0] = src0;
279    src[1] = src1;
280    src[2] = src2;
281    comment = NULL;
282}
283
284void VS10Inst::Validate( int &vsflag )
285{
286
287    // Handle comments, noops, and newlines.
288    if ( instid == VS10_COMMENT || instid == VS10_NOP || instid == -1 ) return;
289
290    // Handle the header case.
291    if ( instid == VS10_HEADER )
292    {
293        if ( vsflag == 0 )
294        {
295            vsflag = 1;
296            return;
297        }
298        else
299        {
300            char temp[128];
301            sprintf( temp, "(%d) Error: vs.1.0 token already encountered\n", line );
302            errors.set( temp );
303            return;
304        }
305    }
306
307    // Validate register indices are valid.
308    ValidateRegIndices();
309
310    // Verify destination masking is valid.
311    ValidateDestMask();
312
313    // Verify source swizzling is valid.
314    ValidateSrcMasks();
315
316    // Verify destination register is writable.
317    ValidateDestWritable();
318
319    // Verify source registers are readable.
320    ValidateSrcReadable();
321
322    // Verify not reading from multiple vertex attributes or constants
323    ValidateReadPorts();
324}
325
326void VS10Inst::ValidateRegIndices()
327{
328    char temp[256];
329    int result;
330
331    // Destination register.
332    result = dst.ValidateIndex();
333    if ( !result )
334    {
335        sprintf( temp, "(%d) Error: destination register index out of range\n", line );
336        errors.set( temp );
337    }
338
339    // Source register.
340    result = src[0].ValidateIndex();
341    if ( !result )
342    {
343        sprintf( temp, "(%d) Error: source register index out of range\n", line );
344        errors.set( temp );
345    }
346
347    switch( instid )
348    {
349        // Vector operations.
350        case VS10_MOV:
351        case VS10_LIT:
352            break;
353
354        // Unary operations.
355        case VS10_FRC:
356            break;
357
358        // Scalar operations.
359        case VS10_EXP:
360        case VS10_EXPP:
361        case VS10_LOG:
362        case VS10_LOGP:
363        case VS10_RCP:
364        case VS10_RSQ:
365            break;
366       
367        // Binary operations.
368        case VS10_ADD:
369        case VS10_DP3:
370        case VS10_DP4:
371        case VS10_DST:
372        case VS10_SGE:
373        case VS10_SLT:
374        case VS10_SUB:
375        case VS10_MAX:
376        case VS10_MIN:
377        case VS10_MUL:
378            result = src[1].ValidateIndex();
379            if ( !result )
380            {
381                sprintf( temp, "(%d) Error: second source register index out of range\n", line );
382                errors.set( temp );
383            }
384            break;
385
386        case VS10_M3X2:
387        case VS10_M3X3:
388        case VS10_M3X4:
389        case VS10_M4X3:
390        case VS10_M4X4:
391            {
392                result = src[1].ValidateIndex();
393                if ( !result )
394                {
395                    sprintf( temp, "(%d) Error: second source register index out of range\n", line );
396                    errors.set( temp );
397                }
398                int orig;
399                orig = src[1].index;
400                switch( instid )
401                {
402                    case VS10_M3X2:
403                        src[1].index = src[1].index + 1;
404                        break;
405                    case VS10_M3X3:
406                    case VS10_M4X3:
407                        src[1].index = src[1].index + 2;
408                        break;
409                    case VS10_M3X4:
410                    case VS10_M4X4:
411                        src[1].index = src[1].index + 3;
412                        break;
413                }
414                result = src[1].ValidateIndex();
415                src[1].index = orig;
416                if ( !result )
417                {
418                    sprintf( temp, "(%d) Error: macro expansion produces source register index out of range\n", line );
419                    errors.set( temp );
420                }
421            }
422            break;
423
424        // Trinary operations.
425        case VS10_MAD:
426            result = src[1].ValidateIndex();
427            if ( !result )
428            {
429                sprintf( temp, "(%d) Error: second source register index out of range\n", line );
430                errors.set( temp );
431            }
432            result = src[2].ValidateIndex();
433            if ( !result )
434            {
435                sprintf( temp, "(%d) Error: third source register index out of range\n", line );
436                errors.set( temp );
437            }
438            break;
439        default:
440            errors.set( "VS10Inst::ValidateRegIndices() Internal Error: unknown instruction type\n" );
441            break;
442    }
443}
444
445void VS10Inst::ValidateDestMask()
446{
447    char temp[256];
448    typedef std::map<char, int> MyMap;
449    typedef MyMap::value_type MyPair;
450    static const MyPair pairs[] =
451    {
452        MyPair('x',1),
453        MyPair('y',2),
454        MyPair('z',3),
455        MyPair('w',4),
456    };
457    static const MyMap swizzleMap(pairs, pairs+(sizeof(pairs)/sizeof(pairs[0])));
458
459    if ( dst.mask[0] == 0 ) return;
460    int i = 1;
461    while ( i < 4 && dst.mask[i] != 0 )
462    {
463        MyMap::const_iterator lastMaskIt = swizzleMap.find(dst.mask[i-1]);
464        MyMap::const_iterator curMaskIt = swizzleMap.find(dst.mask[i]);
465        if (lastMaskIt == swizzleMap.end() || curMaskIt == swizzleMap.end() ||
466            lastMaskIt->second >= curMaskIt->second)
467//        if ( dst.mask[i-1] >= dst.mask[i] )
468        {
469            char mask[5];
470            strncpy( mask, dst.mask, 4 );
471            mask[4] = 0;
472            sprintf( temp, "(%d) Error: destination register has invalid mask: %s\n", line, mask );
473            errors.set( temp );
474            break;
475        }
476        i++;
477    }
478}
479
480void VS10Inst::ValidateSrcMasks()
481{
482    char temp[256];
483    char mask[5];
484    int len;
485    int i;
486
487    switch( instid )
488    {
489        // Vector operations.
490        case VS10_MOV:
491        case VS10_LIT:
492            strncpy( mask, src[0].mask, 4 );
493            mask[4] = 0;
494            len = strlen( mask );
495            if ( len != 1 )
496            {
497                for ( i = len; i < 4; i++ )
498                    src[0].mask[i] = src[0].mask[len-1];
499            }
500            break;
501
502        // Unary operations.
503        case VS10_FRC:
504            strncpy( mask, src[0].mask, 4 );
505            mask[4] = 0;
506            len = strlen( mask );
507            if ( len != 1 )
508            {
509                for ( i = len; i < 4; i++ )
510                    src[0].mask[i] = src[0].mask[len-1];
511            }
512            break;
513
514        // Scalar operations.
515        case VS10_EXP:
516        case VS10_EXPP:
517        case VS10_LOG:
518        case VS10_LOGP:
519            strncpy( mask, src[0].mask, 4 );
520            mask[4] = 0;
521            len = strlen( mask );
522            if( len != 1 )
523            {
524                sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
525                errors.set( temp );
526            }
527            break;
528
529        case VS10_RCP:
530        case VS10_RSQ:
531            strncpy( mask, src[0].mask, 4 );
532            mask[4] = 0;
533            len = strlen( mask );
534            if( len != 0 && len != 1 )
535            {
536                sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
537                errors.set( temp );
538            }
539            if ( len == 0 )
540            {
541                strcpy( src[0].mask, "w" );
542            }
543            break;
544       
545        // Binary operations.
546        case VS10_ADD:
547        case VS10_DP3:
548        case VS10_DP4:
549        case VS10_DST:
550        case VS10_SGE:
551        case VS10_SLT:
552        case VS10_SUB:
553        case VS10_M3X2:
554        case VS10_M3X3:
555        case VS10_M3X4:
556        case VS10_M4X3:
557        case VS10_M4X4:
558        case VS10_MAX:
559        case VS10_MIN:
560        case VS10_MUL:
561            strncpy( mask, src[0].mask, 4 );
562            mask[4] = 0;
563            len = strlen( mask );
564            if ( len != 0 && len != 1 )
565            {
566                for ( i = len; i < 4; i++ )
567                    src[0].mask[i] = src[0].mask[len-1];
568            }
569            strncpy( mask, src[1].mask, 4 );
570            mask[4] = 0;
571            len = strlen( mask );
572            if ( len != 0 && len != 1 )
573            {
574                for ( i = len; i < 4; i++ )
575                    src[1].mask[i] = src[1].mask[len-1];
576            }
577            break;
578
579        // Trinary operations.
580        case VS10_MAD:
581            strncpy( mask, src[0].mask, 4 );
582            mask[4] = 0;
583            len = strlen( mask );
584            if ( len != 0 && len != 1 )
585            {
586                for ( i = len; i < 4; i++ )
587                    src[0].mask[i] = src[0].mask[len-1];
588            }
589            strncpy( mask, src[1].mask, 4 );
590            mask[4] = 0;
591            len = strlen( mask );
592            if ( len != 0 && len != 1 )
593            {
594                for ( i = len; i < 4; i++ )
595                    src[1].mask[i] = src[1].mask[len-1];
596            }
597            strncpy( mask, src[2].mask, 4 );
598            mask[4] = 0;
599            len = strlen( mask );
600            if ( len != 0 && len != 1 )
601            {
602                for ( i = len; i < 4; i++ )
603                    src[2].mask[i] = src[2].mask[len-1];
604            }
605            break;
606        default:
607            errors.set( "VS10Inst::ValidateSrcMasks() Internal Error: unknown instruction type\n" );
608            break;
609    }
610}
611
612void VS10Inst::ValidateDestWritable()
613{
614    char temp[256];
615
616    switch ( dst.type )
617    {
618        case TYPE_TEMPORARY_REG:
619        case TYPE_POSITION_RESULT_REG:
620        case TYPE_COLOR_RESULT_REG:
621        case TYPE_TEXTURE_RESULT_REG:
622        case TYPE_FOG_RESULT_REG:
623        case TYPE_POINTS_RESULT_REG:
624            break;
625        case TYPE_VERTEX_ATTRIB_REG:
626        case TYPE_CONSTANT_MEM_REG:
627        case TYPE_CONSTANT_A0_REG:
628        case TYPE_CONSTANT_A0_OFFSET_REG:
629            sprintf( temp, "(%d) Error: destination register is not writable\n", line );
630            errors.set( temp );
631            break;
632        case TYPE_ADDRESS_REG:
633            if ( instid != VS10_MOV )
634            {
635                sprintf( temp, "(%d) Error: destination register is not writable using this instruction\n", line );
636                errors.set( temp );
637            }
638            break;
639        default:
640            errors.set( "VS10Inst::ValidateDestWritable() Internal Error: unknown register type\n" );
641    }
642
643    if ( instid == VS10_FRC && dst.type != TYPE_TEMPORARY_REG )
644    {
645        sprintf( temp, "(%d) Error: destination register must be a temporary register\n", line );
646        errors.set( temp );
647    }
648}
649
650void VS10Inst::ValidateSrcReadable()
651{
652    char temp[256];
653
654    // Source register.
655    switch( src[0].type )
656    {
657        case TYPE_TEMPORARY_REG:
658        case TYPE_VERTEX_ATTRIB_REG:
659        case TYPE_CONSTANT_MEM_REG:
660        case TYPE_CONSTANT_A0_REG:
661        case TYPE_CONSTANT_A0_OFFSET_REG:
662            break;
663        case TYPE_ADDRESS_REG:
664        case TYPE_POSITION_RESULT_REG:
665        case TYPE_COLOR_RESULT_REG:
666        case TYPE_TEXTURE_RESULT_REG:
667        case TYPE_FOG_RESULT_REG:
668        case TYPE_POINTS_RESULT_REG:
669            sprintf( temp, "(%d) Error: source register is not readable\n", line );
670            errors.set( temp );
671            break;
672        default:
673            errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
674    }
675   
676    switch( instid )
677    {
678        // Vector operations.
679        case VS10_MOV:
680        case VS10_LIT:
681            break;
682
683        // Unary operations.
684        case VS10_FRC:
685            break;
686
687        // Scalar operations.
688        case VS10_EXP:
689        case VS10_EXPP:
690        case VS10_LOG:
691        case VS10_LOGP:
692        case VS10_RCP:
693        case VS10_RSQ:
694            break;
695       
696        // Binary operations.
697        case VS10_ADD:
698        case VS10_DP3:
699        case VS10_DP4:
700        case VS10_DST:
701        case VS10_SGE:
702        case VS10_SLT:
703        case VS10_SUB:
704        case VS10_M3X2:
705        case VS10_M3X3:
706        case VS10_M3X4:
707        case VS10_M4X3:
708        case VS10_M4X4:
709        case VS10_MAX:
710        case VS10_MIN:
711        case VS10_MUL:
712            switch( src[1].type )
713            {
714                case TYPE_TEMPORARY_REG:
715                case TYPE_VERTEX_ATTRIB_REG:
716                case TYPE_CONSTANT_MEM_REG:
717                case TYPE_CONSTANT_A0_REG:
718                case TYPE_CONSTANT_A0_OFFSET_REG:
719                    break;
720                case TYPE_ADDRESS_REG:
721                case TYPE_POSITION_RESULT_REG:
722                case TYPE_COLOR_RESULT_REG:
723                case TYPE_TEXTURE_RESULT_REG:
724                case TYPE_FOG_RESULT_REG:
725                case TYPE_POINTS_RESULT_REG:
726                    sprintf( temp, "(%d) Error: second source register is not readable\n", line );
727                    errors.set( temp );
728                    break;
729                default:
730                    errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
731            }
732            break;
733
734        // Trinary operations.
735        case VS10_MAD:
736            switch( src[1].type )
737            {
738                case TYPE_TEMPORARY_REG:
739                case TYPE_VERTEX_ATTRIB_REG:
740                case TYPE_CONSTANT_MEM_REG:
741                case TYPE_CONSTANT_A0_REG:
742                case TYPE_CONSTANT_A0_OFFSET_REG:
743                    break;
744                case TYPE_ADDRESS_REG:
745                case TYPE_POSITION_RESULT_REG:
746                case TYPE_COLOR_RESULT_REG:
747                case TYPE_TEXTURE_RESULT_REG:
748                case TYPE_FOG_RESULT_REG:
749                case TYPE_POINTS_RESULT_REG:
750                    sprintf( temp, "(%d) Error: second source register is not readable\n", line );
751                    errors.set( temp );
752                    break;
753                default:
754                    errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
755            }
756            switch( src[2].type )
757            {
758                case TYPE_TEMPORARY_REG:
759                case TYPE_VERTEX_ATTRIB_REG:
760                case TYPE_CONSTANT_MEM_REG:
761                case TYPE_CONSTANT_A0_REG:
762                case TYPE_CONSTANT_A0_OFFSET_REG:
763                    break;
764                case TYPE_ADDRESS_REG:
765                case TYPE_POSITION_RESULT_REG:
766                case TYPE_COLOR_RESULT_REG:
767                case TYPE_TEXTURE_RESULT_REG:
768                case TYPE_FOG_RESULT_REG:
769                case TYPE_POINTS_RESULT_REG:
770                    sprintf( temp, "(%d) Error: third source register is not readable\n", line );
771                    errors.set( temp );
772                    break;
773                default:
774                    errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
775            }
776            break;
777        default:
778            errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
779            break;
780    }
781}
782
783void VS10Inst::ValidateReadPorts()
784{
785    int constidx[3];
786    int attribidx[3];
787    int i;
788    int acount;
789    int ccount;
790    char temp[256];
791
792    switch( instid )
793    {
794        // Vector operations.
795        case VS10_MOV:
796        case VS10_LIT:
797            break;
798
799        // Unary operations.
800        case VS10_FRC:
801            break;
802
803        // Scalar operations.
804        case VS10_EXP:
805        case VS10_EXPP:
806        case VS10_LOG:
807        case VS10_LOGP:
808        case VS10_RCP:
809        case VS10_RSQ:
810            break;
811       
812        // Binary operations.
813        case VS10_ADD:
814        case VS10_DP3:
815        case VS10_DP4:
816        case VS10_DST:
817        case VS10_SGE:
818        case VS10_SLT:
819        case VS10_SUB:
820        case VS10_M3X2:
821        case VS10_M3X3:
822        case VS10_M3X4:
823        case VS10_M4X3:
824        case VS10_M4X4:
825        case VS10_MAX:
826        case VS10_MIN:
827        case VS10_MUL:
828            acount = 0;
829            ccount = 0;
830            for ( i = 0; i < 2; i++ )
831            {
832                switch( src[i].type )
833                {
834                    case TYPE_VERTEX_ATTRIB_REG:
835                        attribidx[acount] = src[i].index;
836                        acount++;
837                        break;
838                    case TYPE_CONSTANT_MEM_REG:
839                        constidx[ccount] = src[i].index;
840                        ccount++;
841                        break;
842                    case TYPE_CONSTANT_A0_REG:
843                        constidx[ccount] = 100 + src[i].index;
844                        ccount++;
845                        break;
846                    case TYPE_CONSTANT_A0_OFFSET_REG:
847                        constidx[ccount] = 200 + src[i].index;
848                        ccount++;
849                        break;
850                    case TYPE_TEMPORARY_REG:
851                    case TYPE_ADDRESS_REG:
852                    case TYPE_POSITION_RESULT_REG:
853                    case TYPE_COLOR_RESULT_REG:
854                    case TYPE_TEXTURE_RESULT_REG:
855                    case TYPE_FOG_RESULT_REG:
856                    case TYPE_POINTS_RESULT_REG:
857                        break;
858                    default:
859                        errors.set( "VS10Inst::ValidateReadPorts() Internal Error: unknown register type\n" );
860                }
861            }
862            if ( acount == 2 )
863            {
864                if ( attribidx[0] != attribidx[1] )
865                {
866                    sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
867                    errors.set( temp );
868                }
869            }
870            else if ( ccount == 2 )
871            {
872                if ( constidx[0] != constidx[1] )
873                {
874                    sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
875                    errors.set( temp );
876                }
877            }
878            break;
879
880        // Trinary operations.
881        case VS10_MAD:
882            acount = 0;
883            ccount = 0;
884            for ( i = 0; i < 3; i++ )
885            {
886                switch( src[i].type )
887                {
888                    case TYPE_VERTEX_ATTRIB_REG:
889                        attribidx[acount] = src[i].index;
890                        acount++;
891                        break;
892                    case TYPE_CONSTANT_MEM_REG:
893                        constidx[ccount] = src[i].index;
894                        ccount++;
895                        break;
896                    case TYPE_CONSTANT_A0_REG:
897                        constidx[ccount] = 100 + src[i].index;
898                        ccount++;
899                        break;
900                    case TYPE_CONSTANT_A0_OFFSET_REG:
901                        constidx[ccount] = 200 + src[i].index;
902                        ccount++;
903                        break;
904                    case TYPE_TEMPORARY_REG:
905                    case TYPE_ADDRESS_REG:
906                    case TYPE_POSITION_RESULT_REG:
907                    case TYPE_COLOR_RESULT_REG:
908                    case TYPE_TEXTURE_RESULT_REG:
909                    case TYPE_FOG_RESULT_REG:
910                    case TYPE_POINTS_RESULT_REG:
911                        break;
912                    default:
913                        errors.set( "VS10Inst::ValidateReadPorts() Internal Error: unknown register type\n" );
914                }
915            }
916            if ( acount == 3 )
917            {
918                if ( attribidx[0] != attribidx[1] || attribidx[1] != attribidx[2] )
919                {
920                    sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
921                    errors.set( temp );
922                }
923            }
924            else if ( acount == 2 )
925            {
926                if ( attribidx[0] != attribidx[1] )
927                {
928                    sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
929                    errors.set( temp );
930                }
931            }
932            else if ( ccount == 3 )
933            {
934                if ( constidx[0] != constidx[1] || constidx[1] != constidx[2] )
935                {
936                    sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
937                    errors.set( temp );
938                }
939            }
940            else if ( ccount == 2 )
941            {
942                if ( constidx[0] != constidx[1] )
943                {
944                    sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
945                    errors.set( temp );
946                }
947            }
948            break;
949        default:
950            errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
951            break;
952    }
953}
954
955int VS10Inst::Translate()
956{
957    int flag;
958    int ninstr;
959
960#if DEBUGGING_PURPOSES
961    char mystr[16];
962    if ( instid == VS10_HEADER )
963    {
964        sprintf( mystr, "%d:\tvs.1.0 (skip)\n", line );
965        vs10_transstring.append( mystr );
966        return 0;
967    }
968    sprintf( mystr, "%d:\t", line );
969    vs10_transstring.append( mystr );
970#endif
971
972    switch( instid )
973    {
974    case VS10_ADD:
975        vs10_transstring.append( "ADD    " );
976        dst.Translate();
977        vs10_transstring.append( ", " );
978        src[0].Translate();
979        vs10_transstring.append( ", " );
980        src[1].Translate();
981        ninstr = 1;
982        break;
983    case VS10_DP3:
984        vs10_transstring.append( "DP3    " );
985        dst.Translate();
986        vs10_transstring.append( ", " );
987        src[0].Translate();
988        vs10_transstring.append( ", " );
989        src[1].Translate();
990        ninstr = 1;
991        break;
992    case VS10_DP4:
993        vs10_transstring.append( "DP4    " );
994        dst.Translate();
995        vs10_transstring.append( ", " );
996        src[0].Translate();
997        vs10_transstring.append( ", " );
998        src[1].Translate();
999        ninstr = 1;
1000        break;
1001    case VS10_DST:
1002        vs10_transstring.append( "DST    " );
1003        dst.Translate();
1004        vs10_transstring.append( ", " );
1005        src[0].Translate();
1006        vs10_transstring.append( ", " );
1007        src[1].Translate();
1008        ninstr = 1;
1009        break;
1010    case VS10_EXP:
1011        vs10_transstring.append( "EXP    " );
1012        dst.Translate();
1013        vs10_transstring.append( ", " );
1014        src[0].Translate();
1015        ninstr = 1;
1016        break;
1017    case VS10_EXPP:
1018        vs10_transstring.append( "EXP    " );
1019        dst.Translate();
1020        vs10_transstring.append( ", " );
1021        src[0].Translate();
1022        ninstr = 1;
1023        break;
1024    case VS10_FRC:
1025        char temp[128];
1026        sprintf( temp, "(%d) Error: FRC built-in macro not yet supported.\n", line );
1027        errors.set( temp );
1028        ninstr = 0;
1029        break;
1030    case VS10_LIT:
1031        vs10_transstring.append( "LIT    " );
1032        dst.Translate();
1033        vs10_transstring.append( ", " );
1034        src[0].Translate();
1035        ninstr = 1;
1036        break;
1037    case VS10_LOG:
1038        vs10_transstring.append( "LOG    " );
1039        dst.Translate();
1040        vs10_transstring.append( ", " );
1041        src[0].Translate();
1042        ninstr = 1;
1043        break;
1044    case VS10_LOGP:
1045        vs10_transstring.append( "LOG    " );
1046        dst.Translate();
1047        vs10_transstring.append( ", " );
1048        src[0].Translate();
1049        ninstr = 1;
1050        break;
1051    case VS10_M3X2:
1052    case VS10_M3X3:
1053    case VS10_M3X4:
1054        if ( dst.mask[0] != 0 )
1055        {
1056            ninstr = 0;
1057            int i = 0;
1058            while ( i < 4 && dst.mask[i] != 0 )
1059            {
1060                if ( dst.mask[i] == 'x' )
1061                {
1062                    char oldval;
1063                    vs10_transstring.append( "DP3    " );
1064                    oldval = dst.mask[0];
1065                    dst.mask[0] = 0;
1066                    dst.Translate();
1067                    dst.mask[0] = oldval;
1068                    vs10_transstring.append( ".x, " );
1069                    src[0].Translate();
1070                    vs10_transstring.append( ", " );
1071                    src[1].Translate();
1072                    vs10_transstring.append( ";\n" );
1073                    ninstr++;
1074                }
1075                if ( dst.mask[i] == 'y' )
1076                {
1077                    char oldval;
1078                    int  oldindex;
1079                    vs10_transstring.append( "DP3    " );
1080                    oldval = dst.mask[0];
1081                    dst.mask[0] = 0;
1082                    dst.Translate();
1083                    dst.mask[0] = oldval;
1084                    vs10_transstring.append( ".y, " );
1085                    src[0].Translate();
1086                    vs10_transstring.append( ", " );
1087                    oldindex = src[1].index;
1088                    src[1].index = src[1].index + 1;
1089                    src[1].Translate();
1090                    src[1].index = oldindex;
1091                    vs10_transstring.append( ";\n" );
1092                    ninstr++;
1093                }
1094                if ( dst.mask[i] == 'z' && (instid == VS10_M3X3 || instid == VS10_M3X4) )
1095                {
1096                    char oldval;
1097                    int  oldindex;
1098                    vs10_transstring.append( "DP3    " );
1099                    oldval = dst.mask[0];
1100                    dst.mask[0] = 0;
1101                    dst.Translate();
1102                    dst.mask[0] = oldval;
1103                    vs10_transstring.append( ".z, " );
1104                    src[0].Translate();
1105                    vs10_transstring.append( ", " );
1106                    oldindex = src[1].index;
1107                    src[1].index = src[1].index + 2;
1108                    src[1].Translate();
1109                    src[1].index = oldindex;
1110                    vs10_transstring.append( ";\n" );
1111                    ninstr++;
1112                }
1113                if ( dst.mask[i] == 'w' && instid == VS10_M3X4 )
1114                {
1115                    char oldval;
1116                    int  oldindex;
1117                    vs10_transstring.append( "DP3    " );
1118                    oldval = dst.mask[0];
1119                    dst.mask[0] = 0;
1120                    dst.Translate();
1121                    dst.mask[0] = oldval;
1122                    vs10_transstring.append( ".w, " );
1123                    src[0].Translate();
1124                    vs10_transstring.append( ", " );
1125                    oldindex = src[1].index;
1126                    src[1].index = src[1].index + 3;
1127                    src[1].Translate();
1128                    src[1].index = oldindex;
1129                    vs10_transstring.append( ";\n" );
1130                    ninstr++;
1131                }
1132                i++;
1133            }
1134            return ninstr;
1135        }
1136        else
1137        {
1138            ninstr = 0;
1139
1140            char oldval;
1141            int  oldindex;
1142
1143            vs10_transstring.append( "DP3    " );
1144            oldval = dst.mask[0];
1145            dst.mask[0] = 0;
1146            dst.Translate();
1147            dst.mask[0] = oldval;
1148            vs10_transstring.append( ".x, " );
1149            src[0].Translate();
1150            vs10_transstring.append( ", " );
1151            src[1].Translate();
1152            vs10_transstring.append( ";\n" );
1153            ninstr++;
1154
1155            vs10_transstring.append( "DP3    " );
1156            oldval = dst.mask[0];
1157            dst.mask[0] = 0;
1158            dst.Translate();
1159            dst.mask[0] = oldval;
1160            vs10_transstring.append( ".y, " );
1161            src[0].Translate();
1162            vs10_transstring.append( ", " );
1163            oldindex = src[1].index;
1164            src[1].index = src[1].index + 1;
1165            src[1].Translate();
1166            src[1].index = oldindex;
1167            vs10_transstring.append( ";\n" );
1168            ninstr++;
1169
1170            if ( instid == VS10_M3X3 || instid == VS10_M3X4 )
1171            {
1172                vs10_transstring.append( "DP3    " );
1173                oldval = dst.mask[0];
1174                dst.mask[0] = 0;
1175                dst.Translate();
1176                dst.mask[0] = oldval;
1177                vs10_transstring.append( ".z, " );
1178                src[0].Translate();
1179                vs10_transstring.append( ", " );
1180                oldindex = src[1].index;
1181                src[1].index = src[1].index + 2;
1182                src[1].Translate();
1183                src[1].index = oldindex;
1184                vs10_transstring.append( ";\n" );
1185                ninstr++;
1186            }
1187
1188            if ( instid == VS10_M3X4 )
1189            {
1190                vs10_transstring.append( "DP3    " );
1191                oldval = dst.mask[0];
1192                dst.mask[0] = 0;
1193                dst.Translate();
1194                dst.mask[0] = oldval;
1195                vs10_transstring.append( ".w, " );
1196                src[0].Translate();
1197                vs10_transstring.append( ", " );
1198                oldindex = src[1].index;
1199                src[1].index = src[1].index + 3;
1200                src[1].Translate();
1201                src[1].index = oldindex;
1202                vs10_transstring.append( ";\n" );
1203                ninstr++;
1204            }
1205            return ninstr;
1206        }
1207        break;
1208    case VS10_M4X3:
1209    case VS10_M4X4:
1210        if ( dst.mask[0] != 0 )
1211        {
1212            ninstr = 0;
1213            int i = 0;
1214            while ( i < 4 && dst.mask[i] != 0 )
1215            {
1216                if ( dst.mask[i] == 'x' )
1217                {
1218                    char oldval;
1219                    vs10_transstring.append( "DP4    " );
1220                    oldval = dst.mask[0];
1221                    dst.mask[0] = 0;
1222                    dst.Translate();
1223                    dst.mask[0] = oldval;
1224                    vs10_transstring.append( ".x, " );
1225                    src[0].Translate();
1226                    vs10_transstring.append( ", " );
1227                    src[1].Translate();
1228                    vs10_transstring.append( ";\n" );
1229                    ninstr++;
1230                }
1231                if ( dst.mask[i] == 'y' )
1232                {
1233                    char oldval;
1234                    int  oldindex;
1235                    vs10_transstring.append( "DP4    " );
1236                    oldval = dst.mask[0];
1237                    dst.mask[0] = 0;
1238                    dst.Translate();
1239                    dst.mask[0] = oldval;
1240                    vs10_transstring.append( ".y, " );
1241                    src[0].Translate();
1242                    vs10_transstring.append( ", " );
1243                    oldindex = src[1].index;
1244                    src[1].index = src[1].index + 1;
1245                    src[1].Translate();
1246                    src[1].index = oldindex;
1247                    vs10_transstring.append( ";\n" );
1248                    ninstr++;
1249                }
1250                if ( dst.mask[i] == 'z' )
1251                {
1252                    char oldval;
1253                    int  oldindex;
1254                    vs10_transstring.append( "DP4    " );
1255                    oldval = dst.mask[0];
1256                    dst.mask[0] = 0;
1257                    dst.Translate();
1258                    dst.mask[0] = oldval;
1259                    vs10_transstring.append( ".z, " );
1260                    src[0].Translate();
1261                    vs10_transstring.append( ", " );
1262                    oldindex = src[1].index;
1263                    src[1].index = src[1].index + 2;
1264                    src[1].Translate();
1265                    src[1].index = oldindex;
1266                    vs10_transstring.append( ";\n" );
1267                    ninstr++;
1268                }
1269                if ( dst.mask[i] == 'w' && instid == VS10_M4X4 )
1270                {
1271                    char oldval;
1272                    int  oldindex;
1273                    vs10_transstring.append( "DP4    " );
1274                    oldval = dst.mask[0];
1275                    dst.mask[0] = 0;
1276                    dst.Translate();
1277                    dst.mask[0] = oldval;
1278                    vs10_transstring.append( ".w, " );
1279                    src[0].Translate();
1280                    vs10_transstring.append( ", " );
1281                    oldindex = src[1].index;
1282                    src[1].index = src[1].index + 3;
1283                    src[1].Translate();
1284                    src[1].index = oldindex;
1285                    vs10_transstring.append( ";\n" );
1286                    ninstr++;
1287                }
1288                i++;
1289            }
1290            return ninstr;
1291        }
1292        else
1293        {
1294            ninstr = 0;
1295
1296            char oldval;
1297            int  oldindex;
1298
1299            vs10_transstring.append( "DP4    " );
1300            oldval = dst.mask[0];
1301            dst.mask[0] = 0;
1302            dst.Translate();
1303            dst.mask[0] = oldval;
1304            vs10_transstring.append( ".x, " );
1305            src[0].Translate();
1306            vs10_transstring.append( ", " );
1307            src[1].Translate();
1308            vs10_transstring.append( ";\n" );
1309            ninstr++;
1310
1311            vs10_transstring.append( "DP4    " );
1312            oldval = dst.mask[0];
1313            dst.mask[0] = 0;
1314            dst.Translate();
1315            dst.mask[0] = oldval;
1316            vs10_transstring.append( ".y, " );
1317            src[0].Translate();
1318            vs10_transstring.append( ", " );
1319            oldindex = src[1].index;
1320            src[1].index = src[1].index + 1;
1321            src[1].Translate();
1322            src[1].index = oldindex;
1323            vs10_transstring.append( ";\n" );
1324            ninstr++;
1325
1326            vs10_transstring.append( "DP4    " );
1327            oldval = dst.mask[0];
1328            dst.mask[0] = 0;
1329            dst.Translate();
1330            dst.mask[0] = oldval;
1331            vs10_transstring.append( ".z, " );
1332            src[0].Translate();
1333            vs10_transstring.append( ", " );
1334            oldindex = src[1].index;
1335            src[1].index = src[1].index + 2;
1336            src[1].Translate();
1337            src[1].index = oldindex;
1338            vs10_transstring.append( ";\n" );
1339            ninstr++;
1340
1341            if ( instid == VS10_M4X4 )
1342            {
1343                vs10_transstring.append( "DP4    " );
1344                oldval = dst.mask[0];
1345                dst.mask[0] = 0;
1346                dst.Translate();
1347                dst.mask[0] = oldval;
1348                vs10_transstring.append( ".w, " );
1349                src[0].Translate();
1350                vs10_transstring.append( ", " );
1351                oldindex = src[1].index;
1352                src[1].index = src[1].index + 3;
1353                src[1].Translate();
1354                src[1].index = oldindex;
1355                vs10_transstring.append( ";\n" );
1356                ninstr++;
1357            }
1358            return ninstr;
1359        }
1360        break;
1361    case VS10_MAD:
1362        vs10_transstring.append( "MAD    " );
1363        dst.Translate();
1364        vs10_transstring.append( ", " );
1365        src[0].Translate();
1366        vs10_transstring.append( ", " );
1367        src[1].Translate();
1368        vs10_transstring.append( ", " );
1369        src[2].Translate();
1370        ninstr = 1;
1371        break;
1372    case VS10_MAX:
1373        vs10_transstring.append( "MAX    " );
1374        dst.Translate();
1375        vs10_transstring.append( ", " );
1376        src[0].Translate();
1377        vs10_transstring.append( ", " );
1378        src[1].Translate();
1379        ninstr = 1;
1380        break;
1381    case VS10_MIN:
1382        vs10_transstring.append( "MIN    " );
1383        dst.Translate();
1384        vs10_transstring.append( ", " );
1385        src[0].Translate();
1386        vs10_transstring.append( ", " );
1387        src[1].Translate();
1388        ninstr = 1;
1389        break;
1390    case VS10_MOV:
1391        if ( dst.type == TYPE_ADDRESS_REG )
1392            vs10_transstring.append( "ARL    " );
1393        else
1394            vs10_transstring.append( "MOV    " );
1395        dst.Translate();
1396        vs10_transstring.append( ", " );
1397        src[0].Translate();
1398        ninstr = 1;
1399        break;
1400    case VS10_MUL:
1401        vs10_transstring.append( "MUL    " );
1402        dst.Translate();
1403        vs10_transstring.append( ", " );
1404        src[0].Translate();
1405        vs10_transstring.append( ", " );
1406        src[1].Translate();
1407        ninstr = 1;
1408        break;
1409    case VS10_NOP:
1410        return 0;
1411        break;
1412    case VS10_RCP:
1413        vs10_transstring.append( "RCP    " );
1414        dst.Translate();
1415        vs10_transstring.append( ", " );
1416        src[0].Translate();
1417        ninstr = 1;
1418        break;
1419    case VS10_RSQ:
1420        vs10_transstring.append( "RSQ    " );
1421        dst.Translate();
1422        vs10_transstring.append( ", " );
1423        src[0].Translate();
1424        ninstr = 1;
1425        break;
1426    case VS10_SGE:
1427        vs10_transstring.append( "SGE    " );
1428        dst.Translate();
1429        vs10_transstring.append( ", " );
1430        src[0].Translate();
1431        vs10_transstring.append( ", " );
1432        src[1].Translate();
1433        ninstr = 1;
1434        break;
1435    case VS10_SLT:
1436        vs10_transstring.append( "SLT    " );
1437        dst.Translate();
1438        vs10_transstring.append( ", " );
1439        src[0].Translate();
1440        vs10_transstring.append( ", " );
1441        src[1].Translate();
1442        ninstr = 1;
1443        break;
1444    case VS10_SUB:
1445        vs10_transstring.append( "ADD    " );
1446        dst.Translate();
1447        vs10_transstring.append( ", " );
1448        src[0].Translate();
1449        vs10_transstring.append( ", " );
1450        flag = src[1].sign;
1451        if ( flag == -1 ) src[1].sign = 1;
1452        else src[1].sign = -1;
1453        src[1].Translate();
1454        src[1].sign = flag;
1455        ninstr = 1;
1456        break;
1457    case VS10_COMMENT:
1458        vs10_transstring.append( comment );
1459        return 0;
1460        break;
1461    case VS10_HEADER:
1462        //vs10_transstring.append( "!!VP1.0\n" );
1463        return 0;
1464        break;
1465    case -1:
1466        vs10_transstring.append( "\n" );
1467        return 0;
1468    default:
1469        errors.set( "VS10Inst::Translate() Internal Error: unknown instruction type\n" );
1470    }
1471
1472    vs10_transstring.append( ";\n" );
1473    return ninstr;
1474}
Note: See TracBrowser for help on using the repository browser.