gallium: call tgsi_set_exec_mask() and use exec mask in SSE ARL code
[mesa.git] / src / gallium / auxiliary / gallivm / tgsitollvm.cpp
1 #include "tgsitollvm.h"
2
3 #include "gallivm.h"
4 #include "gallivm_p.h"
5
6 #include "storage.h"
7 #include "instructions.h"
8 #include "storagesoa.h"
9 #include "instructionssoa.h"
10
11 #include "pipe/p_shader_tokens.h"
12
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"
18
19
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>
40
41
42 #include <sstream>
43 #include <fstream>
44 #include <iostream>
45
46 using namespace llvm;
47
48 static inline FunctionType *vertexShaderFunctionType()
49 {
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
57
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);
62
63 ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4);
64 ArrayType *constsArray = ArrayType::get(floatArray, 4);
65 PointerType *constsArrayPtr = PointerType::get(constsArray, 0);
66
67 funcArgs.push_back(vectorArrayPtr);//inputs
68 funcArgs.push_back(vectorArrayPtr);//output
69 funcArgs.push_back(constsArrayPtr);//consts
70 funcArgs.push_back(vectorArrayPtr);//temps
71
72 FunctionType *functionType = FunctionType::get(
73 /*Result=*/Type::VoidTy,
74 /*Params=*/funcArgs,
75 /*isVarArg=*/false);
76
77 return functionType;
78 }
79
80 static inline void
81 add_interpolator(struct gallivm_ir *ir,
82 struct gallivm_interpolate *interp)
83 {
84 ir->interpolators[ir->num_interp] = *interp;
85 ++ir->num_interp;
86 }
87
88 static void
89 translate_declaration(struct gallivm_ir *prog,
90 llvm::Module *module,
91 Storage *storage,
92 struct tgsi_full_declaration *decl,
93 struct tgsi_full_declaration *fd)
94 {
95 if (decl->Declaration.File == TGSI_FILE_INPUT) {
96 unsigned first, last, mask;
97 uint interp_method;
98
99 first = decl->DeclarationRange.First;
100 last = decl->DeclarationRange.Last;
101 mask = decl->Declaration.UsageMask;
102
103 /* Do not touch WPOS.xy */
104 if (first == 0) {
105 mask &= ~TGSI_WRITEMASK_XY;
106 if (mask == TGSI_WRITEMASK_NONE) {
107 first++;
108 if (first > last) {
109 return;
110 }
111 }
112 }
113
114 interp_method = decl->Declaration.Interpolate;
115
116 if (mask == TGSI_WRITEMASK_XYZW) {
117 unsigned i, j;
118
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;
124 interp.attrib = i;
125 interp.chan = j;
126 add_interpolator(prog, &interp);
127 }
128 }
129 } else {
130 unsigned i, j;
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;
136 interp.attrib = i;
137 interp.chan = j;
138 add_interpolator(prog, &interp);
139 }
140 }
141 }
142 }
143 }
144 }
145
146 static void
147 translate_declarationir(struct gallivm_ir *,
148 llvm::Module *,
149 StorageSoa *storage,
150 struct tgsi_full_declaration *decl,
151 struct tgsi_full_declaration *)
152 {
153 if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
154 int idx = decl->DeclarationRange.First;
155 storage->addAddress(idx);
156 }
157 }
158
159 static void
160 translate_immediate(Storage *storage,
161 struct tgsi_full_immediate *imm)
162 {
163 float vec[4];
164 int i;
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;
169 break;
170 default:
171 assert(0);
172 }
173 }
174 storage->addImmediate(vec);
175 }
176
177
178 static void
179 translate_immediateir(StorageSoa *storage,
180 struct tgsi_full_immediate *imm)
181 {
182 float vec[4];
183 int i;
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;
188 break;
189 default:
190 assert(0);
191 }
192 }
193 storage->addImmediate(vec);
194 }
195
196 static inline int
197 swizzleInt(struct tgsi_full_src_register *src)
198 {
199 int swizzle = 0;
200 int start = 1000;
201
202 for (int k = 0; k < 4; ++k) {
203 swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start;
204 start /= 10;
205 }
206 return swizzle;
207 }
208
209 static inline llvm::Value *
210 swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src,
211 Storage *storage)
212 {
213 int swizzle = swizzleInt(src);
214
215 if (gallivm_is_swizzle(swizzle)) {
216 /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/
217 val = storage->shuffleVector(val, swizzle);
218 }
219 return val;
220 }
221
222 static void
223 translate_instruction(llvm::Module *module,
224 Storage *storage,
225 Instructions *instr,
226 struct tgsi_full_instruction *inst,
227 struct tgsi_full_instruction *fi,
228 unsigned instno)
229 {
230 llvm::Value *inputs[4];
231 inputs[0] = 0;
232 inputs[1] = 0;
233 inputs[2] = 0;
234 inputs[3] = 0;
235
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;
240
241 if (src->SrcRegister.Indirect) {
242 indIdx = storage->addrElement(src->SrcRegisterInd.Index);
243 indIdx = storage->extractIndex(indIdx);
244 }
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 } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
250 val = storage->tempElement(src->SrcRegister.Index);
251 } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) {
252 val = storage->outputElement(src->SrcRegister.Index, indIdx);
253 } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
254 val = storage->immediateElement(src->SrcRegister.Index);
255 } else {
256 fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
257 return;
258 }
259
260 inputs[i] = swizzleVector(val, src, storage);
261 }
262
263 /*if (inputs[0])
264 instr->printVector(inputs[0]);
265 if (inputs[1])
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]);
271 }
272 break;
273 case TGSI_OPCODE_MOV: {
274 out = inputs[0];
275 }
276 break;
277 case TGSI_OPCODE_LIT: {
278 out = instr->lit(inputs[0]);
279 }
280 break;
281 case TGSI_OPCODE_RCP: {
282 out = instr->rcp(inputs[0]);
283 }
284 break;
285 case TGSI_OPCODE_RSQ: {
286 out = instr->rsq(inputs[0]);
287 }
288 break;
289 case TGSI_OPCODE_EXP: {
290 out = instr->exp(inputs[0]);
291 }
292 break;
293 case TGSI_OPCODE_LOG: {
294 out = instr->log(inputs[0]);
295 }
296 break;
297 case TGSI_OPCODE_MUL: {
298 out = instr->mul(inputs[0], inputs[1]);
299 }
300 break;
301 case TGSI_OPCODE_ADD: {
302 out = instr->add(inputs[0], inputs[1]);
303 }
304 break;
305 case TGSI_OPCODE_DP3: {
306 out = instr->dp3(inputs[0], inputs[1]);
307 }
308 break;
309 case TGSI_OPCODE_DP4: {
310 out = instr->dp4(inputs[0], inputs[1]);
311 }
312 break;
313 case TGSI_OPCODE_DST: {
314 out = instr->dst(inputs[0], inputs[1]);
315 }
316 break;
317 case TGSI_OPCODE_MIN: {
318 out = instr->min(inputs[0], inputs[1]);
319 }
320 break;
321 case TGSI_OPCODE_MAX: {
322 out = instr->max(inputs[0], inputs[1]);
323 }
324 break;
325 case TGSI_OPCODE_SLT: {
326 out = instr->slt(inputs[0], inputs[1]);
327 }
328 break;
329 case TGSI_OPCODE_SGE: {
330 out = instr->sge(inputs[0], inputs[1]);
331 }
332 break;
333 case TGSI_OPCODE_MAD: {
334 out = instr->madd(inputs[0], inputs[1], inputs[2]);
335 }
336 break;
337 case TGSI_OPCODE_SUB: {
338 out = instr->sub(inputs[0], inputs[1]);
339 }
340 break;
341 case TGSI_OPCODE_LERP: {
342 out = instr->lerp(inputs[0], inputs[1], inputs[2]);
343 }
344 break;
345 case TGSI_OPCODE_CND: {
346 out = instr->cnd(inputs[0], inputs[1], inputs[2]);
347 }
348 break;
349 case TGSI_OPCODE_CND0: {
350 out = instr->cnd0(inputs[0], inputs[1], inputs[2]);
351 }
352 break;
353 case TGSI_OPCODE_DOT2ADD: {
354 out = instr->dot2add(inputs[0], inputs[1], inputs[2]);
355 }
356 break;
357 case TGSI_OPCODE_INDEX:
358 break;
359 case TGSI_OPCODE_NEGATE: {
360 out = instr->neg(inputs[0]);
361 }
362 break;
363 case TGSI_OPCODE_FRAC: {
364 out = instr->frc(inputs[0]);
365 }
366 break;
367 case TGSI_OPCODE_CLAMP: {
368 out = instr->clamp(inputs[0]);
369 }
370 break;
371 case TGSI_OPCODE_FLOOR: {
372 out = instr->floor(inputs[0]);
373 }
374 break;
375 case TGSI_OPCODE_ROUND:
376 break;
377 case TGSI_OPCODE_EXPBASE2: {
378 out = instr->ex2(inputs[0]);
379 }
380 break;
381 case TGSI_OPCODE_LOGBASE2: {
382 out = instr->lg2(inputs[0]);
383 }
384 break;
385 case TGSI_OPCODE_POWER: {
386 out = instr->pow(inputs[0], inputs[1]);
387 }
388 break;
389 case TGSI_OPCODE_CROSSPRODUCT: {
390 out = instr->cross(inputs[0], inputs[1]);
391 }
392 break;
393 case TGSI_OPCODE_MULTIPLYMATRIX:
394 break;
395 case TGSI_OPCODE_ABS: {
396 out = instr->abs(inputs[0]);
397 }
398 break;
399 case TGSI_OPCODE_RCC:
400 break;
401 case TGSI_OPCODE_DPH: {
402 out = instr->dph(inputs[0], inputs[1]);
403 }
404 break;
405 case TGSI_OPCODE_COS: {
406 out = instr->cos(inputs[0]);
407 }
408 break;
409 case TGSI_OPCODE_DDX: {
410 out = instr->ddx(inputs[0]);
411 }
412 break;
413 case TGSI_OPCODE_DDY: {
414 out = instr->ddy(inputs[0]);
415 }
416 break;
417 case TGSI_OPCODE_KILP:
418 break;
419 case TGSI_OPCODE_PK2H:
420 break;
421 case TGSI_OPCODE_PK2US:
422 break;
423 case TGSI_OPCODE_PK4B:
424 break;
425 case TGSI_OPCODE_PK4UB:
426 break;
427 case TGSI_OPCODE_RFL:
428 break;
429 case TGSI_OPCODE_SEQ: {
430 out = instr->seq(inputs[0], inputs[1]);
431 }
432 break;
433 case TGSI_OPCODE_SFL: {
434 out = instr->sfl(inputs[0], inputs[1]);
435 }
436 break;
437 case TGSI_OPCODE_SGT: {
438 out = instr->sgt(inputs[0], inputs[1]);
439 }
440 break;
441 case TGSI_OPCODE_SIN: {
442 out = instr->sin(inputs[0]);
443 }
444 break;
445 case TGSI_OPCODE_SLE: {
446 out = instr->sle(inputs[0], inputs[1]);
447 }
448 break;
449 case TGSI_OPCODE_SNE: {
450 out = instr->sne(inputs[0], inputs[1]);
451 }
452 break;
453 case TGSI_OPCODE_STR: {
454 out = instr->str(inputs[0], inputs[1]);
455 }
456 break;
457 case TGSI_OPCODE_TEX:
458 break;
459 case TGSI_OPCODE_TXD:
460 break;
461 case TGSI_OPCODE_UP2H:
462 break;
463 case TGSI_OPCODE_UP2US:
464 break;
465 case TGSI_OPCODE_UP4B:
466 break;
467 case TGSI_OPCODE_UP4UB:
468 break;
469 case TGSI_OPCODE_X2D: {
470 out = instr->x2d(inputs[0], inputs[1], inputs[2]);
471 }
472 break;
473 case TGSI_OPCODE_ARA:
474 break;
475 case TGSI_OPCODE_ARR:
476 break;
477 case TGSI_OPCODE_BRA:
478 break;
479 case TGSI_OPCODE_CAL: {
480 instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr());
481 return;
482 }
483 break;
484 case TGSI_OPCODE_RET: {
485 instr->end();
486 return;
487 }
488 break;
489 case TGSI_OPCODE_SSG:
490 break;
491 case TGSI_OPCODE_CMP: {
492 out = instr->cmp(inputs[0], inputs[1], inputs[2]);
493 }
494 break;
495 case TGSI_OPCODE_SCS: {
496 out = instr->scs(inputs[0]);
497 }
498 break;
499 case TGSI_OPCODE_TXB:
500 break;
501 case TGSI_OPCODE_NRM4:
502 case TGSI_OPCODE_NRM: {
503 out = instr->nrm(inputs[0]);
504 }
505 break;
506 case TGSI_OPCODE_DIV: {
507 out = instr->div(inputs[0], inputs[1]);
508 }
509 break;
510 case TGSI_OPCODE_DP2: {
511 out = instr->dp2(inputs[0], inputs[1]);
512 }
513 break;
514 case TGSI_OPCODE_TXL:
515 break;
516 case TGSI_OPCODE_BRK: {
517 instr->brk();
518 return;
519 }
520 break;
521 case TGSI_OPCODE_IF: {
522 instr->ifop(inputs[0]);
523 storage->setCurrentBlock(instr->currentBlock());
524 return; //just update the state
525 }
526 break;
527 case TGSI_OPCODE_LOOP:
528 break;
529 case TGSI_OPCODE_REP:
530 break;
531 case TGSI_OPCODE_ELSE: {
532 instr->elseop();
533 storage->setCurrentBlock(instr->currentBlock());
534 return; //only state update
535 }
536 break;
537 case TGSI_OPCODE_ENDIF: {
538 instr->endif();
539 storage->setCurrentBlock(instr->currentBlock());
540 return; //just update the state
541 }
542 break;
543 case TGSI_OPCODE_ENDLOOP:
544 break;
545 case TGSI_OPCODE_ENDREP:
546 break;
547 case TGSI_OPCODE_PUSHA:
548 break;
549 case TGSI_OPCODE_POPA:
550 break;
551 case TGSI_OPCODE_CEIL:
552 break;
553 case TGSI_OPCODE_I2F:
554 break;
555 case TGSI_OPCODE_NOT:
556 break;
557 case TGSI_OPCODE_TRUNC: {
558 out = instr->trunc(inputs[0]);
559 }
560 break;
561 case TGSI_OPCODE_SHL:
562 break;
563 case TGSI_OPCODE_SHR:
564 break;
565 case TGSI_OPCODE_AND:
566 break;
567 case TGSI_OPCODE_OR:
568 break;
569 case TGSI_OPCODE_MOD:
570 break;
571 case TGSI_OPCODE_XOR:
572 break;
573 case TGSI_OPCODE_SAD:
574 break;
575 case TGSI_OPCODE_TXF:
576 break;
577 case TGSI_OPCODE_TXQ:
578 break;
579 case TGSI_OPCODE_CONT:
580 break;
581 case TGSI_OPCODE_EMIT:
582 break;
583 case TGSI_OPCODE_ENDPRIM:
584 break;
585 case TGSI_OPCODE_BGNLOOP2: {
586 instr->beginLoop();
587 storage->setCurrentBlock(instr->currentBlock());
588 return;
589 }
590 break;
591 case TGSI_OPCODE_BGNSUB: {
592 instr->bgnSub(instno);
593 storage->setCurrentBlock(instr->currentBlock());
594 storage->pushTemps();
595 return;
596 }
597 break;
598 case TGSI_OPCODE_ENDLOOP2: {
599 instr->endLoop();
600 storage->setCurrentBlock(instr->currentBlock());
601 return;
602 }
603 break;
604 case TGSI_OPCODE_ENDSUB: {
605 instr->endSub();
606 storage->setCurrentBlock(instr->currentBlock());
607 storage->popArguments();
608 storage->popTemps();
609 return;
610 }
611 break;
612 case TGSI_OPCODE_NOISE1:
613 break;
614 case TGSI_OPCODE_NOISE2:
615 break;
616 case TGSI_OPCODE_NOISE3:
617 break;
618 case TGSI_OPCODE_NOISE4:
619 break;
620 case TGSI_OPCODE_NOP:
621 break;
622 case TGSI_OPCODE_M4X3:
623 break;
624 case TGSI_OPCODE_M3X4:
625 break;
626 case TGSI_OPCODE_M3X3:
627 break;
628 case TGSI_OPCODE_M3X2:
629 break;
630 case TGSI_OPCODE_CALLNZ:
631 break;
632 case TGSI_OPCODE_IFC:
633 break;
634 case TGSI_OPCODE_BREAKC:
635 break;
636 case TGSI_OPCODE_KIL: {
637 out = instr->kil(inputs[0]);
638 storage->setKilElement(out);
639 return;
640 }
641 break;
642 case TGSI_OPCODE_END:
643 instr->end();
644 return;
645 break;
646 default:
647 fprintf(stderr, "ERROR: Unknown opcode %d\n",
648 inst->Instruction.Opcode);
649 assert(0);
650 break;
651 }
652
653 if (!out) {
654 fprintf(stderr, "ERROR: unsupported opcode %d\n",
655 inst->Instruction.Opcode);
656 assert(!"Unsupported opcode");
657 }
658
659 /* # not sure if we need this */
660 switch( inst->Instruction.Saturate ) {
661 case TGSI_SAT_NONE:
662 break;
663 case TGSI_SAT_ZERO_ONE:
664 /*TXT( "_SAT" );*/
665 break;
666 case TGSI_SAT_MINUS_PLUS_ONE:
667 /*TXT( "_SAT[-1,1]" );*/
668 break;
669 default:
670 assert( 0 );
671 }
672
673 /* store results */
674 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
675 struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
676
677 if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
678 storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
679 } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) {
680 storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
681 } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) {
682 storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
683 } else {
684 fprintf(stderr, "ERROR: unsupported LLVM destination!");
685 assert(!"wrong destination");
686 }
687 }
688 }
689
690
691 static void
692 translate_instructionir(llvm::Module *module,
693 StorageSoa *storage,
694 InstructionsSoa *instr,
695 struct tgsi_full_instruction *inst,
696 struct tgsi_full_instruction *fi,
697 unsigned instno)
698 {
699 std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs);
700
701 for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
702 struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
703 std::vector<llvm::Value*> val;
704 llvm::Value *indIdx = 0;
705 int swizzle = swizzleInt(src);
706
707 if (src->SrcRegister.Indirect) {
708 indIdx = storage->addrElement(src->SrcRegisterInd.Index);
709 }
710
711 val = storage->load((enum tgsi_file_type)src->SrcRegister.File,
712 src->SrcRegister.Index, swizzle, indIdx);
713
714 inputs[i] = val;
715 }
716
717 std::vector<llvm::Value*> out(4);
718 switch (inst->Instruction.Opcode) {
719 case TGSI_OPCODE_ARL: {
720 out = instr->arl(inputs[0]);
721 }
722 break;
723 case TGSI_OPCODE_MOV: {
724 out = inputs[0];
725 }
726 break;
727 case TGSI_OPCODE_LIT: {
728 out = instr->lit(inputs[0]);
729 }
730 break;
731 case TGSI_OPCODE_RCP: {
732 }
733 break;
734 case TGSI_OPCODE_RSQ: {
735 out = instr->rsq(inputs[0]);
736 }
737 break;
738 case TGSI_OPCODE_EXP:
739 break;
740 case TGSI_OPCODE_LOG:
741 break;
742 case TGSI_OPCODE_MUL: {
743 out = instr->mul(inputs[0], inputs[1]);
744 }
745 break;
746 case TGSI_OPCODE_ADD: {
747 out = instr->add(inputs[0], inputs[1]);
748 }
749 break;
750 case TGSI_OPCODE_DP3: {
751 out = instr->dp3(inputs[0], inputs[1]);
752 }
753 break;
754 case TGSI_OPCODE_DP4: {
755 out = instr->dp4(inputs[0], inputs[1]);
756 }
757 break;
758 case TGSI_OPCODE_DST: {
759 }
760 break;
761 case TGSI_OPCODE_MIN: {
762 out = instr->min(inputs[0], inputs[1]);
763 }
764 break;
765 case TGSI_OPCODE_MAX: {
766 out = instr->max(inputs[0], inputs[1]);
767 }
768 break;
769 case TGSI_OPCODE_SLT: {
770 out = instr->slt(inputs[0], inputs[1]);
771 }
772 break;
773 case TGSI_OPCODE_SGE: {
774 }
775 break;
776 case TGSI_OPCODE_MAD: {
777 out = instr->madd(inputs[0], inputs[1], inputs[2]);
778 }
779 break;
780 case TGSI_OPCODE_SUB: {
781 out = instr->sub(inputs[0], inputs[1]);
782 }
783 break;
784 case TGSI_OPCODE_LERP: {
785 }
786 break;
787 case TGSI_OPCODE_CND:
788 break;
789 case TGSI_OPCODE_CND0:
790 break;
791 case TGSI_OPCODE_DOT2ADD:
792 break;
793 case TGSI_OPCODE_INDEX:
794 break;
795 case TGSI_OPCODE_NEGATE:
796 break;
797 case TGSI_OPCODE_FRAC: {
798 }
799 break;
800 case TGSI_OPCODE_CLAMP:
801 break;
802 case TGSI_OPCODE_FLOOR: {
803 }
804 break;
805 case TGSI_OPCODE_ROUND:
806 break;
807 case TGSI_OPCODE_EXPBASE2: {
808 }
809 break;
810 case TGSI_OPCODE_LOGBASE2: {
811 }
812 break;
813 case TGSI_OPCODE_POWER: {
814 out = instr->pow(inputs[0], inputs[1]);
815 }
816 break;
817 case TGSI_OPCODE_CROSSPRODUCT: {
818 }
819 break;
820 case TGSI_OPCODE_MULTIPLYMATRIX:
821 break;
822 case TGSI_OPCODE_ABS: {
823 out = instr->abs(inputs[0]);
824 }
825 break;
826 case TGSI_OPCODE_RCC:
827 break;
828 case TGSI_OPCODE_DPH: {
829 }
830 break;
831 case TGSI_OPCODE_COS: {
832 }
833 break;
834 case TGSI_OPCODE_DDX:
835 break;
836 case TGSI_OPCODE_DDY:
837 break;
838 case TGSI_OPCODE_KILP:
839 break;
840 case TGSI_OPCODE_PK2H:
841 break;
842 case TGSI_OPCODE_PK2US:
843 break;
844 case TGSI_OPCODE_PK4B:
845 break;
846 case TGSI_OPCODE_PK4UB:
847 break;
848 case TGSI_OPCODE_RFL:
849 break;
850 case TGSI_OPCODE_SEQ:
851 break;
852 case TGSI_OPCODE_SFL:
853 break;
854 case TGSI_OPCODE_SGT: {
855 }
856 break;
857 case TGSI_OPCODE_SIN: {
858 }
859 break;
860 case TGSI_OPCODE_SLE:
861 break;
862 case TGSI_OPCODE_SNE:
863 break;
864 case TGSI_OPCODE_STR:
865 break;
866 case TGSI_OPCODE_TEX:
867 break;
868 case TGSI_OPCODE_TXD:
869 break;
870 case TGSI_OPCODE_UP2H:
871 break;
872 case TGSI_OPCODE_UP2US:
873 break;
874 case TGSI_OPCODE_UP4B:
875 break;
876 case TGSI_OPCODE_UP4UB:
877 break;
878 case TGSI_OPCODE_X2D:
879 break;
880 case TGSI_OPCODE_ARA:
881 break;
882 case TGSI_OPCODE_ARR:
883 break;
884 case TGSI_OPCODE_BRA:
885 break;
886 case TGSI_OPCODE_CAL: {
887 }
888 break;
889 case TGSI_OPCODE_RET: {
890 }
891 break;
892 case TGSI_OPCODE_SSG:
893 break;
894 case TGSI_OPCODE_CMP: {
895 }
896 break;
897 case TGSI_OPCODE_SCS: {
898 }
899 break;
900 case TGSI_OPCODE_TXB:
901 break;
902 case TGSI_OPCODE_NRM:
903 break;
904 case TGSI_OPCODE_DIV:
905 break;
906 case TGSI_OPCODE_DP2:
907 break;
908 case TGSI_OPCODE_TXL:
909 break;
910 case TGSI_OPCODE_BRK: {
911 }
912 break;
913 case TGSI_OPCODE_IF: {
914 }
915 break;
916 case TGSI_OPCODE_LOOP:
917 break;
918 case TGSI_OPCODE_REP:
919 break;
920 case TGSI_OPCODE_ELSE: {
921 }
922 break;
923 case TGSI_OPCODE_ENDIF: {
924 }
925 break;
926 case TGSI_OPCODE_ENDLOOP:
927 break;
928 case TGSI_OPCODE_ENDREP:
929 break;
930 case TGSI_OPCODE_PUSHA:
931 break;
932 case TGSI_OPCODE_POPA:
933 break;
934 case TGSI_OPCODE_CEIL:
935 break;
936 case TGSI_OPCODE_I2F:
937 break;
938 case TGSI_OPCODE_NOT:
939 break;
940 case TGSI_OPCODE_TRUNC: {
941 }
942 break;
943 case TGSI_OPCODE_SHL:
944 break;
945 case TGSI_OPCODE_SHR:
946 break;
947 case TGSI_OPCODE_AND:
948 break;
949 case TGSI_OPCODE_OR:
950 break;
951 case TGSI_OPCODE_MOD:
952 break;
953 case TGSI_OPCODE_XOR:
954 break;
955 case TGSI_OPCODE_SAD:
956 break;
957 case TGSI_OPCODE_TXF:
958 break;
959 case TGSI_OPCODE_TXQ:
960 break;
961 case TGSI_OPCODE_CONT:
962 break;
963 case TGSI_OPCODE_EMIT:
964 break;
965 case TGSI_OPCODE_ENDPRIM:
966 break;
967 case TGSI_OPCODE_BGNLOOP2: {
968 }
969 break;
970 case TGSI_OPCODE_BGNSUB: {
971 }
972 break;
973 case TGSI_OPCODE_ENDLOOP2: {
974 }
975 break;
976 case TGSI_OPCODE_ENDSUB: {
977 }
978 break;
979 case TGSI_OPCODE_NOISE1:
980 break;
981 case TGSI_OPCODE_NOISE2:
982 break;
983 case TGSI_OPCODE_NOISE3:
984 break;
985 case TGSI_OPCODE_NOISE4:
986 break;
987 case TGSI_OPCODE_NOP:
988 break;
989 case TGSI_OPCODE_M4X3:
990 break;
991 case TGSI_OPCODE_M3X4:
992 break;
993 case TGSI_OPCODE_M3X3:
994 break;
995 case TGSI_OPCODE_M3X2:
996 break;
997 case TGSI_OPCODE_NRM4:
998 break;
999 case TGSI_OPCODE_CALLNZ:
1000 break;
1001 case TGSI_OPCODE_IFC:
1002 break;
1003 case TGSI_OPCODE_BREAKC:
1004 break;
1005 case TGSI_OPCODE_KIL: {
1006 }
1007 break;
1008 case TGSI_OPCODE_END:
1009 instr->end();
1010 return;
1011 break;
1012 default:
1013 fprintf(stderr, "ERROR: Unknown opcode %d\n",
1014 inst->Instruction.Opcode);
1015 assert(0);
1016 break;
1017 }
1018
1019 if (!out[0]) {
1020 fprintf(stderr, "ERROR: unsupported opcode %d\n",
1021 inst->Instruction.Opcode);
1022 assert(!"Unsupported opcode");
1023 }
1024
1025 /* store results */
1026 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
1027 struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
1028
1029 storage->store((enum tgsi_file_type)dst->DstRegister.File,
1030 dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
1031 }
1032 }
1033
1034 llvm::Module *
1035 tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens)
1036 {
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";
1046 } else {
1047 stream << "fs_shader";
1048 }
1049 stream << ir->id;
1050 std::string func_name = stream.str();
1051 shader->setName(func_name.c_str());
1052
1053 Function::arg_iterator args = shader->arg_begin();
1054 Value *ptr_INPUT = args++;
1055 ptr_INPUT->setName("input");
1056
1057 BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0);
1058
1059 tgsi_parse_init(&parse, tokens);
1060
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);
1067
1068 switch (parse.FullToken.Token.Type) {
1069 case TGSI_TOKEN_TYPE_DECLARATION:
1070 translate_declaration(ir, mod, &storage,
1071 &parse.FullToken.FullDeclaration,
1072 &fd);
1073 break;
1074
1075 case TGSI_TOKEN_TYPE_IMMEDIATE:
1076 translate_immediate(&storage,
1077 &parse.FullToken.FullImmediate);
1078 break;
1079
1080 case TGSI_TOKEN_TYPE_INSTRUCTION:
1081 translate_instruction(mod, &storage, &instr,
1082 &parse.FullToken.FullInstruction,
1083 &fi, instno);
1084 ++instno;
1085 break;
1086
1087 default:
1088 assert(0);
1089 }
1090 }
1091
1092 tgsi_parse_free(&parse);
1093
1094 ir->num_consts = storage.numConsts();
1095 return mod;
1096 }
1097
1098 llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir,
1099 const struct tgsi_token *tokens)
1100 {
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";
1109 } else {
1110 stream << "fs_shader";
1111 }
1112 //stream << ir->id;
1113 std::string func_name = stream.str();
1114 Function *shader = llvm::cast<Function>(mod->getOrInsertFunction(
1115 func_name.c_str(),
1116 vertexShaderFunctionType()));
1117
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");
1127
1128 BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0);
1129
1130 tgsi_parse_init(&parse, tokens);
1131
1132 fi = tgsi_default_full_instruction();
1133 fd = tgsi_default_full_declaration();
1134
1135 StorageSoa storage(label_entry, input, output, consts, temps);
1136 InstructionsSoa instr(mod, shader, label_entry, &storage);
1137
1138 while(!tgsi_parse_end_of_tokens(&parse)) {
1139 tgsi_parse_token(&parse);
1140
1141 switch (parse.FullToken.Token.Type) {
1142 case TGSI_TOKEN_TYPE_DECLARATION:
1143 translate_declarationir(ir, mod, &storage,
1144 &parse.FullToken.FullDeclaration,
1145 &fd);
1146 break;
1147
1148 case TGSI_TOKEN_TYPE_IMMEDIATE:
1149 translate_immediateir(&storage,
1150 &parse.FullToken.FullImmediate);
1151 break;
1152
1153 case TGSI_TOKEN_TYPE_INSTRUCTION:
1154 storage.declareImmediates();
1155 translate_instructionir(mod, &storage, &instr,
1156 &parse.FullToken.FullInstruction,
1157 &fi, instno);
1158 ++instno;
1159 break;
1160
1161 default:
1162 assert(0);
1163 }
1164 }
1165
1166 tgsi_parse_free(&parse);
1167
1168 return mod;
1169 }