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/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>
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,
56 // [4 x <4 x float>] temps
58 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 ArrayType
*floatArray
= ArrayType::get(Type::FloatTy
, 4);
64 ArrayType
*constsArray
= ArrayType::get(floatArray
, 1);
65 PointerType
*constsArrayPtr
= PointerType::get(constsArray
, 0);
67 funcArgs
.push_back(vectorArrayPtr
);//inputs
68 funcArgs
.push_back(vectorArrayPtr
);//output
69 funcArgs
.push_back(constsArrayPtr
);//consts
70 funcArgs
.push_back(vectorArrayPtr
);//temps
72 FunctionType
*functionType
= FunctionType::get(
73 /*Result=*/Type::VoidTy
,
81 add_interpolator(struct gallivm_ir
*ir
,
82 struct gallivm_interpolate
*interp
)
84 ir
->interpolators
[ir
->num_interp
] = *interp
;
89 translate_declaration(struct gallivm_ir
*prog
,
92 struct tgsi_full_declaration
*decl
,
93 struct tgsi_full_declaration
*fd
)
95 if (decl
->Declaration
.File
== TGSI_FILE_INPUT
) {
96 unsigned first
, last
, mask
;
99 first
= decl
->DeclarationRange
.First
;
100 last
= decl
->DeclarationRange
.Last
;
101 mask
= decl
->Declaration
.UsageMask
;
103 /* Do not touch WPOS.xy */
105 mask
&= ~TGSI_WRITEMASK_XY
;
106 if (mask
== TGSI_WRITEMASK_NONE
) {
114 interp_method
= decl
->Declaration
.Interpolate
;
116 if (mask
== TGSI_WRITEMASK_XYZW
) {
119 for (i
= first
; i
<= last
; i
++) {
120 for (j
= 0; j
< NUM_CHANNELS
; j
++) {
121 //interp( mach, i, j );
122 struct gallivm_interpolate interp
;
123 interp
.type
= interp_method
;
126 add_interpolator(prog
, &interp
);
131 for( j
= 0; j
< NUM_CHANNELS
; j
++ ) {
132 if( mask
& (1 << j
) ) {
133 for( i
= first
; i
<= last
; i
++ ) {
134 struct gallivm_interpolate interp
;
135 interp
.type
= interp_method
;
138 add_interpolator(prog
, &interp
);
147 translate_declarationir(struct gallivm_ir
*,
150 struct tgsi_full_declaration
*decl
,
151 struct tgsi_full_declaration
*)
153 if (decl
->Declaration
.File
== TGSI_FILE_ADDRESS
) {
154 int idx
= decl
->DeclarationRange
.First
;
155 storage
->addAddress(idx
);
160 translate_immediate(Storage
*storage
,
161 struct tgsi_full_immediate
*imm
)
165 for (i
= 0; i
< imm
->Immediate
.Size
- 1; ++i
) {
166 switch (imm
->Immediate
.DataType
) {
167 case TGSI_IMM_FLOAT32
:
168 vec
[i
] = imm
->u
.ImmediateFloat32
[i
].Float
;
174 storage
->addImmediate(vec
);
179 translate_immediateir(StorageSoa
*storage
,
180 struct tgsi_full_immediate
*imm
)
184 for (i
= 0; i
< imm
->Immediate
.Size
- 1; ++i
) {
185 switch (imm
->Immediate
.DataType
) {
186 case TGSI_IMM_FLOAT32
:
187 vec
[i
] = imm
->u
.ImmediateFloat32
[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
->FullSrcRegisters
[i
];
238 llvm::Value
*val
= 0;
239 llvm::Value
*indIdx
= 0;
241 if (src
->SrcRegister
.Indirect
) {
242 indIdx
= storage
->addrElement(src
->SrcRegisterInd
.Index
);
243 indIdx
= storage
->extractIndex(indIdx
);
245 if (src
->SrcRegister
.File
== TGSI_FILE_CONSTANT
) {
246 val
= storage
->constElement(src
->SrcRegister
.Index
, indIdx
);
247 } else if (src
->SrcRegister
.File
== TGSI_FILE_INPUT
) {
248 val
= storage
->inputElement(src
->SrcRegister
.Index
, indIdx
);
249 // FIXME we should not be generating elements for temporaries, this creates useless memory writes
250 } else if (src
->SrcRegister
.File
== TGSI_FILE_TEMPORARY
) {
251 val
= storage
->tempElement(src
->SrcRegister
.Index
);
252 } else if (src
->SrcRegister
.File
== TGSI_FILE_OUTPUT
) {
253 val
= storage
->outputElement(src
->SrcRegister
.Index
, indIdx
);
254 } else if (src
->SrcRegister
.File
== TGSI_FILE_IMMEDIATE
) {
255 val
= storage
->immediateElement(src
->SrcRegister
.Index
);
257 fprintf(stderr
, "ERROR: not supported llvm source %d\n", src
->SrcRegister
.File
);
261 inputs
[i
] = swizzleVector(val
, src
, storage
);
265 instr->printVector(inputs[0]);
267 instr->printVector(inputs[1]);*/
268 llvm::Value
*out
= 0;
269 switch (inst
->Instruction
.Opcode
) {
270 case TGSI_OPCODE_ARL
: {
271 out
= instr
->arl(inputs
[0]);
274 case TGSI_OPCODE_MOV
: {
278 case TGSI_OPCODE_LIT
: {
279 out
= instr
->lit(inputs
[0]);
282 case TGSI_OPCODE_RCP
: {
283 out
= instr
->rcp(inputs
[0]);
286 case TGSI_OPCODE_RSQ
: {
287 out
= instr
->rsq(inputs
[0]);
290 case TGSI_OPCODE_EXP
: {
291 out
= instr
->exp(inputs
[0]);
294 case TGSI_OPCODE_LOG
: {
295 out
= instr
->log(inputs
[0]);
298 case TGSI_OPCODE_MUL
: {
299 out
= instr
->mul(inputs
[0], inputs
[1]);
302 case TGSI_OPCODE_ADD
: {
303 out
= instr
->add(inputs
[0], inputs
[1]);
306 case TGSI_OPCODE_DP3
: {
307 out
= instr
->dp3(inputs
[0], inputs
[1]);
310 case TGSI_OPCODE_DP4
: {
311 out
= instr
->dp4(inputs
[0], inputs
[1]);
314 case TGSI_OPCODE_DST
: {
315 out
= instr
->dst(inputs
[0], inputs
[1]);
318 case TGSI_OPCODE_MIN
: {
319 out
= instr
->min(inputs
[0], inputs
[1]);
322 case TGSI_OPCODE_MAX
: {
323 out
= instr
->max(inputs
[0], inputs
[1]);
326 case TGSI_OPCODE_SLT
: {
327 out
= instr
->slt(inputs
[0], inputs
[1]);
330 case TGSI_OPCODE_SGE
: {
331 out
= instr
->sge(inputs
[0], inputs
[1]);
334 case TGSI_OPCODE_MAD
: {
335 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
338 case TGSI_OPCODE_SUB
: {
339 out
= instr
->sub(inputs
[0], inputs
[1]);
342 case TGSI_OPCODE_LERP
: {
343 out
= instr
->lerp(inputs
[0], inputs
[1], inputs
[2]);
346 case TGSI_OPCODE_CND
: {
347 out
= instr
->cnd(inputs
[0], inputs
[1], inputs
[2]);
350 case TGSI_OPCODE_CND0
: {
351 out
= instr
->cnd0(inputs
[0], inputs
[1], inputs
[2]);
354 case TGSI_OPCODE_DOT2ADD
: {
355 out
= instr
->dot2add(inputs
[0], inputs
[1], inputs
[2]);
358 case TGSI_OPCODE_INDEX
:
360 case TGSI_OPCODE_NEGATE
: {
361 out
= instr
->neg(inputs
[0]);
364 case TGSI_OPCODE_FRAC
: {
365 out
= instr
->frc(inputs
[0]);
368 case TGSI_OPCODE_CLAMP
: {
369 out
= instr
->clamp(inputs
[0]);
372 case TGSI_OPCODE_FLOOR
: {
373 out
= instr
->floor(inputs
[0]);
376 case TGSI_OPCODE_ROUND
:
378 case TGSI_OPCODE_EXPBASE2
: {
379 out
= instr
->ex2(inputs
[0]);
382 case TGSI_OPCODE_LOGBASE2
: {
383 out
= instr
->lg2(inputs
[0]);
386 case TGSI_OPCODE_POWER
: {
387 out
= instr
->pow(inputs
[0], inputs
[1]);
390 case TGSI_OPCODE_CROSSPRODUCT
: {
391 out
= instr
->cross(inputs
[0], inputs
[1]);
394 case TGSI_OPCODE_MULTIPLYMATRIX
:
396 case TGSI_OPCODE_ABS
: {
397 out
= instr
->abs(inputs
[0]);
400 case TGSI_OPCODE_RCC
:
402 case TGSI_OPCODE_DPH
: {
403 out
= instr
->dph(inputs
[0], inputs
[1]);
406 case TGSI_OPCODE_COS
: {
407 out
= instr
->cos(inputs
[0]);
410 case TGSI_OPCODE_DDX
: {
411 out
= instr
->ddx(inputs
[0]);
414 case TGSI_OPCODE_DDY
: {
415 out
= instr
->ddy(inputs
[0]);
418 case TGSI_OPCODE_KILP
:
420 case TGSI_OPCODE_PK2H
:
422 case TGSI_OPCODE_PK2US
:
424 case TGSI_OPCODE_PK4B
:
426 case TGSI_OPCODE_PK4UB
:
428 case TGSI_OPCODE_RFL
:
430 case TGSI_OPCODE_SEQ
: {
431 out
= instr
->seq(inputs
[0], inputs
[1]);
434 case TGSI_OPCODE_SFL
: {
435 out
= instr
->sfl(inputs
[0], inputs
[1]);
438 case TGSI_OPCODE_SGT
: {
439 out
= instr
->sgt(inputs
[0], inputs
[1]);
442 case TGSI_OPCODE_SIN
: {
443 out
= instr
->sin(inputs
[0]);
446 case TGSI_OPCODE_SLE
: {
447 out
= instr
->sle(inputs
[0], inputs
[1]);
450 case TGSI_OPCODE_SNE
: {
451 out
= instr
->sne(inputs
[0], inputs
[1]);
454 case TGSI_OPCODE_STR
: {
455 out
= instr
->str(inputs
[0], inputs
[1]);
458 case TGSI_OPCODE_TEX
:
460 case TGSI_OPCODE_TXD
:
462 case TGSI_OPCODE_UP2H
:
464 case TGSI_OPCODE_UP2US
:
466 case TGSI_OPCODE_UP4B
:
468 case TGSI_OPCODE_UP4UB
:
470 case TGSI_OPCODE_X2D
: {
471 out
= instr
->x2d(inputs
[0], inputs
[1], inputs
[2]);
474 case TGSI_OPCODE_ARA
:
476 case TGSI_OPCODE_ARR
:
478 case TGSI_OPCODE_BRA
:
480 case TGSI_OPCODE_CAL
: {
481 instr
->cal(inst
->InstructionExtLabel
.Label
, storage
->inputPtr());
485 case TGSI_OPCODE_RET
: {
490 case TGSI_OPCODE_SSG
:
492 case TGSI_OPCODE_CMP
: {
493 out
= instr
->cmp(inputs
[0], inputs
[1], inputs
[2]);
496 case TGSI_OPCODE_SCS
: {
497 out
= instr
->scs(inputs
[0]);
500 case TGSI_OPCODE_TXB
:
502 case TGSI_OPCODE_NRM4
:
503 case TGSI_OPCODE_NRM
: {
504 out
= instr
->nrm(inputs
[0]);
507 case TGSI_OPCODE_DIV
: {
508 out
= instr
->div(inputs
[0], inputs
[1]);
511 case TGSI_OPCODE_DP2
: {
512 out
= instr
->dp2(inputs
[0], inputs
[1]);
515 case TGSI_OPCODE_TXL
:
517 case TGSI_OPCODE_BRK
: {
522 case TGSI_OPCODE_IF
: {
523 instr
->ifop(inputs
[0]);
524 storage
->setCurrentBlock(instr
->currentBlock());
525 return; //just update the state
528 case TGSI_OPCODE_LOOP
:
530 case TGSI_OPCODE_REP
:
532 case TGSI_OPCODE_ELSE
: {
534 storage
->setCurrentBlock(instr
->currentBlock());
535 return; //only state update
538 case TGSI_OPCODE_ENDIF
: {
540 storage
->setCurrentBlock(instr
->currentBlock());
541 return; //just update the state
544 case TGSI_OPCODE_ENDLOOP
:
546 case TGSI_OPCODE_ENDREP
:
548 case TGSI_OPCODE_PUSHA
:
550 case TGSI_OPCODE_POPA
:
552 case TGSI_OPCODE_CEIL
:
554 case TGSI_OPCODE_I2F
:
556 case TGSI_OPCODE_NOT
:
558 case TGSI_OPCODE_TRUNC
: {
559 out
= instr
->trunc(inputs
[0]);
562 case TGSI_OPCODE_SHL
:
564 case TGSI_OPCODE_SHR
:
566 case TGSI_OPCODE_AND
:
570 case TGSI_OPCODE_MOD
:
572 case TGSI_OPCODE_XOR
:
574 case TGSI_OPCODE_SAD
:
576 case TGSI_OPCODE_TXF
:
578 case TGSI_OPCODE_TXQ
:
580 case TGSI_OPCODE_CONT
:
582 case TGSI_OPCODE_EMIT
:
584 case TGSI_OPCODE_ENDPRIM
:
586 case TGSI_OPCODE_BGNLOOP2
: {
588 storage
->setCurrentBlock(instr
->currentBlock());
592 case TGSI_OPCODE_BGNSUB
: {
593 instr
->bgnSub(instno
);
594 storage
->setCurrentBlock(instr
->currentBlock());
595 storage
->pushTemps();
599 case TGSI_OPCODE_ENDLOOP2
: {
601 storage
->setCurrentBlock(instr
->currentBlock());
605 case TGSI_OPCODE_ENDSUB
: {
607 storage
->setCurrentBlock(instr
->currentBlock());
608 storage
->popArguments();
613 case TGSI_OPCODE_NOISE1
:
615 case TGSI_OPCODE_NOISE2
:
617 case TGSI_OPCODE_NOISE3
:
619 case TGSI_OPCODE_NOISE4
:
621 case TGSI_OPCODE_NOP
:
623 case TGSI_OPCODE_M4X3
:
625 case TGSI_OPCODE_M3X4
:
627 case TGSI_OPCODE_M3X3
:
629 case TGSI_OPCODE_M3X2
:
631 case TGSI_OPCODE_CALLNZ
:
633 case TGSI_OPCODE_IFC
:
635 case TGSI_OPCODE_BREAKC
:
637 case TGSI_OPCODE_KIL
: {
638 out
= instr
->kil(inputs
[0]);
639 storage
->setKilElement(out
);
643 case TGSI_OPCODE_END
:
648 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
649 inst
->Instruction
.Opcode
);
655 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
656 inst
->Instruction
.Opcode
);
657 assert(!"Unsupported opcode");
660 /* # not sure if we need this */
661 switch( inst
->Instruction
.Saturate
) {
664 case TGSI_SAT_ZERO_ONE
:
667 case TGSI_SAT_MINUS_PLUS_ONE
:
668 /*TXT( "_SAT[-1,1]" );*/
675 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
676 struct tgsi_full_dst_register
*dst
= &inst
->FullDstRegisters
[i
];
678 if (dst
->DstRegister
.File
== TGSI_FILE_OUTPUT
) {
679 storage
->setOutputElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
680 // FIXME we should not be generating elements for temporaries, this creates useless memory writes
681 } else if (dst
->DstRegister
.File
== TGSI_FILE_TEMPORARY
) {
682 storage
->setTempElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
683 } else if (dst
->DstRegister
.File
== TGSI_FILE_ADDRESS
) {
684 storage
->setAddrElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
686 fprintf(stderr
, "ERROR: unsupported LLVM destination!");
687 assert(!"wrong destination");
694 translate_instructionir(llvm::Module
*module
,
696 InstructionsSoa
*instr
,
697 struct tgsi_full_instruction
*inst
,
698 struct tgsi_full_instruction
*fi
,
701 std::vector
< std::vector
<llvm::Value
*> > inputs(inst
->Instruction
.NumSrcRegs
);
703 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
704 struct tgsi_full_src_register
*src
= &inst
->FullSrcRegisters
[i
];
705 std::vector
<llvm::Value
*> val
;
706 llvm::Value
*indIdx
= 0;
707 int swizzle
= swizzleInt(src
);
709 if (src
->SrcRegister
.Indirect
) {
710 indIdx
= storage
->addrElement(src
->SrcRegisterInd
.Index
);
712 val
= storage
->load((enum tgsi_file_type
)src
->SrcRegister
.File
,
713 src
->SrcRegister
.Index
, swizzle
, instr
->getIRBuilder(), indIdx
);
718 std::vector
<llvm::Value
*> out(4);
719 switch (inst
->Instruction
.Opcode
) {
720 case TGSI_OPCODE_ARL
: {
721 out
= instr
->arl(inputs
[0]);
724 case TGSI_OPCODE_MOV
: {
728 case TGSI_OPCODE_LIT
: {
729 out
= instr
->lit(inputs
[0]);
732 case TGSI_OPCODE_RCP
: {
735 case TGSI_OPCODE_RSQ
: {
736 out
= instr
->rsq(inputs
[0]);
739 case TGSI_OPCODE_EXP
:
741 case TGSI_OPCODE_LOG
:
743 case TGSI_OPCODE_MUL
: {
744 out
= instr
->mul(inputs
[0], inputs
[1]);
747 case TGSI_OPCODE_ADD
: {
748 out
= instr
->add(inputs
[0], inputs
[1]);
751 case TGSI_OPCODE_DP3
: {
752 out
= instr
->dp3(inputs
[0], inputs
[1]);
755 case TGSI_OPCODE_DP4
: {
756 out
= instr
->dp4(inputs
[0], inputs
[1]);
759 case TGSI_OPCODE_DST
: {
762 case TGSI_OPCODE_MIN
: {
763 out
= instr
->min(inputs
[0], inputs
[1]);
766 case TGSI_OPCODE_MAX
: {
767 out
= instr
->max(inputs
[0], inputs
[1]);
770 case TGSI_OPCODE_SLT
: {
771 out
= instr
->slt(inputs
[0], inputs
[1]);
774 case TGSI_OPCODE_SGE
: {
777 case TGSI_OPCODE_MAD
: {
778 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
781 case TGSI_OPCODE_SUB
: {
782 out
= instr
->sub(inputs
[0], inputs
[1]);
785 case TGSI_OPCODE_LERP
: {
788 case TGSI_OPCODE_CND
:
790 case TGSI_OPCODE_CND0
:
792 case TGSI_OPCODE_DOT2ADD
:
794 case TGSI_OPCODE_INDEX
:
796 case TGSI_OPCODE_NEGATE
:
798 case TGSI_OPCODE_FRAC
: {
801 case TGSI_OPCODE_CLAMP
:
803 case TGSI_OPCODE_FLOOR
: {
806 case TGSI_OPCODE_ROUND
:
808 case TGSI_OPCODE_EXPBASE2
: {
811 case TGSI_OPCODE_LOGBASE2
: {
814 case TGSI_OPCODE_POWER
: {
815 out
= instr
->pow(inputs
[0], inputs
[1]);
818 case TGSI_OPCODE_CROSSPRODUCT
: {
821 case TGSI_OPCODE_MULTIPLYMATRIX
:
823 case TGSI_OPCODE_ABS
: {
824 out
= instr
->abs(inputs
[0]);
827 case TGSI_OPCODE_RCC
:
829 case TGSI_OPCODE_DPH
: {
832 case TGSI_OPCODE_COS
: {
835 case TGSI_OPCODE_DDX
:
837 case TGSI_OPCODE_DDY
:
839 case TGSI_OPCODE_KILP
:
841 case TGSI_OPCODE_PK2H
:
843 case TGSI_OPCODE_PK2US
:
845 case TGSI_OPCODE_PK4B
:
847 case TGSI_OPCODE_PK4UB
:
849 case TGSI_OPCODE_RFL
:
851 case TGSI_OPCODE_SEQ
:
853 case TGSI_OPCODE_SFL
:
855 case TGSI_OPCODE_SGT
: {
858 case TGSI_OPCODE_SIN
: {
861 case TGSI_OPCODE_SLE
:
863 case TGSI_OPCODE_SNE
:
865 case TGSI_OPCODE_STR
:
867 case TGSI_OPCODE_TEX
:
869 case TGSI_OPCODE_TXD
:
871 case TGSI_OPCODE_UP2H
:
873 case TGSI_OPCODE_UP2US
:
875 case TGSI_OPCODE_UP4B
:
877 case TGSI_OPCODE_UP4UB
:
879 case TGSI_OPCODE_X2D
:
881 case TGSI_OPCODE_ARA
:
883 case TGSI_OPCODE_ARR
:
885 case TGSI_OPCODE_BRA
:
887 case TGSI_OPCODE_CAL
: {
890 case TGSI_OPCODE_RET
: {
893 case TGSI_OPCODE_SSG
:
895 case TGSI_OPCODE_CMP
: {
898 case TGSI_OPCODE_SCS
: {
901 case TGSI_OPCODE_TXB
:
903 case TGSI_OPCODE_NRM
:
905 case TGSI_OPCODE_DIV
:
907 case TGSI_OPCODE_DP2
:
909 case TGSI_OPCODE_TXL
:
911 case TGSI_OPCODE_BRK
: {
914 case TGSI_OPCODE_IF
: {
917 case TGSI_OPCODE_LOOP
:
919 case TGSI_OPCODE_REP
:
921 case TGSI_OPCODE_ELSE
: {
924 case TGSI_OPCODE_ENDIF
: {
927 case TGSI_OPCODE_ENDLOOP
:
929 case TGSI_OPCODE_ENDREP
:
931 case TGSI_OPCODE_PUSHA
:
933 case TGSI_OPCODE_POPA
:
935 case TGSI_OPCODE_CEIL
:
937 case TGSI_OPCODE_I2F
:
939 case TGSI_OPCODE_NOT
:
941 case TGSI_OPCODE_TRUNC
: {
944 case TGSI_OPCODE_SHL
:
946 case TGSI_OPCODE_SHR
:
948 case TGSI_OPCODE_AND
:
952 case TGSI_OPCODE_MOD
:
954 case TGSI_OPCODE_XOR
:
956 case TGSI_OPCODE_SAD
:
958 case TGSI_OPCODE_TXF
:
960 case TGSI_OPCODE_TXQ
:
962 case TGSI_OPCODE_CONT
:
964 case TGSI_OPCODE_EMIT
:
966 case TGSI_OPCODE_ENDPRIM
:
968 case TGSI_OPCODE_BGNLOOP2
: {
971 case TGSI_OPCODE_BGNSUB
: {
974 case TGSI_OPCODE_ENDLOOP2
: {
977 case TGSI_OPCODE_ENDSUB
: {
980 case TGSI_OPCODE_NOISE1
:
982 case TGSI_OPCODE_NOISE2
:
984 case TGSI_OPCODE_NOISE3
:
986 case TGSI_OPCODE_NOISE4
:
988 case TGSI_OPCODE_NOP
:
990 case TGSI_OPCODE_M4X3
:
992 case TGSI_OPCODE_M3X4
:
994 case TGSI_OPCODE_M3X3
:
996 case TGSI_OPCODE_M3X2
:
998 case TGSI_OPCODE_NRM4
:
1000 case TGSI_OPCODE_CALLNZ
:
1002 case TGSI_OPCODE_IFC
:
1004 case TGSI_OPCODE_BREAKC
:
1006 case TGSI_OPCODE_KIL
: {
1009 case TGSI_OPCODE_END
:
1014 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
1015 inst
->Instruction
.Opcode
);
1021 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
1022 inst
->Instruction
.Opcode
);
1023 assert(!"Unsupported opcode");
1027 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
1028 struct tgsi_full_dst_register
*dst
= &inst
->FullDstRegisters
[i
];
1029 storage
->store((enum tgsi_file_type
)dst
->DstRegister
.File
,
1030 dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1035 tgsi_to_llvm(struct gallivm_ir
*ir
, const struct tgsi_token
*tokens
)
1037 llvm::Module
*mod
= new Module("shader");
1038 struct tgsi_parse_context parse
;
1039 struct tgsi_full_instruction fi
;
1040 struct tgsi_full_declaration fd
;
1041 unsigned instno
= 0;
1042 Function
* shader
= mod
->getFunction("execute_shader");
1043 std::ostringstream stream
;
1044 if (ir
->type
== GALLIVM_VS
) {
1045 stream
<< "vs_shader";
1047 stream
<< "fs_shader";
1050 std::string func_name
= stream
.str();
1051 shader
->setName(func_name
.c_str());
1053 Function::arg_iterator args
= shader
->arg_begin();
1054 Value
*ptr_INPUT
= args
++;
1055 ptr_INPUT
->setName("input");
1057 BasicBlock
*label_entry
= BasicBlock::Create("entry", shader
, 0);
1059 tgsi_parse_init(&parse
, tokens
);
1061 fi
= tgsi_default_full_instruction();
1062 fd
= tgsi_default_full_declaration();
1063 Storage
storage(label_entry
, ptr_INPUT
);
1064 Instructions
instr(mod
, shader
, label_entry
, &storage
);
1065 while(!tgsi_parse_end_of_tokens(&parse
)) {
1066 tgsi_parse_token(&parse
);
1068 switch (parse
.FullToken
.Token
.Type
) {
1069 case TGSI_TOKEN_TYPE_DECLARATION
:
1070 translate_declaration(ir
, mod
, &storage
,
1071 &parse
.FullToken
.FullDeclaration
,
1075 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1076 translate_immediate(&storage
,
1077 &parse
.FullToken
.FullImmediate
);
1080 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1081 translate_instruction(mod
, &storage
, &instr
,
1082 &parse
.FullToken
.FullInstruction
,
1092 tgsi_parse_free(&parse
);
1094 ir
->num_consts
= storage
.numConsts();
1098 llvm::Module
* tgsi_to_llvmir(struct gallivm_ir
*ir
,
1099 const struct tgsi_token
*tokens
)
1101 llvm::Module
*mod
= new Module("shader");
1102 struct tgsi_parse_context parse
;
1103 struct tgsi_full_instruction fi
;
1104 struct tgsi_full_declaration fd
;
1105 unsigned instno
= 0;
1106 std::ostringstream stream
;
1107 if (ir
->type
== GALLIVM_VS
) {
1108 stream
<< "vs_shader";
1110 stream
<< "fs_shader";
1113 std::string func_name
= stream
.str();
1114 Function
*shader
= llvm::cast
<Function
>(mod
->getOrInsertFunction(
1116 vertexShaderFunctionType()));
1118 Function::arg_iterator args
= shader
->arg_begin();
1119 Value
*input
= args
++;
1120 input
->setName("inputs");
1121 Value
*output
= args
++;
1122 output
->setName("outputs");
1123 Value
*consts
= args
++;
1124 consts
->setName("consts");
1125 Value
*temps
= args
++;
1126 temps
->setName("temps");
1128 BasicBlock
*label_entry
= BasicBlock::Create("entry", shader
, 0);
1130 tgsi_parse_init(&parse
, tokens
);
1132 fi
= tgsi_default_full_instruction();
1133 fd
= tgsi_default_full_declaration();
1135 StorageSoa
storage(label_entry
, input
, output
, consts
, temps
);
1136 InstructionsSoa
instr(mod
, shader
, label_entry
, &storage
);
1138 while(!tgsi_parse_end_of_tokens(&parse
)) {
1139 tgsi_parse_token(&parse
);
1141 switch (parse
.FullToken
.Token
.Type
) {
1142 case TGSI_TOKEN_TYPE_DECLARATION
:
1143 translate_declarationir(ir
, mod
, &storage
,
1144 &parse
.FullToken
.FullDeclaration
,
1148 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1149 translate_immediateir(&storage
,
1150 &parse
.FullToken
.FullImmediate
);
1153 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1154 storage
.declareImmediates();
1155 translate_instructionir(mod
, &storage
, &instr
,
1156 &parse
.FullToken
.FullInstruction
,
1166 tgsi_parse_free(&parse
);