Merge commit 'origin/master' into gallium-0.2
[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 [1 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, 1);
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 // 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);
256 } else {
257 fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
258 return;
259 }
260
261 inputs[i] = swizzleVector(val, src, storage);
262 }
263
264 /*if (inputs[0])
265 instr->printVector(inputs[0]);
266 if (inputs[1])
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]);
272 }
273 break;
274 case TGSI_OPCODE_MOV: {
275 out = inputs[0];
276 }
277 break;
278 case TGSI_OPCODE_LIT: {
279 out = instr->lit(inputs[0]);
280 }
281 break;
282 case TGSI_OPCODE_RCP: {
283 out = instr->rcp(inputs[0]);
284 }
285 break;
286 case TGSI_OPCODE_RSQ: {
287 out = instr->rsq(inputs[0]);
288 }
289 break;
290 case TGSI_OPCODE_EXP: {
291 out = instr->exp(inputs[0]);
292 }
293 break;
294 case TGSI_OPCODE_LOG: {
295 out = instr->log(inputs[0]);
296 }
297 break;
298 case TGSI_OPCODE_MUL: {
299 out = instr->mul(inputs[0], inputs[1]);
300 }
301 break;
302 case TGSI_OPCODE_ADD: {
303 out = instr->add(inputs[0], inputs[1]);
304 }
305 break;
306 case TGSI_OPCODE_DP3: {
307 out = instr->dp3(inputs[0], inputs[1]);
308 }
309 break;
310 case TGSI_OPCODE_DP4: {
311 out = instr->dp4(inputs[0], inputs[1]);
312 }
313 break;
314 case TGSI_OPCODE_DST: {
315 out = instr->dst(inputs[0], inputs[1]);
316 }
317 break;
318 case TGSI_OPCODE_MIN: {
319 out = instr->min(inputs[0], inputs[1]);
320 }
321 break;
322 case TGSI_OPCODE_MAX: {
323 out = instr->max(inputs[0], inputs[1]);
324 }
325 break;
326 case TGSI_OPCODE_SLT: {
327 out = instr->slt(inputs[0], inputs[1]);
328 }
329 break;
330 case TGSI_OPCODE_SGE: {
331 out = instr->sge(inputs[0], inputs[1]);
332 }
333 break;
334 case TGSI_OPCODE_MAD: {
335 out = instr->madd(inputs[0], inputs[1], inputs[2]);
336 }
337 break;
338 case TGSI_OPCODE_SUB: {
339 out = instr->sub(inputs[0], inputs[1]);
340 }
341 break;
342 case TGSI_OPCODE_LERP: {
343 out = instr->lerp(inputs[0], inputs[1], inputs[2]);
344 }
345 break;
346 case TGSI_OPCODE_CND: {
347 out = instr->cnd(inputs[0], inputs[1], inputs[2]);
348 }
349 break;
350 case TGSI_OPCODE_CND0: {
351 out = instr->cnd0(inputs[0], inputs[1], inputs[2]);
352 }
353 break;
354 case TGSI_OPCODE_DOT2ADD: {
355 out = instr->dot2add(inputs[0], inputs[1], inputs[2]);
356 }
357 break;
358 case TGSI_OPCODE_INDEX:
359 break;
360 case TGSI_OPCODE_NEGATE: {
361 out = instr->neg(inputs[0]);
362 }
363 break;
364 case TGSI_OPCODE_FRAC: {
365 out = instr->frc(inputs[0]);
366 }
367 break;
368 case TGSI_OPCODE_CLAMP: {
369 out = instr->clamp(inputs[0]);
370 }
371 break;
372 case TGSI_OPCODE_FLOOR: {
373 out = instr->floor(inputs[0]);
374 }
375 break;
376 case TGSI_OPCODE_ROUND:
377 break;
378 case TGSI_OPCODE_EXPBASE2: {
379 out = instr->ex2(inputs[0]);
380 }
381 break;
382 case TGSI_OPCODE_LOGBASE2: {
383 out = instr->lg2(inputs[0]);
384 }
385 break;
386 case TGSI_OPCODE_POWER: {
387 out = instr->pow(inputs[0], inputs[1]);
388 }
389 break;
390 case TGSI_OPCODE_CROSSPRODUCT: {
391 out = instr->cross(inputs[0], inputs[1]);
392 }
393 break;
394 case TGSI_OPCODE_MULTIPLYMATRIX:
395 break;
396 case TGSI_OPCODE_ABS: {
397 out = instr->abs(inputs[0]);
398 }
399 break;
400 case TGSI_OPCODE_RCC:
401 break;
402 case TGSI_OPCODE_DPH: {
403 out = instr->dph(inputs[0], inputs[1]);
404 }
405 break;
406 case TGSI_OPCODE_COS: {
407 out = instr->cos(inputs[0]);
408 }
409 break;
410 case TGSI_OPCODE_DDX: {
411 out = instr->ddx(inputs[0]);
412 }
413 break;
414 case TGSI_OPCODE_DDY: {
415 out = instr->ddy(inputs[0]);
416 }
417 break;
418 case TGSI_OPCODE_KILP:
419 break;
420 case TGSI_OPCODE_PK2H:
421 break;
422 case TGSI_OPCODE_PK2US:
423 break;
424 case TGSI_OPCODE_PK4B:
425 break;
426 case TGSI_OPCODE_PK4UB:
427 break;
428 case TGSI_OPCODE_RFL:
429 break;
430 case TGSI_OPCODE_SEQ: {
431 out = instr->seq(inputs[0], inputs[1]);
432 }
433 break;
434 case TGSI_OPCODE_SFL: {
435 out = instr->sfl(inputs[0], inputs[1]);
436 }
437 break;
438 case TGSI_OPCODE_SGT: {
439 out = instr->sgt(inputs[0], inputs[1]);
440 }
441 break;
442 case TGSI_OPCODE_SIN: {
443 out = instr->sin(inputs[0]);
444 }
445 break;
446 case TGSI_OPCODE_SLE: {
447 out = instr->sle(inputs[0], inputs[1]);
448 }
449 break;
450 case TGSI_OPCODE_SNE: {
451 out = instr->sne(inputs[0], inputs[1]);
452 }
453 break;
454 case TGSI_OPCODE_STR: {
455 out = instr->str(inputs[0], inputs[1]);
456 }
457 break;
458 case TGSI_OPCODE_TEX:
459 break;
460 case TGSI_OPCODE_TXD:
461 break;
462 case TGSI_OPCODE_UP2H:
463 break;
464 case TGSI_OPCODE_UP2US:
465 break;
466 case TGSI_OPCODE_UP4B:
467 break;
468 case TGSI_OPCODE_UP4UB:
469 break;
470 case TGSI_OPCODE_X2D: {
471 out = instr->x2d(inputs[0], inputs[1], inputs[2]);
472 }
473 break;
474 case TGSI_OPCODE_ARA:
475 break;
476 case TGSI_OPCODE_ARR:
477 break;
478 case TGSI_OPCODE_BRA:
479 break;
480 case TGSI_OPCODE_CAL: {
481 instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr());
482 return;
483 }
484 break;
485 case TGSI_OPCODE_RET: {
486 instr->end();
487 return;
488 }
489 break;
490 case TGSI_OPCODE_SSG:
491 break;
492 case TGSI_OPCODE_CMP: {
493 out = instr->cmp(inputs[0], inputs[1], inputs[2]);
494 }
495 break;
496 case TGSI_OPCODE_SCS: {
497 out = instr->scs(inputs[0]);
498 }
499 break;
500 case TGSI_OPCODE_TXB:
501 break;
502 case TGSI_OPCODE_NRM4:
503 case TGSI_OPCODE_NRM: {
504 out = instr->nrm(inputs[0]);
505 }
506 break;
507 case TGSI_OPCODE_DIV: {
508 out = instr->div(inputs[0], inputs[1]);
509 }
510 break;
511 case TGSI_OPCODE_DP2: {
512 out = instr->dp2(inputs[0], inputs[1]);
513 }
514 break;
515 case TGSI_OPCODE_TXL:
516 break;
517 case TGSI_OPCODE_BRK: {
518 instr->brk();
519 return;
520 }
521 break;
522 case TGSI_OPCODE_IF: {
523 instr->ifop(inputs[0]);
524 storage->setCurrentBlock(instr->currentBlock());
525 return; //just update the state
526 }
527 break;
528 case TGSI_OPCODE_LOOP:
529 break;
530 case TGSI_OPCODE_REP:
531 break;
532 case TGSI_OPCODE_ELSE: {
533 instr->elseop();
534 storage->setCurrentBlock(instr->currentBlock());
535 return; //only state update
536 }
537 break;
538 case TGSI_OPCODE_ENDIF: {
539 instr->endif();
540 storage->setCurrentBlock(instr->currentBlock());
541 return; //just update the state
542 }
543 break;
544 case TGSI_OPCODE_ENDLOOP:
545 break;
546 case TGSI_OPCODE_ENDREP:
547 break;
548 case TGSI_OPCODE_PUSHA:
549 break;
550 case TGSI_OPCODE_POPA:
551 break;
552 case TGSI_OPCODE_CEIL:
553 break;
554 case TGSI_OPCODE_I2F:
555 break;
556 case TGSI_OPCODE_NOT:
557 break;
558 case TGSI_OPCODE_TRUNC: {
559 out = instr->trunc(inputs[0]);
560 }
561 break;
562 case TGSI_OPCODE_SHL:
563 break;
564 case TGSI_OPCODE_SHR:
565 break;
566 case TGSI_OPCODE_AND:
567 break;
568 case TGSI_OPCODE_OR:
569 break;
570 case TGSI_OPCODE_MOD:
571 break;
572 case TGSI_OPCODE_XOR:
573 break;
574 case TGSI_OPCODE_SAD:
575 break;
576 case TGSI_OPCODE_TXF:
577 break;
578 case TGSI_OPCODE_TXQ:
579 break;
580 case TGSI_OPCODE_CONT:
581 break;
582 case TGSI_OPCODE_EMIT:
583 break;
584 case TGSI_OPCODE_ENDPRIM:
585 break;
586 case TGSI_OPCODE_BGNLOOP2: {
587 instr->beginLoop();
588 storage->setCurrentBlock(instr->currentBlock());
589 return;
590 }
591 break;
592 case TGSI_OPCODE_BGNSUB: {
593 instr->bgnSub(instno);
594 storage->setCurrentBlock(instr->currentBlock());
595 storage->pushTemps();
596 return;
597 }
598 break;
599 case TGSI_OPCODE_ENDLOOP2: {
600 instr->endLoop();
601 storage->setCurrentBlock(instr->currentBlock());
602 return;
603 }
604 break;
605 case TGSI_OPCODE_ENDSUB: {
606 instr->endSub();
607 storage->setCurrentBlock(instr->currentBlock());
608 storage->popArguments();
609 storage->popTemps();
610 return;
611 }
612 break;
613 case TGSI_OPCODE_NOISE1:
614 break;
615 case TGSI_OPCODE_NOISE2:
616 break;
617 case TGSI_OPCODE_NOISE3:
618 break;
619 case TGSI_OPCODE_NOISE4:
620 break;
621 case TGSI_OPCODE_NOP:
622 break;
623 case TGSI_OPCODE_M4X3:
624 break;
625 case TGSI_OPCODE_M3X4:
626 break;
627 case TGSI_OPCODE_M3X3:
628 break;
629 case TGSI_OPCODE_M3X2:
630 break;
631 case TGSI_OPCODE_CALLNZ:
632 break;
633 case TGSI_OPCODE_IFC:
634 break;
635 case TGSI_OPCODE_BREAKC:
636 break;
637 case TGSI_OPCODE_KIL: {
638 out = instr->kil(inputs[0]);
639 storage->setKilElement(out);
640 return;
641 }
642 break;
643 case TGSI_OPCODE_END:
644 instr->end();
645 return;
646 break;
647 default:
648 fprintf(stderr, "ERROR: Unknown opcode %d\n",
649 inst->Instruction.Opcode);
650 assert(0);
651 break;
652 }
653
654 if (!out) {
655 fprintf(stderr, "ERROR: unsupported opcode %d\n",
656 inst->Instruction.Opcode);
657 assert(!"Unsupported opcode");
658 }
659
660 /* # not sure if we need this */
661 switch( inst->Instruction.Saturate ) {
662 case TGSI_SAT_NONE:
663 break;
664 case TGSI_SAT_ZERO_ONE:
665 /*TXT( "_SAT" );*/
666 break;
667 case TGSI_SAT_MINUS_PLUS_ONE:
668 /*TXT( "_SAT[-1,1]" );*/
669 break;
670 default:
671 assert( 0 );
672 }
673
674 /* store results */
675 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
676 struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
677
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);
685 } else {
686 fprintf(stderr, "ERROR: unsupported LLVM destination!");
687 assert(!"wrong destination");
688 }
689 }
690 }
691
692
693 static void
694 translate_instructionir(llvm::Module *module,
695 StorageSoa *storage,
696 InstructionsSoa *instr,
697 struct tgsi_full_instruction *inst,
698 struct tgsi_full_instruction *fi,
699 unsigned instno)
700 {
701 std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs);
702
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);
708
709 if (src->SrcRegister.Indirect) {
710 indIdx = storage->addrElement(src->SrcRegisterInd.Index);
711 }
712 val = storage->load((enum tgsi_file_type)src->SrcRegister.File,
713 src->SrcRegister.Index, swizzle, instr->getIRBuilder(), indIdx);
714
715 inputs[i] = val;
716 }
717
718 std::vector<llvm::Value*> out(4);
719 switch (inst->Instruction.Opcode) {
720 case TGSI_OPCODE_ARL: {
721 out = instr->arl(inputs[0]);
722 }
723 break;
724 case TGSI_OPCODE_MOV: {
725 out = inputs[0];
726 }
727 break;
728 case TGSI_OPCODE_LIT: {
729 out = instr->lit(inputs[0]);
730 }
731 break;
732 case TGSI_OPCODE_RCP: {
733 }
734 break;
735 case TGSI_OPCODE_RSQ: {
736 out = instr->rsq(inputs[0]);
737 }
738 break;
739 case TGSI_OPCODE_EXP:
740 break;
741 case TGSI_OPCODE_LOG:
742 break;
743 case TGSI_OPCODE_MUL: {
744 out = instr->mul(inputs[0], inputs[1]);
745 }
746 break;
747 case TGSI_OPCODE_ADD: {
748 out = instr->add(inputs[0], inputs[1]);
749 }
750 break;
751 case TGSI_OPCODE_DP3: {
752 out = instr->dp3(inputs[0], inputs[1]);
753 }
754 break;
755 case TGSI_OPCODE_DP4: {
756 out = instr->dp4(inputs[0], inputs[1]);
757 }
758 break;
759 case TGSI_OPCODE_DST: {
760 }
761 break;
762 case TGSI_OPCODE_MIN: {
763 out = instr->min(inputs[0], inputs[1]);
764 }
765 break;
766 case TGSI_OPCODE_MAX: {
767 out = instr->max(inputs[0], inputs[1]);
768 }
769 break;
770 case TGSI_OPCODE_SLT: {
771 out = instr->slt(inputs[0], inputs[1]);
772 }
773 break;
774 case TGSI_OPCODE_SGE: {
775 }
776 break;
777 case TGSI_OPCODE_MAD: {
778 out = instr->madd(inputs[0], inputs[1], inputs[2]);
779 }
780 break;
781 case TGSI_OPCODE_SUB: {
782 out = instr->sub(inputs[0], inputs[1]);
783 }
784 break;
785 case TGSI_OPCODE_LERP: {
786 }
787 break;
788 case TGSI_OPCODE_CND:
789 break;
790 case TGSI_OPCODE_CND0:
791 break;
792 case TGSI_OPCODE_DOT2ADD:
793 break;
794 case TGSI_OPCODE_INDEX:
795 break;
796 case TGSI_OPCODE_NEGATE:
797 break;
798 case TGSI_OPCODE_FRAC: {
799 }
800 break;
801 case TGSI_OPCODE_CLAMP:
802 break;
803 case TGSI_OPCODE_FLOOR: {
804 }
805 break;
806 case TGSI_OPCODE_ROUND:
807 break;
808 case TGSI_OPCODE_EXPBASE2: {
809 }
810 break;
811 case TGSI_OPCODE_LOGBASE2: {
812 }
813 break;
814 case TGSI_OPCODE_POWER: {
815 out = instr->pow(inputs[0], inputs[1]);
816 }
817 break;
818 case TGSI_OPCODE_CROSSPRODUCT: {
819 }
820 break;
821 case TGSI_OPCODE_MULTIPLYMATRIX:
822 break;
823 case TGSI_OPCODE_ABS: {
824 out = instr->abs(inputs[0]);
825 }
826 break;
827 case TGSI_OPCODE_RCC:
828 break;
829 case TGSI_OPCODE_DPH: {
830 }
831 break;
832 case TGSI_OPCODE_COS: {
833 }
834 break;
835 case TGSI_OPCODE_DDX:
836 break;
837 case TGSI_OPCODE_DDY:
838 break;
839 case TGSI_OPCODE_KILP:
840 break;
841 case TGSI_OPCODE_PK2H:
842 break;
843 case TGSI_OPCODE_PK2US:
844 break;
845 case TGSI_OPCODE_PK4B:
846 break;
847 case TGSI_OPCODE_PK4UB:
848 break;
849 case TGSI_OPCODE_RFL:
850 break;
851 case TGSI_OPCODE_SEQ:
852 break;
853 case TGSI_OPCODE_SFL:
854 break;
855 case TGSI_OPCODE_SGT: {
856 }
857 break;
858 case TGSI_OPCODE_SIN: {
859 }
860 break;
861 case TGSI_OPCODE_SLE:
862 break;
863 case TGSI_OPCODE_SNE:
864 break;
865 case TGSI_OPCODE_STR:
866 break;
867 case TGSI_OPCODE_TEX:
868 break;
869 case TGSI_OPCODE_TXD:
870 break;
871 case TGSI_OPCODE_UP2H:
872 break;
873 case TGSI_OPCODE_UP2US:
874 break;
875 case TGSI_OPCODE_UP4B:
876 break;
877 case TGSI_OPCODE_UP4UB:
878 break;
879 case TGSI_OPCODE_X2D:
880 break;
881 case TGSI_OPCODE_ARA:
882 break;
883 case TGSI_OPCODE_ARR:
884 break;
885 case TGSI_OPCODE_BRA:
886 break;
887 case TGSI_OPCODE_CAL: {
888 }
889 break;
890 case TGSI_OPCODE_RET: {
891 }
892 break;
893 case TGSI_OPCODE_SSG:
894 break;
895 case TGSI_OPCODE_CMP: {
896 }
897 break;
898 case TGSI_OPCODE_SCS: {
899 }
900 break;
901 case TGSI_OPCODE_TXB:
902 break;
903 case TGSI_OPCODE_NRM:
904 break;
905 case TGSI_OPCODE_DIV:
906 break;
907 case TGSI_OPCODE_DP2:
908 break;
909 case TGSI_OPCODE_TXL:
910 break;
911 case TGSI_OPCODE_BRK: {
912 }
913 break;
914 case TGSI_OPCODE_IF: {
915 }
916 break;
917 case TGSI_OPCODE_LOOP:
918 break;
919 case TGSI_OPCODE_REP:
920 break;
921 case TGSI_OPCODE_ELSE: {
922 }
923 break;
924 case TGSI_OPCODE_ENDIF: {
925 }
926 break;
927 case TGSI_OPCODE_ENDLOOP:
928 break;
929 case TGSI_OPCODE_ENDREP:
930 break;
931 case TGSI_OPCODE_PUSHA:
932 break;
933 case TGSI_OPCODE_POPA:
934 break;
935 case TGSI_OPCODE_CEIL:
936 break;
937 case TGSI_OPCODE_I2F:
938 break;
939 case TGSI_OPCODE_NOT:
940 break;
941 case TGSI_OPCODE_TRUNC: {
942 }
943 break;
944 case TGSI_OPCODE_SHL:
945 break;
946 case TGSI_OPCODE_SHR:
947 break;
948 case TGSI_OPCODE_AND:
949 break;
950 case TGSI_OPCODE_OR:
951 break;
952 case TGSI_OPCODE_MOD:
953 break;
954 case TGSI_OPCODE_XOR:
955 break;
956 case TGSI_OPCODE_SAD:
957 break;
958 case TGSI_OPCODE_TXF:
959 break;
960 case TGSI_OPCODE_TXQ:
961 break;
962 case TGSI_OPCODE_CONT:
963 break;
964 case TGSI_OPCODE_EMIT:
965 break;
966 case TGSI_OPCODE_ENDPRIM:
967 break;
968 case TGSI_OPCODE_BGNLOOP2: {
969 }
970 break;
971 case TGSI_OPCODE_BGNSUB: {
972 }
973 break;
974 case TGSI_OPCODE_ENDLOOP2: {
975 }
976 break;
977 case TGSI_OPCODE_ENDSUB: {
978 }
979 break;
980 case TGSI_OPCODE_NOISE1:
981 break;
982 case TGSI_OPCODE_NOISE2:
983 break;
984 case TGSI_OPCODE_NOISE3:
985 break;
986 case TGSI_OPCODE_NOISE4:
987 break;
988 case TGSI_OPCODE_NOP:
989 break;
990 case TGSI_OPCODE_M4X3:
991 break;
992 case TGSI_OPCODE_M3X4:
993 break;
994 case TGSI_OPCODE_M3X3:
995 break;
996 case TGSI_OPCODE_M3X2:
997 break;
998 case TGSI_OPCODE_NRM4:
999 break;
1000 case TGSI_OPCODE_CALLNZ:
1001 break;
1002 case TGSI_OPCODE_IFC:
1003 break;
1004 case TGSI_OPCODE_BREAKC:
1005 break;
1006 case TGSI_OPCODE_KIL: {
1007 }
1008 break;
1009 case TGSI_OPCODE_END:
1010 instr->end();
1011 return;
1012 break;
1013 default:
1014 fprintf(stderr, "ERROR: Unknown opcode %d\n",
1015 inst->Instruction.Opcode);
1016 assert(0);
1017 break;
1018 }
1019
1020 if (!out[0]) {
1021 fprintf(stderr, "ERROR: unsupported opcode %d\n",
1022 inst->Instruction.Opcode);
1023 assert(!"Unsupported opcode");
1024 }
1025
1026 /* store results */
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);
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 }