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