1 #include "tgsitollvm.h"
7 #include "instructions.h"
8 #include "storagesoa.h"
9 #include "instructionssoa.h"
11 #include "pipe/p_shader_tokens.h"
13 #include "tgsi/tgsi_parse.h"
14 #include "tgsi/tgsi_exec.h"
15 #include "tgsi/tgsi_util.h"
16 #include "tgsi/tgsi_build.h"
17 #include "tgsi/tgsi_dump.h"
20 #include <llvm/Module.h>
21 #include <llvm/CallingConv.h>
22 #include <llvm/Constants.h>
23 #include <llvm/DerivedTypes.h>
24 #include <llvm/Instructions.h>
25 #include <llvm/ModuleProvider.h>
26 #include <llvm/Pass.h>
27 #include <llvm/PassManager.h>
28 #include <llvm/Attributes.h>
29 #include <llvm/Support/PatternMatch.h>
30 #include <llvm/ExecutionEngine/JIT.h>
31 #include <llvm/ExecutionEngine/Interpreter.h>
32 #include <llvm/ExecutionEngine/GenericValue.h>
33 #include <llvm/Support/MemoryBuffer.h>
34 #include <llvm/LinkAllPasses.h>
35 #include <llvm/Analysis/Verifier.h>
36 #include <llvm/Analysis/LoopPass.h>
37 #include <llvm/Target/TargetData.h>
38 #include <llvm/Bitcode/ReaderWriter.h>
39 #include <llvm/Transforms/Utils/Cloning.h>
48 static inline FunctionType
*vertexShaderFunctionType()
50 //Function takes three arguments,
51 // the calling code has to make sure the types it will
52 // pass are castable to the following:
53 // [4 x <4 x float>] inputs,
54 // [4 x <4 x float>] output,
55 // [4 x [1 x float]] consts,
57 std::vector
<const Type
*> funcArgs
;
58 VectorType
*vectorType
= VectorType::get(Type::FloatTy
, 4);
59 ArrayType
*vectorArray
= ArrayType::get(vectorType
, 4);
60 PointerType
*vectorArrayPtr
= PointerType::get(vectorArray
, 0);
62 ArrayType
*floatArray
= ArrayType::get(Type::FloatTy
, 4);
63 ArrayType
*constsArray
= ArrayType::get(floatArray
, 1);
64 PointerType
*constsArrayPtr
= PointerType::get(constsArray
, 0);
66 funcArgs
.push_back(vectorArrayPtr
);//inputs
67 funcArgs
.push_back(vectorArrayPtr
);//output
68 funcArgs
.push_back(constsArrayPtr
);//consts
70 FunctionType
*functionType
= FunctionType::get(
71 /*Result=*/Type::VoidTy
,
79 add_interpolator(struct gallivm_ir
*ir
,
80 struct gallivm_interpolate
*interp
)
82 ir
->interpolators
[ir
->num_interp
] = *interp
;
87 translate_declaration(struct gallivm_ir
*prog
,
90 struct tgsi_full_declaration
*decl
,
91 struct tgsi_full_declaration
*fd
)
93 if (decl
->Declaration
.File
== TGSI_FILE_INPUT
) {
94 unsigned first
, last
, mask
;
97 first
= decl
->Range
.First
;
98 last
= decl
->Range
.Last
;
99 mask
= decl
->Declaration
.UsageMask
;
101 /* Do not touch WPOS.xy */
103 mask
&= ~TGSI_WRITEMASK_XY
;
104 if (mask
== TGSI_WRITEMASK_NONE
) {
112 interp_method
= decl
->Declaration
.Interpolate
;
114 if (mask
== TGSI_WRITEMASK_XYZW
) {
117 for (i
= first
; i
<= last
; i
++) {
118 for (j
= 0; j
< NUM_CHANNELS
; j
++) {
119 //interp( mach, i, j );
120 struct gallivm_interpolate interp
;
121 interp
.type
= interp_method
;
124 add_interpolator(prog
, &interp
);
129 for( j
= 0; j
< NUM_CHANNELS
; j
++ ) {
130 if( mask
& (1 << j
) ) {
131 for( i
= first
; i
<= last
; i
++ ) {
132 struct gallivm_interpolate interp
;
133 interp
.type
= interp_method
;
136 add_interpolator(prog
, &interp
);
145 translate_declarationir(struct gallivm_ir
*,
148 struct tgsi_full_declaration
*decl
,
149 struct tgsi_full_declaration
*)
151 if (decl
->Declaration
.File
== TGSI_FILE_ADDRESS
) {
152 int idx
= decl
->Range
.First
;
153 storage
->addAddress(idx
);
158 translate_immediate(Storage
*storage
,
159 struct tgsi_full_immediate
*imm
)
163 assert( imm
->Immediate
.NrTokens
<= 4 + 1 );
164 for (i
= 0; i
< imm
->Immediate
.NrTokens
- 1; ++i
) {
165 switch (imm
->Immediate
.DataType
) {
166 case TGSI_IMM_FLOAT32
:
167 vec
[i
] = imm
->u
[i
].Float
;
173 storage
->addImmediate(vec
);
178 translate_immediateir(StorageSoa
*storage
,
179 struct tgsi_full_immediate
*imm
)
183 assert( imm
->Immediate
.NrTokens
<= 4 + 1 );
184 for (i
= 0; i
< imm
->Immediate
.NrTokens
- 1; ++i
) {
185 switch (imm
->Immediate
.DataType
) {
186 case TGSI_IMM_FLOAT32
:
187 vec
[i
] = imm
->u
[i
].Float
;
193 storage
->addImmediate(vec
);
197 swizzleInt(struct tgsi_full_src_register
*src
)
202 for (int k
= 0; k
< 4; ++k
) {
203 swizzle
+= tgsi_util_get_full_src_register_extswizzle(src
, k
) * start
;
209 static inline llvm::Value
*
210 swizzleVector(llvm::Value
*val
, struct tgsi_full_src_register
*src
,
213 int swizzle
= swizzleInt(src
);
215 if (gallivm_is_swizzle(swizzle
)) {
216 /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/
217 val
= storage
->shuffleVector(val
, swizzle
);
223 translate_instruction(llvm::Module
*module
,
226 struct tgsi_full_instruction
*inst
,
227 struct tgsi_full_instruction
*fi
,
230 llvm::Value
*inputs
[4];
236 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
237 struct tgsi_full_src_register
*src
= &inst
->Src
[i
];
238 llvm::Value
*val
= 0;
239 llvm::Value
*indIdx
= 0;
241 if (src
->Register
.Indirect
) {
242 indIdx
= storage
->addrElement(src
->Indirect
.Index
);
243 indIdx
= storage
->extractIndex(indIdx
);
245 if (src
->Register
.File
== TGSI_FILE_CONSTANT
) {
246 val
= storage
->constElement(src
->Register
.Index
, indIdx
);
247 } else if (src
->Register
.File
== TGSI_FILE_INPUT
) {
248 val
= storage
->inputElement(src
->Register
.Index
, indIdx
);
249 } else if (src
->Register
.File
== TGSI_FILE_TEMPORARY
) {
250 val
= storage
->tempElement(src
->Register
.Index
);
251 } else if (src
->Register
.File
== TGSI_FILE_OUTPUT
) {
252 val
= storage
->outputElement(src
->Register
.Index
, indIdx
);
253 } else if (src
->Register
.File
== TGSI_FILE_IMMEDIATE
) {
254 val
= storage
->immediateElement(src
->Register
.Index
);
256 fprintf(stderr
, "ERROR: not supported llvm source %d\n", src
->Register
.File
);
260 inputs
[i
] = swizzleVector(val
, src
, storage
);
264 instr->printVector(inputs[0]);
266 instr->printVector(inputs[1]);*/
267 llvm::Value
*out
= 0;
268 switch (inst
->Instruction
.Opcode
) {
269 case TGSI_OPCODE_ARL
: {
270 out
= instr
->arl(inputs
[0]);
273 case TGSI_OPCODE_MOV
: {
277 case TGSI_OPCODE_LIT
: {
278 out
= instr
->lit(inputs
[0]);
281 case TGSI_OPCODE_RCP
: {
282 out
= instr
->rcp(inputs
[0]);
285 case TGSI_OPCODE_RSQ
: {
286 out
= instr
->rsq(inputs
[0]);
289 case TGSI_OPCODE_EXP
: {
290 out
= instr
->exp(inputs
[0]);
293 case TGSI_OPCODE_LOG
: {
294 out
= instr
->log(inputs
[0]);
297 case TGSI_OPCODE_MUL
: {
298 out
= instr
->mul(inputs
[0], inputs
[1]);
301 case TGSI_OPCODE_ADD
: {
302 out
= instr
->add(inputs
[0], inputs
[1]);
305 case TGSI_OPCODE_DP3
: {
306 out
= instr
->dp3(inputs
[0], inputs
[1]);
309 case TGSI_OPCODE_DP4
: {
310 out
= instr
->dp4(inputs
[0], inputs
[1]);
313 case TGSI_OPCODE_DST
: {
314 out
= instr
->dst(inputs
[0], inputs
[1]);
317 case TGSI_OPCODE_MIN
: {
318 out
= instr
->min(inputs
[0], inputs
[1]);
321 case TGSI_OPCODE_MAX
: {
322 out
= instr
->max(inputs
[0], inputs
[1]);
325 case TGSI_OPCODE_SLT
: {
326 out
= instr
->slt(inputs
[0], inputs
[1]);
329 case TGSI_OPCODE_SGE
: {
330 out
= instr
->sge(inputs
[0], inputs
[1]);
333 case TGSI_OPCODE_MAD
: {
334 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
337 case TGSI_OPCODE_SUB
: {
338 out
= instr
->sub(inputs
[0], inputs
[1]);
341 case TGSI_OPCODE_LRP
: {
342 out
= instr
->lerp(inputs
[0], inputs
[1], inputs
[2]);
345 case TGSI_OPCODE_CND
: {
346 out
= instr
->cnd(inputs
[0], inputs
[1], inputs
[2]);
349 case TGSI_OPCODE_CND0
: {
350 out
= instr
->cnd0(inputs
[0], inputs
[1], inputs
[2]);
353 case TGSI_OPCODE_DP2A
: {
354 out
= instr
->dot2add(inputs
[0], inputs
[1], inputs
[2]);
357 case TGSI_OPCODE_FRC
: {
358 out
= instr
->frc(inputs
[0]);
361 case TGSI_OPCODE_CLAMP
: {
362 out
= instr
->clamp(inputs
[0]);
365 case TGSI_OPCODE_FLR
: {
366 out
= instr
->floor(inputs
[0]);
369 case TGSI_OPCODE_ROUND
:
371 case TGSI_OPCODE_EX2
: {
372 out
= instr
->ex2(inputs
[0]);
375 case TGSI_OPCODE_LG2
: {
376 out
= instr
->lg2(inputs
[0]);
379 case TGSI_OPCODE_POW
: {
380 out
= instr
->pow(inputs
[0], inputs
[1]);
383 case TGSI_OPCODE_XPD
: {
384 out
= instr
->cross(inputs
[0], inputs
[1]);
387 case TGSI_OPCODE_ABS
: {
388 out
= instr
->abs(inputs
[0]);
391 case TGSI_OPCODE_RCC
:
393 case TGSI_OPCODE_DPH
: {
394 out
= instr
->dph(inputs
[0], inputs
[1]);
397 case TGSI_OPCODE_COS
: {
398 out
= instr
->cos(inputs
[0]);
401 case TGSI_OPCODE_DDX
: {
402 out
= instr
->ddx(inputs
[0]);
405 case TGSI_OPCODE_DDY
: {
406 out
= instr
->ddy(inputs
[0]);
409 case TGSI_OPCODE_KILP
:
411 case TGSI_OPCODE_PK2H
:
413 case TGSI_OPCODE_PK2US
:
415 case TGSI_OPCODE_PK4B
:
417 case TGSI_OPCODE_PK4UB
:
419 case TGSI_OPCODE_RFL
:
421 case TGSI_OPCODE_SEQ
: {
422 out
= instr
->seq(inputs
[0], inputs
[1]);
425 case TGSI_OPCODE_SFL
: {
426 out
= instr
->sfl(inputs
[0], inputs
[1]);
429 case TGSI_OPCODE_SGT
: {
430 out
= instr
->sgt(inputs
[0], inputs
[1]);
433 case TGSI_OPCODE_SIN
: {
434 out
= instr
->sin(inputs
[0]);
437 case TGSI_OPCODE_SLE
: {
438 out
= instr
->sle(inputs
[0], inputs
[1]);
441 case TGSI_OPCODE_SNE
: {
442 out
= instr
->sne(inputs
[0], inputs
[1]);
445 case TGSI_OPCODE_STR
: {
446 out
= instr
->str(inputs
[0], inputs
[1]);
449 case TGSI_OPCODE_TEX
:
451 case TGSI_OPCODE_TXD
:
453 case TGSI_OPCODE_UP2H
:
455 case TGSI_OPCODE_UP2US
:
457 case TGSI_OPCODE_UP4B
:
459 case TGSI_OPCODE_UP4UB
:
461 case TGSI_OPCODE_X2D
: {
462 out
= instr
->x2d(inputs
[0], inputs
[1], inputs
[2]);
465 case TGSI_OPCODE_ARA
:
467 case TGSI_OPCODE_ARR
:
469 case TGSI_OPCODE_BRA
:
471 case TGSI_OPCODE_CAL
: {
472 instr
->cal(inst
->InstructionExtLabel
.Label
, storage
->inputPtr());
476 case TGSI_OPCODE_RET
: {
481 case TGSI_OPCODE_SSG
:
483 case TGSI_OPCODE_CMP
: {
484 out
= instr
->cmp(inputs
[0], inputs
[1], inputs
[2]);
487 case TGSI_OPCODE_SCS
: {
488 out
= instr
->scs(inputs
[0]);
491 case TGSI_OPCODE_TXB
:
493 case TGSI_OPCODE_NRM4
:
494 case TGSI_OPCODE_NRM
: {
495 out
= instr
->nrm(inputs
[0]);
498 case TGSI_OPCODE_DIV
: {
499 out
= instr
->div(inputs
[0], inputs
[1]);
502 case TGSI_OPCODE_DP2
: {
503 out
= instr
->dp2(inputs
[0], inputs
[1]);
506 case TGSI_OPCODE_TXL
:
508 case TGSI_OPCODE_BRK
: {
513 case TGSI_OPCODE_IF
: {
514 instr
->ifop(inputs
[0]);
515 storage
->setCurrentBlock(instr
->currentBlock());
516 return; //just update the state
519 case TGSI_OPCODE_BGNFOR
:
521 case TGSI_OPCODE_REP
:
523 case TGSI_OPCODE_ELSE
: {
525 storage
->setCurrentBlock(instr
->currentBlock());
526 return; //only state update
529 case TGSI_OPCODE_ENDIF
: {
531 storage
->setCurrentBlock(instr
->currentBlock());
532 return; //just update the state
535 case TGSI_OPCODE_ENDFOR
:
537 case TGSI_OPCODE_ENDREP
:
539 case TGSI_OPCODE_PUSHA
:
541 case TGSI_OPCODE_POPA
:
543 case TGSI_OPCODE_CEIL
:
545 case TGSI_OPCODE_I2F
:
547 case TGSI_OPCODE_NOT
:
549 case TGSI_OPCODE_TRUNC
: {
550 out
= instr
->trunc(inputs
[0]);
553 case TGSI_OPCODE_SHL
:
555 case TGSI_OPCODE_ISHR
:
557 case TGSI_OPCODE_AND
:
561 case TGSI_OPCODE_MOD
:
563 case TGSI_OPCODE_XOR
:
565 case TGSI_OPCODE_SAD
:
567 case TGSI_OPCODE_TXF
:
569 case TGSI_OPCODE_TXQ
:
571 case TGSI_OPCODE_CONT
:
573 case TGSI_OPCODE_EMIT
:
575 case TGSI_OPCODE_ENDPRIM
:
577 case TGSI_OPCODE_BGNLOOP
: {
579 storage
->setCurrentBlock(instr
->currentBlock());
583 case TGSI_OPCODE_BGNSUB
: {
584 instr
->bgnSub(instno
);
585 storage
->setCurrentBlock(instr
->currentBlock());
586 storage
->pushTemps();
590 case TGSI_OPCODE_ENDLOOP
: {
592 storage
->setCurrentBlock(instr
->currentBlock());
596 case TGSI_OPCODE_ENDSUB
: {
598 storage
->setCurrentBlock(instr
->currentBlock());
599 storage
->popArguments();
604 case TGSI_OPCODE_NOISE1
:
606 case TGSI_OPCODE_NOISE2
:
608 case TGSI_OPCODE_NOISE3
:
610 case TGSI_OPCODE_NOISE4
:
612 case TGSI_OPCODE_NOP
:
614 case TGSI_OPCODE_CALLNZ
:
616 case TGSI_OPCODE_IFC
:
618 case TGSI_OPCODE_BREAKC
:
620 case TGSI_OPCODE_KIL
: {
621 out
= instr
->kil(inputs
[0]);
622 storage
->setKilElement(out
);
626 case TGSI_OPCODE_END
:
631 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
632 inst
->Instruction
.Opcode
);
638 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
639 inst
->Instruction
.Opcode
);
640 assert(!"Unsupported opcode");
643 /* # not sure if we need this */
644 switch( inst
->Instruction
.Saturate
) {
647 case TGSI_SAT_ZERO_ONE
:
650 case TGSI_SAT_MINUS_PLUS_ONE
:
651 /*TXT( "_SAT[-1,1]" );*/
658 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
659 struct tgsi_full_dst_register
*dst
= &inst
->Dst
[i
];
661 if (dst
->Register
.File
== TGSI_FILE_OUTPUT
) {
662 storage
->setOutputElement(dst
->Register
.Index
, out
, dst
->Register
.WriteMask
);
663 } else if (dst
->Register
.File
== TGSI_FILE_TEMPORARY
) {
664 storage
->setTempElement(dst
->Register
.Index
, out
, dst
->Register
.WriteMask
);
665 } else if (dst
->Register
.File
== TGSI_FILE_ADDRESS
) {
666 storage
->setAddrElement(dst
->Register
.Index
, out
, dst
->Register
.WriteMask
);
668 fprintf(stderr
, "ERROR: unsupported LLVM destination!");
669 assert(!"wrong destination");
676 translate_instructionir(llvm::Module
*module
,
678 InstructionsSoa
*instr
,
679 struct tgsi_full_instruction
*inst
,
680 struct tgsi_full_instruction
*fi
,
683 std::vector
< std::vector
<llvm::Value
*> > inputs(inst
->Instruction
.NumSrcRegs
);
685 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
686 struct tgsi_full_src_register
*src
= &inst
->Src
[i
];
687 std::vector
<llvm::Value
*> val
;
688 llvm::Value
*indIdx
= 0;
689 int swizzle
= swizzleInt(src
);
691 if (src
->Register
.Indirect
) {
692 indIdx
= storage
->addrElement(src
->Indirect
.Index
);
694 val
= storage
->load((enum tgsi_file_type
)src
->Register
.File
,
695 src
->Register
.Index
, swizzle
, instr
->getIRBuilder(), indIdx
);
700 std::vector
<llvm::Value
*> out(4);
701 switch (inst
->Instruction
.Opcode
) {
702 case TGSI_OPCODE_ARL
: {
703 out
= instr
->arl(inputs
[0]);
706 case TGSI_OPCODE_MOV
: {
710 case TGSI_OPCODE_LIT
: {
711 out
= instr
->lit(inputs
[0]);
714 case TGSI_OPCODE_RCP
: {
717 case TGSI_OPCODE_RSQ
: {
718 out
= instr
->rsq(inputs
[0]);
721 case TGSI_OPCODE_EXP
:
723 case TGSI_OPCODE_LOG
:
725 case TGSI_OPCODE_MUL
: {
726 out
= instr
->mul(inputs
[0], inputs
[1]);
729 case TGSI_OPCODE_ADD
: {
730 out
= instr
->add(inputs
[0], inputs
[1]);
733 case TGSI_OPCODE_DP3
: {
734 out
= instr
->dp3(inputs
[0], inputs
[1]);
737 case TGSI_OPCODE_DP4
: {
738 out
= instr
->dp4(inputs
[0], inputs
[1]);
741 case TGSI_OPCODE_DST
: {
744 case TGSI_OPCODE_MIN
: {
745 out
= instr
->min(inputs
[0], inputs
[1]);
748 case TGSI_OPCODE_MAX
: {
749 out
= instr
->max(inputs
[0], inputs
[1]);
752 case TGSI_OPCODE_SLT
: {
753 out
= instr
->slt(inputs
[0], inputs
[1]);
756 case TGSI_OPCODE_SGE
: {
759 case TGSI_OPCODE_MAD
: {
760 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
763 case TGSI_OPCODE_SUB
: {
764 out
= instr
->sub(inputs
[0], inputs
[1]);
767 case TGSI_OPCODE_LRP
: {
770 case TGSI_OPCODE_CND
:
772 case TGSI_OPCODE_CND0
:
774 case TGSI_OPCODE_DP2A
:
776 case TGSI_OPCODE_FRC
: {
779 case TGSI_OPCODE_CLAMP
:
781 case TGSI_OPCODE_FLR
: {
784 case TGSI_OPCODE_ROUND
:
786 case TGSI_OPCODE_EX2
: {
789 case TGSI_OPCODE_LG2
: {
792 case TGSI_OPCODE_POW
: {
793 out
= instr
->pow(inputs
[0], inputs
[1]);
796 case TGSI_OPCODE_XPD
: {
799 case TGSI_OPCODE_ABS
: {
800 out
= instr
->abs(inputs
[0]);
803 case TGSI_OPCODE_RCC
:
805 case TGSI_OPCODE_DPH
: {
808 case TGSI_OPCODE_COS
: {
811 case TGSI_OPCODE_DDX
:
813 case TGSI_OPCODE_DDY
:
815 case TGSI_OPCODE_KILP
:
817 case TGSI_OPCODE_PK2H
:
819 case TGSI_OPCODE_PK2US
:
821 case TGSI_OPCODE_PK4B
:
823 case TGSI_OPCODE_PK4UB
:
825 case TGSI_OPCODE_RFL
:
827 case TGSI_OPCODE_SEQ
:
829 case TGSI_OPCODE_SFL
:
831 case TGSI_OPCODE_SGT
: {
834 case TGSI_OPCODE_SIN
: {
837 case TGSI_OPCODE_SLE
:
839 case TGSI_OPCODE_SNE
:
841 case TGSI_OPCODE_STR
:
843 case TGSI_OPCODE_TEX
:
845 case TGSI_OPCODE_TXD
:
847 case TGSI_OPCODE_UP2H
:
849 case TGSI_OPCODE_UP2US
:
851 case TGSI_OPCODE_UP4B
:
853 case TGSI_OPCODE_UP4UB
:
855 case TGSI_OPCODE_X2D
:
857 case TGSI_OPCODE_ARA
:
859 case TGSI_OPCODE_ARR
:
861 case TGSI_OPCODE_BRA
:
863 case TGSI_OPCODE_CAL
: {
866 case TGSI_OPCODE_RET
: {
869 case TGSI_OPCODE_SSG
:
871 case TGSI_OPCODE_CMP
: {
874 case TGSI_OPCODE_SCS
: {
877 case TGSI_OPCODE_TXB
:
879 case TGSI_OPCODE_NRM
:
881 case TGSI_OPCODE_DIV
:
883 case TGSI_OPCODE_DP2
:
885 case TGSI_OPCODE_TXL
:
887 case TGSI_OPCODE_BRK
: {
890 case TGSI_OPCODE_IF
: {
893 case TGSI_OPCODE_BGNFOR
:
895 case TGSI_OPCODE_REP
:
897 case TGSI_OPCODE_ELSE
: {
900 case TGSI_OPCODE_ENDIF
: {
903 case TGSI_OPCODE_ENDFOR
:
905 case TGSI_OPCODE_ENDREP
:
907 case TGSI_OPCODE_PUSHA
:
909 case TGSI_OPCODE_POPA
:
911 case TGSI_OPCODE_CEIL
:
913 case TGSI_OPCODE_I2F
:
915 case TGSI_OPCODE_NOT
:
917 case TGSI_OPCODE_TRUNC
: {
920 case TGSI_OPCODE_SHL
:
922 case TGSI_OPCODE_ISHR
:
924 case TGSI_OPCODE_AND
:
928 case TGSI_OPCODE_MOD
:
930 case TGSI_OPCODE_XOR
:
932 case TGSI_OPCODE_SAD
:
934 case TGSI_OPCODE_TXF
:
936 case TGSI_OPCODE_TXQ
:
938 case TGSI_OPCODE_CONT
:
940 case TGSI_OPCODE_EMIT
:
942 case TGSI_OPCODE_ENDPRIM
:
944 case TGSI_OPCODE_BGNLOOP
: {
947 case TGSI_OPCODE_BGNSUB
: {
950 case TGSI_OPCODE_ENDLOOP
: {
953 case TGSI_OPCODE_ENDSUB
: {
956 case TGSI_OPCODE_NOISE1
:
958 case TGSI_OPCODE_NOISE2
:
960 case TGSI_OPCODE_NOISE3
:
962 case TGSI_OPCODE_NOISE4
:
964 case TGSI_OPCODE_NOP
:
966 case TGSI_OPCODE_NRM4
:
968 case TGSI_OPCODE_CALLNZ
:
970 case TGSI_OPCODE_IFC
:
972 case TGSI_OPCODE_BREAKC
:
974 case TGSI_OPCODE_KIL
: {
977 case TGSI_OPCODE_END
:
982 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
983 inst
->Instruction
.Opcode
);
989 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
990 inst
->Instruction
.Opcode
);
991 assert(!"Unsupported opcode");
995 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
996 struct tgsi_full_dst_register
*dst
= &inst
->Dst
[i
];
997 storage
->store((enum tgsi_file_type
)dst
->Register
.File
,
998 dst
->Register
.Index
, out
, dst
->Register
.WriteMask
,
999 instr
->getIRBuilder() );
1004 tgsi_to_llvm(struct gallivm_ir
*ir
, const struct tgsi_token
*tokens
)
1006 llvm::Module
*mod
= new Module("shader");
1007 struct tgsi_parse_context parse
;
1008 struct tgsi_full_instruction fi
;
1009 struct tgsi_full_declaration fd
;
1010 unsigned instno
= 0;
1011 Function
* shader
= mod
->getFunction("execute_shader");
1012 std::ostringstream stream
;
1013 if (ir
->type
== GALLIVM_VS
) {
1014 stream
<< "vs_shader";
1016 stream
<< "fs_shader";
1019 std::string func_name
= stream
.str();
1020 shader
->setName(func_name
.c_str());
1022 Function::arg_iterator args
= shader
->arg_begin();
1023 Value
*ptr_INPUT
= args
++;
1024 ptr_INPUT
->setName("input");
1026 BasicBlock
*label_entry
= BasicBlock::Create("entry", shader
, 0);
1028 tgsi_parse_init(&parse
, tokens
);
1030 fi
= tgsi_default_full_instruction();
1031 fd
= tgsi_default_full_declaration();
1032 Storage
storage(label_entry
, ptr_INPUT
);
1033 Instructions
instr(mod
, shader
, label_entry
, &storage
);
1034 while(!tgsi_parse_end_of_tokens(&parse
)) {
1035 tgsi_parse_token(&parse
);
1037 switch (parse
.FullToken
.Token
.Type
) {
1038 case TGSI_TOKEN_TYPE_DECLARATION
:
1039 translate_declaration(ir
, mod
, &storage
,
1040 &parse
.FullToken
.FullDeclaration
,
1044 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1045 translate_immediate(&storage
,
1046 &parse
.FullToken
.FullImmediate
);
1049 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1050 translate_instruction(mod
, &storage
, &instr
,
1051 &parse
.FullToken
.FullInstruction
,
1061 tgsi_parse_free(&parse
);
1063 ir
->num_consts
= storage
.numConsts();
1067 llvm::Module
* tgsi_to_llvmir(struct gallivm_ir
*ir
,
1068 const struct tgsi_token
*tokens
)
1070 llvm::Module
*mod
= new Module("shader");
1071 struct tgsi_parse_context parse
;
1072 struct tgsi_full_instruction fi
;
1073 struct tgsi_full_declaration fd
;
1074 unsigned instno
= 0;
1075 std::ostringstream stream
;
1076 if (ir
->type
== GALLIVM_VS
) {
1077 stream
<< "vs_shader";
1079 stream
<< "fs_shader";
1082 std::string func_name
= stream
.str();
1083 Function
*shader
= llvm::cast
<Function
>(mod
->getOrInsertFunction(
1085 vertexShaderFunctionType()));
1087 Function::arg_iterator args
= shader
->arg_begin();
1088 Value
*input
= args
++;
1089 input
->setName("inputs");
1090 Value
*output
= args
++;
1091 output
->setName("outputs");
1092 Value
*consts
= args
++;
1093 consts
->setName("consts");
1095 BasicBlock
*label_entry
= BasicBlock::Create("entry", shader
, 0);
1097 tgsi_parse_init(&parse
, tokens
);
1099 fi
= tgsi_default_full_instruction();
1100 fd
= tgsi_default_full_declaration();
1102 StorageSoa
storage(label_entry
, input
, output
, consts
);
1103 InstructionsSoa
instr(mod
, shader
, label_entry
, &storage
);
1105 while(!tgsi_parse_end_of_tokens(&parse
)) {
1106 tgsi_parse_token(&parse
);
1108 switch (parse
.FullToken
.Token
.Type
) {
1109 case TGSI_TOKEN_TYPE_DECLARATION
:
1110 translate_declarationir(ir
, mod
, &storage
,
1111 &parse
.FullToken
.FullDeclaration
,
1115 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1116 translate_immediateir(&storage
,
1117 &parse
.FullToken
.FullImmediate
);
1120 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1121 storage
.declareImmediates();
1122 translate_instructionir(mod
, &storage
, &instr
,
1123 &parse
.FullToken
.FullInstruction
,
1133 tgsi_parse_free(&parse
);