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/util/tgsi_parse.h"
14 #include "tgsi/exec/tgsi_exec.h"
15 #include "tgsi/util/tgsi_util.h"
16 #include "tgsi/util/tgsi_build.h"
17 #include "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>
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 [4 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
, 4);
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 assert(decl
->Declaration
.Declare
== TGSI_DECLARE_RANGE
);
101 first
= decl
->u
.DeclarationRange
.First
;
102 last
= decl
->u
.DeclarationRange
.Last
;
103 mask
= decl
->Declaration
.UsageMask
;
105 /* Do not touch WPOS.xy */
107 mask
&= ~TGSI_WRITEMASK_XY
;
108 if (mask
== TGSI_WRITEMASK_NONE
) {
116 interp_method
= decl
->Interpolation
.Interpolate
;
118 if (mask
== TGSI_WRITEMASK_XYZW
) {
121 for (i
= first
; i
<= last
; i
++) {
122 for (j
= 0; j
< NUM_CHANNELS
; j
++) {
123 //interp( mach, i, j );
124 struct gallivm_interpolate interp
;
125 interp
.type
= interp_method
;
128 add_interpolator(prog
, &interp
);
133 for( j
= 0; j
< NUM_CHANNELS
; j
++ ) {
134 if( mask
& (1 << j
) ) {
135 for( i
= first
; i
<= last
; i
++ ) {
136 struct gallivm_interpolate interp
;
137 interp
.type
= interp_method
;
140 add_interpolator(prog
, &interp
);
149 translate_declarationir(struct gallivm_ir
*,
152 struct tgsi_full_declaration
*decl
,
153 struct tgsi_full_declaration
*)
155 if (decl
->Declaration
.File
== TGSI_FILE_ADDRESS
) {
156 int idx
= decl
->u
.DeclarationRange
.First
;
157 storage
->addAddress(idx
);
162 translate_immediate(Storage
*storage
,
163 struct tgsi_full_immediate
*imm
)
167 for (i
= 0; i
< imm
->Immediate
.Size
- 1; ++i
) {
168 switch (imm
->Immediate
.DataType
) {
169 case TGSI_IMM_FLOAT32
:
170 vec
[i
] = imm
->u
.ImmediateFloat32
[i
].Float
;
176 storage
->addImmediate(vec
);
181 translate_immediateir(StorageSoa
*storage
,
182 struct tgsi_full_immediate
*imm
)
186 for (i
= 0; i
< imm
->Immediate
.Size
- 1; ++i
) {
187 switch (imm
->Immediate
.DataType
) {
188 case TGSI_IMM_FLOAT32
:
189 vec
[i
] = imm
->u
.ImmediateFloat32
[i
].Float
;
195 storage
->addImmediate(vec
);
199 swizzleInt(struct tgsi_full_src_register
*src
)
204 for (int k
= 0; k
< 4; ++k
) {
205 swizzle
+= tgsi_util_get_full_src_register_extswizzle(src
, k
) * start
;
211 static inline llvm::Value
*
212 swizzleVector(llvm::Value
*val
, struct tgsi_full_src_register
*src
,
215 int swizzle
= swizzleInt(src
);
217 if (gallivm_is_swizzle(swizzle
)) {
218 /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/
219 val
= storage
->shuffleVector(val
, swizzle
);
225 translate_instruction(llvm::Module
*module
,
228 struct tgsi_full_instruction
*inst
,
229 struct tgsi_full_instruction
*fi
,
232 llvm::Value
*inputs
[4];
238 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
239 struct tgsi_full_src_register
*src
= &inst
->FullSrcRegisters
[i
];
240 llvm::Value
*val
= 0;
241 llvm::Value
*indIdx
= 0;
243 if (src
->SrcRegister
.Indirect
) {
244 indIdx
= storage
->addrElement(src
->SrcRegisterInd
.Index
);
245 indIdx
= storage
->extractIndex(indIdx
);
247 if (src
->SrcRegister
.File
== TGSI_FILE_CONSTANT
) {
248 val
= storage
->constElement(src
->SrcRegister
.Index
, indIdx
);
249 } else if (src
->SrcRegister
.File
== TGSI_FILE_INPUT
) {
250 val
= storage
->inputElement(src
->SrcRegister
.Index
, indIdx
);
251 } else if (src
->SrcRegister
.File
== TGSI_FILE_TEMPORARY
) {
252 val
= storage
->tempElement(src
->SrcRegister
.Index
);
253 } else if (src
->SrcRegister
.File
== TGSI_FILE_OUTPUT
) {
254 val
= storage
->outputElement(src
->SrcRegister
.Index
, indIdx
);
255 } else if (src
->SrcRegister
.File
== TGSI_FILE_IMMEDIATE
) {
256 val
= storage
->immediateElement(src
->SrcRegister
.Index
);
258 fprintf(stderr
, "ERROR: not supported llvm source %d\n", src
->SrcRegister
.File
);
262 inputs
[i
] = swizzleVector(val
, src
, storage
);
266 instr->printVector(inputs[0]);
268 instr->printVector(inputs[1]);*/
269 llvm::Value
*out
= 0;
270 switch (inst
->Instruction
.Opcode
) {
271 case TGSI_OPCODE_ARL
: {
272 out
= instr
->arl(inputs
[0]);
275 case TGSI_OPCODE_MOV
: {
279 case TGSI_OPCODE_LIT
: {
280 out
= instr
->lit(inputs
[0]);
283 case TGSI_OPCODE_RCP
: {
284 out
= instr
->rcp(inputs
[0]);
287 case TGSI_OPCODE_RSQ
: {
288 out
= instr
->rsq(inputs
[0]);
291 case TGSI_OPCODE_EXP
:
293 case TGSI_OPCODE_LOG
:
295 case TGSI_OPCODE_MUL
: {
296 out
= instr
->mul(inputs
[0], inputs
[1]);
299 case TGSI_OPCODE_ADD
: {
300 out
= instr
->add(inputs
[0], inputs
[1]);
303 case TGSI_OPCODE_DP3
: {
304 out
= instr
->dp3(inputs
[0], inputs
[1]);
307 case TGSI_OPCODE_DP4
: {
308 out
= instr
->dp4(inputs
[0], inputs
[1]);
311 case TGSI_OPCODE_DST
: {
312 out
= instr
->dst(inputs
[0], inputs
[1]);
315 case TGSI_OPCODE_MIN
: {
316 out
= instr
->min(inputs
[0], inputs
[1]);
319 case TGSI_OPCODE_MAX
: {
320 out
= instr
->max(inputs
[0], inputs
[1]);
323 case TGSI_OPCODE_SLT
: {
324 out
= instr
->slt(inputs
[0], inputs
[1]);
327 case TGSI_OPCODE_SGE
: {
328 out
= instr
->sge(inputs
[0], inputs
[1]);
331 case TGSI_OPCODE_MAD
: {
332 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
335 case TGSI_OPCODE_SUB
: {
336 out
= instr
->sub(inputs
[0], inputs
[1]);
339 case TGSI_OPCODE_LERP
: {
340 out
= instr
->lerp(inputs
[0], inputs
[1], inputs
[2]);
343 case TGSI_OPCODE_CND
:
345 case TGSI_OPCODE_CND0
:
347 case TGSI_OPCODE_DOT2ADD
:
349 case TGSI_OPCODE_INDEX
:
351 case TGSI_OPCODE_NEGATE
:
353 case TGSI_OPCODE_FRAC
: {
354 out
= instr
->frc(inputs
[0]);
357 case TGSI_OPCODE_CLAMP
:
359 case TGSI_OPCODE_FLOOR
: {
360 out
= instr
->floor(inputs
[0]);
363 case TGSI_OPCODE_ROUND
:
365 case TGSI_OPCODE_EXPBASE2
: {
366 out
= instr
->ex2(inputs
[0]);
369 case TGSI_OPCODE_LOGBASE2
: {
370 out
= instr
->lg2(inputs
[0]);
373 case TGSI_OPCODE_POWER
: {
374 out
= instr
->pow(inputs
[0], inputs
[1]);
377 case TGSI_OPCODE_CROSSPRODUCT
: {
378 out
= instr
->cross(inputs
[0], inputs
[1]);
381 case TGSI_OPCODE_MULTIPLYMATRIX
:
383 case TGSI_OPCODE_ABS
: {
384 out
= instr
->abs(inputs
[0]);
387 case TGSI_OPCODE_RCC
:
389 case TGSI_OPCODE_DPH
: {
390 out
= instr
->dph(inputs
[0], inputs
[1]);
393 case TGSI_OPCODE_COS
: {
394 out
= instr
->cos(inputs
[0]);
397 case TGSI_OPCODE_DDX
:
399 case TGSI_OPCODE_DDY
:
401 case TGSI_OPCODE_KILP
: {
402 out
= instr
->kilp(inputs
[0]);
403 storage
->setKilElement(out
);
407 case TGSI_OPCODE_PK2H
:
409 case TGSI_OPCODE_PK2US
:
411 case TGSI_OPCODE_PK4B
:
413 case TGSI_OPCODE_PK4UB
:
415 case TGSI_OPCODE_RFL
:
417 case TGSI_OPCODE_SEQ
:
419 case TGSI_OPCODE_SFL
:
421 case TGSI_OPCODE_SGT
: {
422 out
= instr
->sgt(inputs
[0], inputs
[1]);
425 case TGSI_OPCODE_SIN
: {
426 out
= instr
->sin(inputs
[0]);
429 case TGSI_OPCODE_SLE
:
431 case TGSI_OPCODE_SNE
:
433 case TGSI_OPCODE_STR
:
435 case TGSI_OPCODE_TEX
:
437 case TGSI_OPCODE_TXD
:
439 case TGSI_OPCODE_UP2H
:
441 case TGSI_OPCODE_UP2US
:
443 case TGSI_OPCODE_UP4B
:
445 case TGSI_OPCODE_UP4UB
:
447 case TGSI_OPCODE_X2D
:
449 case TGSI_OPCODE_ARA
:
451 case TGSI_OPCODE_ARR
:
453 case TGSI_OPCODE_BRA
:
455 case TGSI_OPCODE_CAL
: {
456 instr
->cal(inst
->InstructionExtLabel
.Label
, storage
->inputPtr());
460 case TGSI_OPCODE_RET
: {
465 case TGSI_OPCODE_SSG
:
467 case TGSI_OPCODE_CMP
: {
468 out
= instr
->cmp(inputs
[0], inputs
[1], inputs
[2]);
471 case TGSI_OPCODE_SCS
: {
472 out
= instr
->scs(inputs
[0]);
475 case TGSI_OPCODE_TXB
:
477 case TGSI_OPCODE_NRM
:
479 case TGSI_OPCODE_DIV
:
481 case TGSI_OPCODE_DP2
:
483 case TGSI_OPCODE_TXL
:
485 case TGSI_OPCODE_BRK
: {
490 case TGSI_OPCODE_IF
: {
491 instr
->ifop(inputs
[0]);
492 storage
->setCurrentBlock(instr
->currentBlock());
493 return; //just update the state
496 case TGSI_OPCODE_LOOP
:
498 case TGSI_OPCODE_REP
:
500 case TGSI_OPCODE_ELSE
: {
502 storage
->setCurrentBlock(instr
->currentBlock());
503 return; //only state update
506 case TGSI_OPCODE_ENDIF
: {
508 storage
->setCurrentBlock(instr
->currentBlock());
509 return; //just update the state
512 case TGSI_OPCODE_ENDLOOP
:
514 case TGSI_OPCODE_ENDREP
:
516 case TGSI_OPCODE_PUSHA
:
518 case TGSI_OPCODE_POPA
:
520 case TGSI_OPCODE_CEIL
:
522 case TGSI_OPCODE_I2F
:
524 case TGSI_OPCODE_NOT
:
526 case TGSI_OPCODE_TRUNC
: {
527 out
= instr
->trunc(inputs
[0]);
530 case TGSI_OPCODE_SHL
:
532 case TGSI_OPCODE_SHR
:
534 case TGSI_OPCODE_AND
:
538 case TGSI_OPCODE_MOD
:
540 case TGSI_OPCODE_XOR
:
542 case TGSI_OPCODE_SAD
:
544 case TGSI_OPCODE_TXF
:
546 case TGSI_OPCODE_TXQ
:
548 case TGSI_OPCODE_CONT
:
550 case TGSI_OPCODE_EMIT
:
552 case TGSI_OPCODE_ENDPRIM
:
554 case TGSI_OPCODE_BGNLOOP2
: {
556 storage
->setCurrentBlock(instr
->currentBlock());
560 case TGSI_OPCODE_BGNSUB
: {
561 instr
->bgnSub(instno
);
562 storage
->setCurrentBlock(instr
->currentBlock());
563 storage
->pushTemps();
567 case TGSI_OPCODE_ENDLOOP2
: {
569 storage
->setCurrentBlock(instr
->currentBlock());
573 case TGSI_OPCODE_ENDSUB
: {
575 storage
->setCurrentBlock(instr
->currentBlock());
576 storage
->popArguments();
581 case TGSI_OPCODE_NOISE1
:
583 case TGSI_OPCODE_NOISE2
:
585 case TGSI_OPCODE_NOISE3
:
587 case TGSI_OPCODE_NOISE4
:
589 case TGSI_OPCODE_NOP
:
591 case TGSI_OPCODE_TEXBEM
:
593 case TGSI_OPCODE_TEXBEML
:
595 case TGSI_OPCODE_TEXREG2AR
:
597 case TGSI_OPCODE_TEXM3X2PAD
:
599 case TGSI_OPCODE_TEXM3X2TEX
:
601 case TGSI_OPCODE_TEXM3X3PAD
:
603 case TGSI_OPCODE_TEXM3X3TEX
:
605 case TGSI_OPCODE_TEXM3X3SPEC
:
607 case TGSI_OPCODE_TEXM3X3VSPEC
:
609 case TGSI_OPCODE_TEXREG2GB
:
611 case TGSI_OPCODE_TEXREG2RGB
:
613 case TGSI_OPCODE_TEXDP3TEX
:
615 case TGSI_OPCODE_TEXDP3
:
617 case TGSI_OPCODE_TEXM3X3
:
619 case TGSI_OPCODE_TEXM3X2DEPTH
:
621 case TGSI_OPCODE_TEXDEPTH
:
623 case TGSI_OPCODE_BEM
:
625 case TGSI_OPCODE_M4X3
:
627 case TGSI_OPCODE_M3X4
:
629 case TGSI_OPCODE_M3X3
:
631 case TGSI_OPCODE_M3X2
:
633 case TGSI_OPCODE_NRM4
:
635 case TGSI_OPCODE_CALLNZ
:
637 case TGSI_OPCODE_IFC
:
639 case TGSI_OPCODE_BREAKC
:
641 case TGSI_OPCODE_KIL
:
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 } else if (dst
->DstRegister
.File
== TGSI_FILE_TEMPORARY
) {
681 storage
->setTempElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
682 } else if (dst
->DstRegister
.File
== TGSI_FILE_ADDRESS
) {
683 storage
->setAddrElement(dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
685 fprintf(stderr
, "ERROR: unsupported LLVM destination!");
686 assert(!"wrong destination");
693 translate_instructionir(llvm::Module
*module
,
695 InstructionsSoa
*instr
,
696 struct tgsi_full_instruction
*inst
,
697 struct tgsi_full_instruction
*fi
,
700 std::vector
< std::vector
<llvm::Value
*> > inputs(inst
->Instruction
.NumSrcRegs
);
702 for (int i
= 0; i
< inst
->Instruction
.NumSrcRegs
; ++i
) {
703 struct tgsi_full_src_register
*src
= &inst
->FullSrcRegisters
[i
];
704 std::vector
<llvm::Value
*> val
;
705 llvm::Value
*indIdx
= 0;
706 int swizzle
= swizzleInt(src
);
708 if (src
->SrcRegister
.Indirect
) {
709 indIdx
= storage
->addrElement(src
->SrcRegisterInd
.Index
);
711 if (src
->SrcRegister
.File
== TGSI_FILE_CONSTANT
) {
712 val
= storage
->load(StorageSoa::Const
,
713 src
->SrcRegister
.Index
, swizzle
, indIdx
);
714 } else if (src
->SrcRegister
.File
== TGSI_FILE_INPUT
) {
715 val
= storage
->load(StorageSoa::Input
,
716 src
->SrcRegister
.Index
, swizzle
, indIdx
);
717 } else if (src
->SrcRegister
.File
== TGSI_FILE_TEMPORARY
) {
718 val
= storage
->load(StorageSoa::Temp
,
719 src
->SrcRegister
.Index
, swizzle
, indIdx
);
720 } else if (src
->SrcRegister
.File
== TGSI_FILE_OUTPUT
) {
721 val
= storage
->load(StorageSoa::Output
,
722 src
->SrcRegister
.Index
, swizzle
, indIdx
);
723 } else if (src
->SrcRegister
.File
== TGSI_FILE_IMMEDIATE
) {
724 val
= storage
->load(StorageSoa::Immediate
,
725 src
->SrcRegister
.Index
, swizzle
, indIdx
);
727 fprintf(stderr
, "ERROR: not supported llvm source %d\n", src
->SrcRegister
.File
);
734 std::vector
<llvm::Value
*> out(4);
735 switch (inst
->Instruction
.Opcode
) {
736 case TGSI_OPCODE_ARL
: {
737 out
= instr
->arl(inputs
[0]);
740 case TGSI_OPCODE_MOV
: {
744 case TGSI_OPCODE_LIT
: {
747 case TGSI_OPCODE_RCP
: {
750 case TGSI_OPCODE_RSQ
: {
753 case TGSI_OPCODE_EXP
:
755 case TGSI_OPCODE_LOG
:
757 case TGSI_OPCODE_MUL
: {
758 out
= instr
->mul(inputs
[0], inputs
[1]);
761 case TGSI_OPCODE_ADD
: {
762 out
= instr
->add(inputs
[0], inputs
[1]);
765 case TGSI_OPCODE_DP3
: {
768 case TGSI_OPCODE_DP4
: {
771 case TGSI_OPCODE_DST
: {
774 case TGSI_OPCODE_MIN
: {
777 case TGSI_OPCODE_MAX
: {
780 case TGSI_OPCODE_SLT
: {
783 case TGSI_OPCODE_SGE
: {
786 case TGSI_OPCODE_MAD
: {
787 out
= instr
->madd(inputs
[0], inputs
[1], inputs
[2]);
790 case TGSI_OPCODE_SUB
: {
793 case TGSI_OPCODE_LERP
: {
796 case TGSI_OPCODE_CND
:
798 case TGSI_OPCODE_CND0
:
800 case TGSI_OPCODE_DOT2ADD
:
802 case TGSI_OPCODE_INDEX
:
804 case TGSI_OPCODE_NEGATE
:
806 case TGSI_OPCODE_FRAC
: {
809 case TGSI_OPCODE_CLAMP
:
811 case TGSI_OPCODE_FLOOR
: {
814 case TGSI_OPCODE_ROUND
:
816 case TGSI_OPCODE_EXPBASE2
: {
819 case TGSI_OPCODE_LOGBASE2
: {
822 case TGSI_OPCODE_POWER
: {
825 case TGSI_OPCODE_CROSSPRODUCT
: {
828 case TGSI_OPCODE_MULTIPLYMATRIX
:
830 case TGSI_OPCODE_ABS
: {
833 case TGSI_OPCODE_RCC
:
835 case TGSI_OPCODE_DPH
: {
838 case TGSI_OPCODE_COS
: {
841 case TGSI_OPCODE_DDX
:
843 case TGSI_OPCODE_DDY
:
845 case TGSI_OPCODE_KILP
: {
848 case TGSI_OPCODE_PK2H
:
850 case TGSI_OPCODE_PK2US
:
852 case TGSI_OPCODE_PK4B
:
854 case TGSI_OPCODE_PK4UB
:
856 case TGSI_OPCODE_RFL
:
858 case TGSI_OPCODE_SEQ
:
860 case TGSI_OPCODE_SFL
:
862 case TGSI_OPCODE_SGT
: {
865 case TGSI_OPCODE_SIN
: {
868 case TGSI_OPCODE_SLE
:
870 case TGSI_OPCODE_SNE
:
872 case TGSI_OPCODE_STR
:
874 case TGSI_OPCODE_TEX
:
876 case TGSI_OPCODE_TXD
:
878 case TGSI_OPCODE_UP2H
:
880 case TGSI_OPCODE_UP2US
:
882 case TGSI_OPCODE_UP4B
:
884 case TGSI_OPCODE_UP4UB
:
886 case TGSI_OPCODE_X2D
:
888 case TGSI_OPCODE_ARA
:
890 case TGSI_OPCODE_ARR
:
892 case TGSI_OPCODE_BRA
:
894 case TGSI_OPCODE_CAL
: {
897 case TGSI_OPCODE_RET
: {
900 case TGSI_OPCODE_SSG
:
902 case TGSI_OPCODE_CMP
: {
905 case TGSI_OPCODE_SCS
: {
908 case TGSI_OPCODE_TXB
:
910 case TGSI_OPCODE_NRM
:
912 case TGSI_OPCODE_DIV
:
914 case TGSI_OPCODE_DP2
:
916 case TGSI_OPCODE_TXL
:
918 case TGSI_OPCODE_BRK
: {
921 case TGSI_OPCODE_IF
: {
924 case TGSI_OPCODE_LOOP
:
926 case TGSI_OPCODE_REP
:
928 case TGSI_OPCODE_ELSE
: {
931 case TGSI_OPCODE_ENDIF
: {
934 case TGSI_OPCODE_ENDLOOP
:
936 case TGSI_OPCODE_ENDREP
:
938 case TGSI_OPCODE_PUSHA
:
940 case TGSI_OPCODE_POPA
:
942 case TGSI_OPCODE_CEIL
:
944 case TGSI_OPCODE_I2F
:
946 case TGSI_OPCODE_NOT
:
948 case TGSI_OPCODE_TRUNC
: {
951 case TGSI_OPCODE_SHL
:
953 case TGSI_OPCODE_SHR
:
955 case TGSI_OPCODE_AND
:
959 case TGSI_OPCODE_MOD
:
961 case TGSI_OPCODE_XOR
:
963 case TGSI_OPCODE_SAD
:
965 case TGSI_OPCODE_TXF
:
967 case TGSI_OPCODE_TXQ
:
969 case TGSI_OPCODE_CONT
:
971 case TGSI_OPCODE_EMIT
:
973 case TGSI_OPCODE_ENDPRIM
:
975 case TGSI_OPCODE_BGNLOOP2
: {
978 case TGSI_OPCODE_BGNSUB
: {
981 case TGSI_OPCODE_ENDLOOP2
: {
984 case TGSI_OPCODE_ENDSUB
: {
987 case TGSI_OPCODE_NOISE1
:
989 case TGSI_OPCODE_NOISE2
:
991 case TGSI_OPCODE_NOISE3
:
993 case TGSI_OPCODE_NOISE4
:
995 case TGSI_OPCODE_NOP
:
997 case TGSI_OPCODE_TEXBEM
:
999 case TGSI_OPCODE_TEXBEML
:
1001 case TGSI_OPCODE_TEXREG2AR
:
1003 case TGSI_OPCODE_TEXM3X2PAD
:
1005 case TGSI_OPCODE_TEXM3X2TEX
:
1007 case TGSI_OPCODE_TEXM3X3PAD
:
1009 case TGSI_OPCODE_TEXM3X3TEX
:
1011 case TGSI_OPCODE_TEXM3X3SPEC
:
1013 case TGSI_OPCODE_TEXM3X3VSPEC
:
1015 case TGSI_OPCODE_TEXREG2GB
:
1017 case TGSI_OPCODE_TEXREG2RGB
:
1019 case TGSI_OPCODE_TEXDP3TEX
:
1021 case TGSI_OPCODE_TEXDP3
:
1023 case TGSI_OPCODE_TEXM3X3
:
1025 case TGSI_OPCODE_TEXM3X2DEPTH
:
1027 case TGSI_OPCODE_TEXDEPTH
:
1029 case TGSI_OPCODE_BEM
:
1031 case TGSI_OPCODE_M4X3
:
1033 case TGSI_OPCODE_M3X4
:
1035 case TGSI_OPCODE_M3X3
:
1037 case TGSI_OPCODE_M3X2
:
1039 case TGSI_OPCODE_NRM4
:
1041 case TGSI_OPCODE_CALLNZ
:
1043 case TGSI_OPCODE_IFC
:
1045 case TGSI_OPCODE_BREAKC
:
1047 case TGSI_OPCODE_KIL
:
1049 case TGSI_OPCODE_END
:
1054 fprintf(stderr
, "ERROR: Unknown opcode %d\n",
1055 inst
->Instruction
.Opcode
);
1061 fprintf(stderr
, "ERROR: unsupported opcode %d\n",
1062 inst
->Instruction
.Opcode
);
1063 assert(!"Unsupported opcode");
1067 for (int i
= 0; i
< inst
->Instruction
.NumDstRegs
; ++i
) {
1068 struct tgsi_full_dst_register
*dst
= &inst
->FullDstRegisters
[i
];
1070 if (dst
->DstRegister
.File
== TGSI_FILE_OUTPUT
) {
1071 storage
->store(StorageSoa::Output
,
1072 dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1073 } else if (dst
->DstRegister
.File
== TGSI_FILE_TEMPORARY
) {
1074 storage
->store(StorageSoa::Temp
,
1075 dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1076 } else if (dst
->DstRegister
.File
== TGSI_FILE_ADDRESS
) {
1077 storage
->store(StorageSoa::Address
,
1078 dst
->DstRegister
.Index
, out
, dst
->DstRegister
.WriteMask
);
1080 fprintf(stderr
, "ERROR: unsupported LLVM destination!");
1081 assert(!"wrong destination");
1087 tgsi_to_llvm(struct gallivm_ir
*ir
, const struct tgsi_token
*tokens
)
1089 llvm::Module
*mod
= new Module("shader");
1090 struct tgsi_parse_context parse
;
1091 struct tgsi_full_instruction fi
;
1092 struct tgsi_full_declaration fd
;
1093 unsigned instno
= 0;
1094 Function
* shader
= mod
->getFunction("execute_shader");
1095 std::ostringstream stream
;
1096 if (ir
->type
== GALLIVM_VS
) {
1097 stream
<< "vs_shader";
1099 stream
<< "fs_shader";
1102 std::string func_name
= stream
.str();
1103 shader
->setName(func_name
.c_str());
1105 Function::arg_iterator args
= shader
->arg_begin();
1106 Value
*ptr_INPUT
= args
++;
1107 ptr_INPUT
->setName("input");
1109 BasicBlock
*label_entry
= new BasicBlock("entry", shader
, 0);
1111 tgsi_parse_init(&parse
, tokens
);
1113 fi
= tgsi_default_full_instruction();
1114 fd
= tgsi_default_full_declaration();
1115 Storage
storage(label_entry
, ptr_INPUT
);
1116 Instructions
instr(mod
, shader
, label_entry
, &storage
);
1117 while(!tgsi_parse_end_of_tokens(&parse
)) {
1118 tgsi_parse_token(&parse
);
1120 switch (parse
.FullToken
.Token
.Type
) {
1121 case TGSI_TOKEN_TYPE_DECLARATION
:
1122 translate_declaration(ir
, mod
, &storage
,
1123 &parse
.FullToken
.FullDeclaration
,
1127 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1128 translate_immediate(&storage
,
1129 &parse
.FullToken
.FullImmediate
);
1132 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1133 translate_instruction(mod
, &storage
, &instr
,
1134 &parse
.FullToken
.FullInstruction
,
1144 tgsi_parse_free(&parse
);
1146 ir
->num_consts
= storage
.numConsts();
1150 llvm::Module
* tgsi_to_llvmir(struct gallivm_ir
*ir
,
1151 const struct tgsi_token
*tokens
)
1153 llvm::Module
*mod
= new Module("shader");
1154 struct tgsi_parse_context parse
;
1155 struct tgsi_full_instruction fi
;
1156 struct tgsi_full_declaration fd
;
1157 unsigned instno
= 0;
1158 std::ostringstream stream
;
1159 if (ir
->type
== GALLIVM_VS
) {
1160 stream
<< "vs_shader";
1162 stream
<< "fs_shader";
1165 std::string func_name
= stream
.str();
1166 Function
*shader
= llvm::cast
<Function
>(mod
->getOrInsertFunction(
1168 vertexShaderFunctionType()));
1170 Function::arg_iterator args
= shader
->arg_begin();
1171 Value
*input
= args
++;
1172 input
->setName("inputs");
1173 Value
*output
= args
++;
1174 output
->setName("outputs");
1175 Value
*consts
= args
++;
1176 consts
->setName("consts");
1177 Value
*temps
= args
++;
1178 temps
->setName("temps");
1180 BasicBlock
*label_entry
= new BasicBlock("entry", shader
, 0);
1182 tgsi_parse_init(&parse
, tokens
);
1184 fi
= tgsi_default_full_instruction();
1185 fd
= tgsi_default_full_declaration();
1187 StorageSoa
storage(label_entry
, input
, output
, consts
, temps
);
1188 InstructionsSoa
instr(mod
, shader
, label_entry
, &storage
);
1190 while(!tgsi_parse_end_of_tokens(&parse
)) {
1191 tgsi_parse_token(&parse
);
1193 switch (parse
.FullToken
.Token
.Type
) {
1194 case TGSI_TOKEN_TYPE_DECLARATION
:
1195 translate_declarationir(ir
, mod
, &storage
,
1196 &parse
.FullToken
.FullDeclaration
,
1200 case TGSI_TOKEN_TYPE_IMMEDIATE
:
1201 translate_immediateir(&storage
,
1202 &parse
.FullToken
.FullImmediate
);
1205 case TGSI_TOKEN_TYPE_INSTRUCTION
:
1206 storage
.declareImmediates();
1207 translate_instructionir(mod
, &storage
, &instr
,
1208 &parse
.FullToken
.FullInstruction
,
1218 tgsi_parse_free(&parse
);