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