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 "pipe/tgsi/util/tgsi_parse.h"
14 #include "pipe/tgsi/exec/tgsi_exec.h"
15 #include "pipe/tgsi/util/tgsi_util.h"
16 #include "pipe/tgsi/util/tgsi_build.h"
17 #include "pipe/tgsi/util/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/ParameterAttributes.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>
47 #include "llvm_base_shader.cpp"
49 static inline FunctionType
*vertexShaderFunctionType()
51 //Function takes three arguments,
52 // the calling code has to make sure the types it will
53 // pass are castable to the following:
54 // [4 x <4 x float>] inputs,
55 // [4 x <4 x float>] output,
56 // [4 x [4 x float]] consts
57 std::vector
<const Type
*> funcArgs
;
59 VectorType
*vectorType
= VectorType::get(Type::FloatTy
, 4);
60 ArrayType
*vectorArray
= ArrayType::get(vectorType
, 4);
61 PointerType
*vectorArrayPtr
= PointerType::get(vectorArray
, 0);
63 funcArgs
.push_back(vectorArrayPtr
);//inputs
64 funcArgs
.push_back(vectorArrayPtr
);//output
67 ArrayType
*floatArray
= ArrayType::get(Type::FloatTy
, 4);
68 ArrayType
*constsArray
= ArrayType::get(floatArray
, 4);
69 PointerType
*constsArrayPtr
= PointerType::get(constsArray
, 0);
71 funcArgs
.push_back(constsArrayPtr
);//consts
73 FunctionType
*functionType
= FunctionType::get(
74 /*Result=*/Type::VoidTy
,
82 add_interpolator(struct gallivm_ir
*ir
,
83 struct gallivm_interpolate
*interp
)
85 ir
->interpolators
[ir
->num_interp
] = *interp
;
90 translate_declaration(struct gallivm_ir
*prog
,
93 struct tgsi_full_declaration
*decl
,
94 struct tgsi_full_declaration
*fd
)
96 if (decl
->Declaration
.File
== TGSI_FILE_INPUT
) {
97 unsigned first
, last
, mask
;
100 assert(decl
->Declaration
.Declare
== TGSI_DECLARE_RANGE
);
102 first
= decl
->u
.DeclarationRange
.First
;
103 last
= decl
->u
.DeclarationRange
.Last
;
104 mask
= decl
->Declaration
.UsageMask
;
106 /* Do not touch WPOS.xy */
108 mask
&= ~TGSI_WRITEMASK_XY
;
109 if (mask
== TGSI_WRITEMASK_NONE
) {
117 interp_method
= decl
->Interpolation
.Interpolate
;
119 if (mask
== TGSI_WRITEMASK_XYZW
) {
122 for (i
= first
; i
<= last
; i
++) {
123 for (j
= 0; j
< NUM_CHANNELS
; j
++) {
124 //interp( mach, i, j );
125 struct gallivm_interpolate interp
;
126 interp
.type
= interp_method
;
129 add_interpolator(prog
, &interp
);
134 for( j
= 0; j
< NUM_CHANNELS
; j
++ ) {
135 if( mask
& (1 << j
) ) {
136 for( i
= first
; i
<= last
; i
++ ) {
137 struct gallivm_interpolate interp
;
138 interp
.type
= interp_method
;
141 add_interpolator(prog
, &interp
);
150 translate_declarationir(struct gallivm_ir
*,
153 struct tgsi_full_declaration
*,
154 struct tgsi_full_declaration
*)
159 translate_immediate(Storage
*storage
,
160 struct tgsi_full_immediate
*imm
)
164 for (i
= 0; i
< imm
->Immediate
.Size
- 1; ++i
) {
165 switch (imm
->Immediate
.DataType
) {
166 case TGSI_IMM_FLOAT32
:
167 vec
[i
] = imm
->u
.ImmediateFloat32
[i
].Float
;
173 storage
->addImmediate(vec
);
178 translate_immediateir(StorageSoa
*storage
,
179 struct tgsi_full_immediate
*imm
)
183 for (i
= 0; i
< imm
->Immediate
.Size
- 1; ++i
) {
184 switch (imm
->Immediate
.DataType
) {
185 case TGSI_IMM_FLOAT32
:
186 vec
[i
] = imm
->u
.ImmediateFloat32
[i
].Float
;
192 storage
->addImmediate(vec
);
196 swizzleInt(struct tgsi_full_src_register
*src
)
201 for (int k
= 0; k
< 4; ++k
) {
202 swizzle
+= tgsi_util_get_full_src_register_extswizzle(src
, k
) * start
;
208 static inline llvm::Value
*
209 swizzleVector(llvm::Value
*val
, struct tgsi_full_src_register
*src
,
212 int swizzle
= swizzleInt(src
);
214 if (gallivm_is_swizzle(swizzle
)) {
215 /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/
216 val
= storage
->shuffleVector(val
, swizzle
);
222 translate_instruction(llvm::Module
*module
,
225 struct tgsi_full_instruction
*inst
,
226 struct tgsi_full_instruction
*fi
,
229 llvm::Value
*inputs
[4];
235 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
236 struct tgsi_full_src_register
*src
= &inst
->FullSrcRegisters
[i
];
237 llvm::Value
*val
= 0;
238 llvm::Value
*indIdx
= 0;
240 if (src
->SrcRegister
.Indirect
) {
241 indIdx
= storage
->addrElement(src
->SrcRegisterInd
.Index
);
242 indIdx
= storage
->extractIndex(indIdx
);
244 if (src
->SrcRegister
.File
== TGSI_FILE_CONSTANT
) {
245 val
= storage
->constElement(src
->SrcRegister
.Index
, indIdx
);
246 } else if (src
->SrcRegister
.File
== TGSI_FILE_INPUT
) {
247 val
= storage
->inputElement(src
->SrcRegister
.Index
, indIdx
);
248 } else if (src
->SrcRegister
.File
== TGSI_FILE_TEMPORARY
) {
249 val
= storage
->tempElement(src
->SrcRegister
.Index
);
250 } else if (src
->SrcRegister
.File
== TGSI_FILE_OUTPUT
) {
251 val
= storage
->outputElement(src
->SrcRegister
.Index
, indIdx
);
252 } else if (src
->SrcRegister
.File
== TGSI_FILE_IMMEDIATE
) {
253 val
= storage
->immediateElement(src
->SrcRegister
.Index
);
255 fprintf(stderr
, "ERROR: not supported llvm source %d\n", src
->SrcRegister
.File
);
259 inputs
[i
] = swizzleVector(val
, src
, storage
);
263 instr->printVector(inputs[0]);
265 instr->printVector(inputs[1]);*/
266 llvm::Value
*out
= 0;
267 switch (inst
->Instruction
.Opcode
) {
268 case TGSI_OPCODE_ARL
: {
269 out
= instr
->arl(inputs
[0]);
272 case TGSI_OPCODE_MOV
: {
276 case TGSI_OPCODE_LIT
: {
277 out
= instr
->lit(inputs
[0]);
280 case TGSI_OPCODE_RCP
: {
281 out
= instr
->rcp(inputs
[0]);
284 case TGSI_OPCODE_RSQ
: {
285 out
= instr
->rsq(inputs
[0]);
288 case TGSI_OPCODE_EXP
:
290 case TGSI_OPCODE_LOG
:
292 case TGSI_OPCODE_MUL
: {
293 out
= instr
->mul(inputs
[0], inputs
[1]);
296 case TGSI_OPCODE_ADD
: {
297 out
= instr
->add(inputs
[0], inputs
[1]);
300 case TGSI_OPCODE_DP3
: {
301 out
= instr
->dp3(inputs
[0], inputs
[1]);
304 case TGSI_OPCODE_DP4
: {
305 out
= instr
->dp4(inputs
[0], inputs
[1]);
308 case TGSI_OPCODE_DST
: {
309 out
= instr
->dst(inputs
[0], inputs
[1]);
312 case TGSI_OPCODE_MIN
: {
313 out
= instr
->min(inputs
[0], inputs
[1]);
316 case TGSI_OPCODE_MAX
: {
317 out
= instr
->max(inputs
[0], inputs
[1]);
320 case TGSI_OPCODE_SLT
: {
321 out
= instr
->slt(inputs
[0], inputs
[1]);
324 case TGSI_OPCODE_SGE
: {
325 out
= instr
->sge(inputs
[0], inputs
[1]);
328 case TGSI_OPCODE_MAD
: {
329 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
332 case TGSI_OPCODE_SUB
: {
333 out
= instr
->sub(inputs
[0], inputs
[1]);
336 case TGSI_OPCODE_LERP
: {
337 out
= instr
->lerp(inputs
[0], inputs
[1], inputs
[2]);
340 case TGSI_OPCODE_CND
:
342 case TGSI_OPCODE_CND0
:
344 case TGSI_OPCODE_DOT2ADD
:
346 case TGSI_OPCODE_INDEX
:
348 case TGSI_OPCODE_NEGATE
:
350 case TGSI_OPCODE_FRAC
: {
351 out
= instr
->frc(inputs
[0]);
354 case TGSI_OPCODE_CLAMP
:
356 case TGSI_OPCODE_FLOOR
: {
357 out
= instr
->floor(inputs
[0]);
360 case TGSI_OPCODE_ROUND
:
362 case TGSI_OPCODE_EXPBASE2
: {
363 out
= instr
->ex2(inputs
[0]);
366 case TGSI_OPCODE_LOGBASE2
: {
367 out
= instr
->lg2(inputs
[0]);
370 case TGSI_OPCODE_POWER
: {
371 out
= instr
->pow(inputs
[0], inputs
[1]);
374 case TGSI_OPCODE_CROSSPRODUCT
: {
375 out
= instr
->cross(inputs
[0], inputs
[1]);
378 case TGSI_OPCODE_MULTIPLYMATRIX
:
380 case TGSI_OPCODE_ABS
: {
381 out
= instr
->abs(inputs
[0]);
384 case TGSI_OPCODE_RCC
:
386 case TGSI_OPCODE_DPH
: {
387 out
= instr
->dph(inputs
[0], inputs
[1]);
390 case TGSI_OPCODE_COS
: {
391 out
= instr
->cos(inputs
[0]);
394 case TGSI_OPCODE_DDX
:
396 case TGSI_OPCODE_DDY
:
398 case TGSI_OPCODE_KILP
: {
399 out
= instr
->kilp(inputs
[0]);
400 storage
->setKilElement(out
);
404 case TGSI_OPCODE_PK2H
:
406 case TGSI_OPCODE_PK2US
:
408 case TGSI_OPCODE_PK4B
:
410 case TGSI_OPCODE_PK4UB
:
412 case TGSI_OPCODE_RFL
:
414 case TGSI_OPCODE_SEQ
:
416 case TGSI_OPCODE_SFL
:
418 case TGSI_OPCODE_SGT
: {
419 out
= instr
->sgt(inputs
[0], inputs
[1]);
422 case TGSI_OPCODE_SIN
: {
423 out
= instr
->sin(inputs
[0]);
426 case TGSI_OPCODE_SLE
:
428 case TGSI_OPCODE_SNE
:
430 case TGSI_OPCODE_STR
:
432 case TGSI_OPCODE_TEX
:
434 case TGSI_OPCODE_TXD
:
436 case TGSI_OPCODE_UP2H
:
438 case TGSI_OPCODE_UP2US
:
440 case TGSI_OPCODE_UP4B
:
442 case TGSI_OPCODE_UP4UB
:
444 case TGSI_OPCODE_X2D
:
446 case TGSI_OPCODE_ARA
:
448 case TGSI_OPCODE_ARR
:
450 case TGSI_OPCODE_BRA
:
452 case TGSI_OPCODE_CAL
: {
453 instr
->cal(inst
->InstructionExtLabel
.Label
, storage
->inputPtr());
457 case TGSI_OPCODE_RET
: {
462 case TGSI_OPCODE_SSG
:
464 case TGSI_OPCODE_CMP
: {
465 out
= instr
->cmp(inputs
[0], inputs
[1], inputs
[2]);
468 case TGSI_OPCODE_SCS
: {
469 out
= instr
->scs(inputs
[0]);
472 case TGSI_OPCODE_TXB
:
474 case TGSI_OPCODE_NRM
:
476 case TGSI_OPCODE_DIV
:
478 case TGSI_OPCODE_DP2
:
480 case TGSI_OPCODE_TXL
:
482 case TGSI_OPCODE_BRK
: {
487 case TGSI_OPCODE_IF
: {
488 instr
->ifop(inputs
[0]);
489 storage
->setCurrentBlock(instr
->currentBlock());
490 return; //just update the state
493 case TGSI_OPCODE_LOOP
:
495 case TGSI_OPCODE_REP
:
497 case TGSI_OPCODE_ELSE
: {
499 storage
->setCurrentBlock(instr
->currentBlock());
500 return; //only state update
503 case TGSI_OPCODE_ENDIF
: {
505 storage
->setCurrentBlock(instr
->currentBlock());
506 return; //just update the state
509 case TGSI_OPCODE_ENDLOOP
:
511 case TGSI_OPCODE_ENDREP
:
513 case TGSI_OPCODE_PUSHA
:
515 case TGSI_OPCODE_POPA
:
517 case TGSI_OPCODE_CEIL
:
519 case TGSI_OPCODE_I2F
:
521 case TGSI_OPCODE_NOT
:
523 case TGSI_OPCODE_TRUNC
: {
524 out
= instr
->trunc(inputs
[0]);
527 case TGSI_OPCODE_SHL
:
529 case TGSI_OPCODE_SHR
:
531 case TGSI_OPCODE_AND
:
535 case TGSI_OPCODE_MOD
:
537 case TGSI_OPCODE_XOR
:
539 case TGSI_OPCODE_SAD
:
541 case TGSI_OPCODE_TXF
:
543 case TGSI_OPCODE_TXQ
:
545 case TGSI_OPCODE_CONT
:
547 case TGSI_OPCODE_EMIT
:
549 case TGSI_OPCODE_ENDPRIM
:
551 case TGSI_OPCODE_BGNLOOP2
: {
553 storage
->setCurrentBlock(instr
->currentBlock());
557 case TGSI_OPCODE_BGNSUB
: {
558 instr
->bgnSub(instno
);
559 storage
->setCurrentBlock(instr
->currentBlock());
560 storage
->pushTemps();
564 case TGSI_OPCODE_ENDLOOP2
: {
566 storage
->setCurrentBlock(instr
->currentBlock());
570 case TGSI_OPCODE_ENDSUB
: {
572 storage
->setCurrentBlock(instr
->currentBlock());
573 storage
->popArguments();
578 case TGSI_OPCODE_NOISE1
:
580 case TGSI_OPCODE_NOISE2
:
582 case TGSI_OPCODE_NOISE3
:
584 case TGSI_OPCODE_NOISE4
:
586 case TGSI_OPCODE_NOP
:
588 case TGSI_OPCODE_TEXBEM
:
590 case TGSI_OPCODE_TEXBEML
:
592 case TGSI_OPCODE_TEXREG2AR
:
594 case TGSI_OPCODE_TEXM3X2PAD
:
596 case TGSI_OPCODE_TEXM3X2TEX
:
598 case TGSI_OPCODE_TEXM3X3PAD
:
600 case TGSI_OPCODE_TEXM3X3TEX
:
602 case TGSI_OPCODE_TEXM3X3SPEC
:
604 case TGSI_OPCODE_TEXM3X3VSPEC
:
606 case TGSI_OPCODE_TEXREG2GB
:
608 case TGSI_OPCODE_TEXREG2RGB
:
610 case TGSI_OPCODE_TEXDP3TEX
:
612 case TGSI_OPCODE_TEXDP3
:
614 case TGSI_OPCODE_TEXM3X3
:
616 case TGSI_OPCODE_TEXM3X2DEPTH
:
618 case TGSI_OPCODE_TEXDEPTH
:
620 case TGSI_OPCODE_BEM
:
622 case TGSI_OPCODE_M4X3
:
624 case TGSI_OPCODE_M3X4
:
626 case TGSI_OPCODE_M3X3
:
628 case TGSI_OPCODE_M3X2
:
630 case TGSI_OPCODE_NRM4
:
632 case TGSI_OPCODE_CALLNZ
:
634 case TGSI_OPCODE_IFC
:
636 case TGSI_OPCODE_BREAKC
:
638 case TGSI_OPCODE_KIL
:
640 case TGSI_OPCODE_END
:
645 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
646 inst
->Instruction
.Opcode
);
652 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
653 inst
->Instruction
.Opcode
);
654 assert(!"Unsupported opcode");
657 /* # not sure if we need this */
658 switch( inst
->Instruction
.Saturate
) {
661 case TGSI_SAT_ZERO_ONE
:
664 case TGSI_SAT_MINUS_PLUS_ONE
:
665 /*TXT( "_SAT[-1,1]" );*/
672 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
673 struct tgsi_full_dst_register
*dst
= &inst
->FullDstRegisters
[i
];
675 if (dst
->DstRegister
.File
== TGSI_FILE_OUTPUT
) {
676 storage
->setOutputElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
677 } else if (dst
->DstRegister
.File
== TGSI_FILE_TEMPORARY
) {
678 storage
->setTempElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
679 } else if (dst
->DstRegister
.File
== TGSI_FILE_ADDRESS
) {
680 storage
->setAddrElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
682 fprintf(stderr
, "ERROR: unsupported LLVM destination!");
683 assert(!"wrong destination");
690 translate_instructionir(llvm::Module
*module
,
692 InstructionsSoa
*instr
,
693 struct tgsi_full_instruction
*inst
,
694 struct tgsi_full_instruction
*fi
,
697 std::vector
< std::vector
<llvm::Value
*> > inputs(inst
->Instruction
.NumSrcRegs
);
699 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
700 struct tgsi_full_src_register
*src
= &inst
->FullSrcRegisters
[i
];
701 std::vector
<llvm::Value
*> val
;
702 llvm::Value
*indIdx
= 0;
703 int swizzle
= swizzleInt(src
);
705 if (src
->SrcRegister
.Indirect
) {
706 indIdx
= storage
->addrElement(src
->SrcRegisterInd
.Index
);
707 indIdx
= storage
->extractIndex(indIdx
);
709 if (src
->SrcRegister
.File
== TGSI_FILE_CONSTANT
) {
710 val
= storage
->constElement(src
->SrcRegister
.Index
, swizzle
, indIdx
);
711 } else if (src
->SrcRegister
.File
== TGSI_FILE_INPUT
) {
712 val
= storage
->inputElement(src
->SrcRegister
.Index
, swizzle
, indIdx
);
713 } else if (src
->SrcRegister
.File
== TGSI_FILE_TEMPORARY
) {
714 val
= storage
->tempElement(src
->SrcRegister
.Index
, swizzle
);
715 } else if (src
->SrcRegister
.File
== TGSI_FILE_OUTPUT
) {
716 val
= storage
->outputElement(src
->SrcRegister
.Index
, swizzle
, indIdx
);
717 } else if (src
->SrcRegister
.File
== TGSI_FILE_IMMEDIATE
) {
718 val
= storage
->immediateElement(src
->SrcRegister
.Index
, swizzle
);
720 fprintf(stderr
, "ERROR: not supported llvm source %d\n", src
->SrcRegister
.File
);
727 std::vector
<llvm::Value
*> out(4);
728 switch (inst
->Instruction
.Opcode
) {
729 case TGSI_OPCODE_ARL
: {
732 case TGSI_OPCODE_MOV
: {
736 case TGSI_OPCODE_LIT
: {
739 case TGSI_OPCODE_RCP
: {
742 case TGSI_OPCODE_RSQ
: {
745 case TGSI_OPCODE_EXP
:
747 case TGSI_OPCODE_LOG
:
749 case TGSI_OPCODE_MUL
: {
750 out
= instr
->mul(inputs
[0], inputs
[1]);
753 case TGSI_OPCODE_ADD
: {
754 out
= instr
->add(inputs
[0], inputs
[1]);
757 case TGSI_OPCODE_DP3
: {
760 case TGSI_OPCODE_DP4
: {
763 case TGSI_OPCODE_DST
: {
766 case TGSI_OPCODE_MIN
: {
769 case TGSI_OPCODE_MAX
: {
772 case TGSI_OPCODE_SLT
: {
775 case TGSI_OPCODE_SGE
: {
778 case TGSI_OPCODE_MAD
: {
781 case TGSI_OPCODE_SUB
: {
784 case TGSI_OPCODE_LERP
: {
787 case TGSI_OPCODE_CND
:
789 case TGSI_OPCODE_CND0
:
791 case TGSI_OPCODE_DOT2ADD
:
793 case TGSI_OPCODE_INDEX
:
795 case TGSI_OPCODE_NEGATE
:
797 case TGSI_OPCODE_FRAC
: {
800 case TGSI_OPCODE_CLAMP
:
802 case TGSI_OPCODE_FLOOR
: {
805 case TGSI_OPCODE_ROUND
:
807 case TGSI_OPCODE_EXPBASE2
: {
810 case TGSI_OPCODE_LOGBASE2
: {
813 case TGSI_OPCODE_POWER
: {
816 case TGSI_OPCODE_CROSSPRODUCT
: {
819 case TGSI_OPCODE_MULTIPLYMATRIX
:
821 case TGSI_OPCODE_ABS
: {
824 case TGSI_OPCODE_RCC
:
826 case TGSI_OPCODE_DPH
: {
829 case TGSI_OPCODE_COS
: {
832 case TGSI_OPCODE_DDX
:
834 case TGSI_OPCODE_DDY
:
836 case TGSI_OPCODE_KILP
: {
839 case TGSI_OPCODE_PK2H
:
841 case TGSI_OPCODE_PK2US
:
843 case TGSI_OPCODE_PK4B
:
845 case TGSI_OPCODE_PK4UB
:
847 case TGSI_OPCODE_RFL
:
849 case TGSI_OPCODE_SEQ
:
851 case TGSI_OPCODE_SFL
:
853 case TGSI_OPCODE_SGT
: {
856 case TGSI_OPCODE_SIN
: {
859 case TGSI_OPCODE_SLE
:
861 case TGSI_OPCODE_SNE
:
863 case TGSI_OPCODE_STR
:
865 case TGSI_OPCODE_TEX
:
867 case TGSI_OPCODE_TXD
:
869 case TGSI_OPCODE_UP2H
:
871 case TGSI_OPCODE_UP2US
:
873 case TGSI_OPCODE_UP4B
:
875 case TGSI_OPCODE_UP4UB
:
877 case TGSI_OPCODE_X2D
:
879 case TGSI_OPCODE_ARA
:
881 case TGSI_OPCODE_ARR
:
883 case TGSI_OPCODE_BRA
:
885 case TGSI_OPCODE_CAL
: {
888 case TGSI_OPCODE_RET
: {
891 case TGSI_OPCODE_SSG
:
893 case TGSI_OPCODE_CMP
: {
896 case TGSI_OPCODE_SCS
: {
899 case TGSI_OPCODE_TXB
:
901 case TGSI_OPCODE_NRM
:
903 case TGSI_OPCODE_DIV
:
905 case TGSI_OPCODE_DP2
:
907 case TGSI_OPCODE_TXL
:
909 case TGSI_OPCODE_BRK
: {
912 case TGSI_OPCODE_IF
: {
915 case TGSI_OPCODE_LOOP
:
917 case TGSI_OPCODE_REP
:
919 case TGSI_OPCODE_ELSE
: {
922 case TGSI_OPCODE_ENDIF
: {
925 case TGSI_OPCODE_ENDLOOP
:
927 case TGSI_OPCODE_ENDREP
:
929 case TGSI_OPCODE_PUSHA
:
931 case TGSI_OPCODE_POPA
:
933 case TGSI_OPCODE_CEIL
:
935 case TGSI_OPCODE_I2F
:
937 case TGSI_OPCODE_NOT
:
939 case TGSI_OPCODE_TRUNC
: {
942 case TGSI_OPCODE_SHL
:
944 case TGSI_OPCODE_SHR
:
946 case TGSI_OPCODE_AND
:
950 case TGSI_OPCODE_MOD
:
952 case TGSI_OPCODE_XOR
:
954 case TGSI_OPCODE_SAD
:
956 case TGSI_OPCODE_TXF
:
958 case TGSI_OPCODE_TXQ
:
960 case TGSI_OPCODE_CONT
:
962 case TGSI_OPCODE_EMIT
:
964 case TGSI_OPCODE_ENDPRIM
:
966 case TGSI_OPCODE_BGNLOOP2
: {
969 case TGSI_OPCODE_BGNSUB
: {
972 case TGSI_OPCODE_ENDLOOP2
: {
975 case TGSI_OPCODE_ENDSUB
: {
978 case TGSI_OPCODE_NOISE1
:
980 case TGSI_OPCODE_NOISE2
:
982 case TGSI_OPCODE_NOISE3
:
984 case TGSI_OPCODE_NOISE4
:
986 case TGSI_OPCODE_NOP
:
988 case TGSI_OPCODE_TEXBEM
:
990 case TGSI_OPCODE_TEXBEML
:
992 case TGSI_OPCODE_TEXREG2AR
:
994 case TGSI_OPCODE_TEXM3X2PAD
:
996 case TGSI_OPCODE_TEXM3X2TEX
:
998 case TGSI_OPCODE_TEXM3X3PAD
:
1000 case TGSI_OPCODE_TEXM3X3TEX
:
1002 case TGSI_OPCODE_TEXM3X3SPEC
:
1004 case TGSI_OPCODE_TEXM3X3VSPEC
:
1006 case TGSI_OPCODE_TEXREG2GB
:
1008 case TGSI_OPCODE_TEXREG2RGB
:
1010 case TGSI_OPCODE_TEXDP3TEX
:
1012 case TGSI_OPCODE_TEXDP3
:
1014 case TGSI_OPCODE_TEXM3X3
:
1016 case TGSI_OPCODE_TEXM3X2DEPTH
:
1018 case TGSI_OPCODE_TEXDEPTH
:
1020 case TGSI_OPCODE_BEM
:
1022 case TGSI_OPCODE_M4X3
:
1024 case TGSI_OPCODE_M3X4
:
1026 case TGSI_OPCODE_M3X3
:
1028 case TGSI_OPCODE_M3X2
:
1030 case TGSI_OPCODE_NRM4
:
1032 case TGSI_OPCODE_CALLNZ
:
1034 case TGSI_OPCODE_IFC
:
1036 case TGSI_OPCODE_BREAKC
:
1038 case TGSI_OPCODE_KIL
:
1040 case TGSI_OPCODE_END
:
1045 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
1046 inst
->Instruction
.Opcode
);
1052 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
1053 inst
->Instruction
.Opcode
);
1054 assert(!"Unsupported opcode");
1058 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
1059 struct tgsi_full_dst_register
*dst
= &inst
->FullDstRegisters
[i
];
1061 if (dst
->DstRegister
.File
== TGSI_FILE_OUTPUT
) {
1062 storage
->storeOutput(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1063 } else if (dst
->DstRegister
.File
== TGSI_FILE_TEMPORARY
) {
1064 storage
->storeTemp(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1065 } else if (dst
->DstRegister
.File
== TGSI_FILE_ADDRESS
) {
1066 storage
->storeAddress(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1068 fprintf(stderr
, "ERROR: unsupported LLVM destination!");
1069 assert(!"wrong destination");
1075 tgsi_to_llvm(struct gallivm_ir
*ir
, const struct tgsi_token
*tokens
)
1077 llvm::Module
*mod
= createBaseShader();
1078 struct tgsi_parse_context parse
;
1079 struct tgsi_full_instruction fi
;
1080 struct tgsi_full_declaration fd
;
1081 unsigned instno
= 0;
1082 Function
* shader
= mod
->getFunction("execute_shader");
1083 std::ostringstream stream
;
1084 if (ir
->type
== GALLIVM_VS
) {
1085 stream
<< "vs_shader";
1087 stream
<< "fs_shader";
1090 std::string func_name
= stream
.str();
1091 shader
->setName(func_name
.c_str());
1093 Function::arg_iterator args
= shader
->arg_begin();
1094 Value
*ptr_INPUT
= args
++;
1095 ptr_INPUT
->setName("input");
1097 BasicBlock
*label_entry
= new BasicBlock("entry", shader
, 0);
1099 tgsi_parse_init(&parse
, tokens
);
1101 fi
= tgsi_default_full_instruction();
1102 fd
= tgsi_default_full_declaration();
1103 Storage
storage(label_entry
, ptr_INPUT
);
1104 Instructions
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_declaration(ir
, mod
, &storage
,
1111 &parse
.FullToken
.FullDeclaration
,
1115 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1116 translate_immediate(&storage
,
1117 &parse
.FullToken
.FullImmediate
);
1120 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1121 translate_instruction(mod
, &storage
, &instr
,
1122 &parse
.FullToken
.FullInstruction
,
1132 tgsi_parse_free(&parse
);
1134 ir
->num_consts
= storage
.numConsts();
1138 llvm::Module
* tgsi_to_llvmir(struct gallivm_ir
*ir
,
1139 const struct tgsi_token
*tokens
)
1141 llvm::Module
*mod
= new Module("shader");
1142 struct tgsi_parse_context parse
;
1143 struct tgsi_full_instruction fi
;
1144 struct tgsi_full_declaration fd
;
1145 unsigned instno
= 0;
1146 std::ostringstream stream
;
1147 if (ir
->type
== GALLIVM_VS
) {
1148 stream
<< "vs_shader";
1150 stream
<< "fs_shader";
1153 std::string func_name
= stream
.str();
1154 Function
*shader
= llvm::cast
<Function
>(mod
->getOrInsertFunction(
1156 vertexShaderFunctionType()));
1158 Function::arg_iterator args
= shader
->arg_begin();
1159 Value
*input
= args
++;
1160 input
->setName("inputs");
1161 Value
*output
= args
++;
1162 output
->setName("outputs");
1163 Value
*consts
= args
++;
1164 consts
->setName("consts");
1166 BasicBlock
*label_entry
= new BasicBlock("entry", shader
, 0);
1168 tgsi_parse_init(&parse
, tokens
);
1170 fi
= tgsi_default_full_instruction();
1171 fd
= tgsi_default_full_declaration();
1173 StorageSoa
storage(label_entry
, input
, output
, consts
);
1174 InstructionsSoa
instr(mod
, shader
, label_entry
, &storage
);
1176 while(!tgsi_parse_end_of_tokens(&parse
)) {
1177 tgsi_parse_token(&parse
);
1179 switch (parse
.FullToken
.Token
.Type
) {
1180 case TGSI_TOKEN_TYPE_DECLARATION
:
1181 translate_declarationir(ir
, mod
, &storage
,
1182 &parse
.FullToken
.FullDeclaration
,
1186 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1187 translate_immediateir(&storage
,
1188 &parse
.FullToken
.FullImmediate
);
1191 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1192 translate_instructionir(mod
, &storage
, &instr
,
1193 &parse
.FullToken
.FullInstruction
,
1203 tgsi_parse_free(&parse
);