20fce9c9cc6959611b9ecf523f5531bee1fa37f2
[mesa.git] / src / mesa / pipe / llvm / 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 "pipe/tgsi/util/tgsi_parse.h"
14 #include "pipe/tgsi/exec/tgsi_exec.h"
15 #include "pipe/tgsi/util/tgsi_util.h"
16 #include "pipe/tgsi/util/tgsi_build.h"
17 #include "pipe/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 *,
152 struct tgsi_full_declaration *,
153 struct tgsi_full_declaration *)
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.Size - 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.Size - 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 break;
289 case TGSI_OPCODE_LOG:
290 break;
291 case TGSI_OPCODE_MUL: {
292 out = instr->mul(inputs[0], inputs[1]);
293 }
294 break;
295 case TGSI_OPCODE_ADD: {
296 out = instr->add(inputs[0], inputs[1]);
297 }
298 break;
299 case TGSI_OPCODE_DP3: {
300 out = instr->dp3(inputs[0], inputs[1]);
301 }
302 break;
303 case TGSI_OPCODE_DP4: {
304 out = instr->dp4(inputs[0], inputs[1]);
305 }
306 break;
307 case TGSI_OPCODE_DST: {
308 out = instr->dst(inputs[0], inputs[1]);
309 }
310 break;
311 case TGSI_OPCODE_MIN: {
312 out = instr->min(inputs[0], inputs[1]);
313 }
314 break;
315 case TGSI_OPCODE_MAX: {
316 out = instr->max(inputs[0], inputs[1]);
317 }
318 break;
319 case TGSI_OPCODE_SLT: {
320 out = instr->slt(inputs[0], inputs[1]);
321 }
322 break;
323 case TGSI_OPCODE_SGE: {
324 out = instr->sge(inputs[0], inputs[1]);
325 }
326 break;
327 case TGSI_OPCODE_MAD: {
328 out = instr->madd(inputs[0], inputs[1], inputs[2]);
329 }
330 break;
331 case TGSI_OPCODE_SUB: {
332 out = instr->sub(inputs[0], inputs[1]);
333 }
334 break;
335 case TGSI_OPCODE_LERP: {
336 out = instr->lerp(inputs[0], inputs[1], inputs[2]);
337 }
338 break;
339 case TGSI_OPCODE_CND:
340 break;
341 case TGSI_OPCODE_CND0:
342 break;
343 case TGSI_OPCODE_DOT2ADD:
344 break;
345 case TGSI_OPCODE_INDEX:
346 break;
347 case TGSI_OPCODE_NEGATE:
348 break;
349 case TGSI_OPCODE_FRAC: {
350 out = instr->frc(inputs[0]);
351 }
352 break;
353 case TGSI_OPCODE_CLAMP:
354 break;
355 case TGSI_OPCODE_FLOOR: {
356 out = instr->floor(inputs[0]);
357 }
358 break;
359 case TGSI_OPCODE_ROUND:
360 break;
361 case TGSI_OPCODE_EXPBASE2: {
362 out = instr->ex2(inputs[0]);
363 }
364 break;
365 case TGSI_OPCODE_LOGBASE2: {
366 out = instr->lg2(inputs[0]);
367 }
368 break;
369 case TGSI_OPCODE_POWER: {
370 out = instr->pow(inputs[0], inputs[1]);
371 }
372 break;
373 case TGSI_OPCODE_CROSSPRODUCT: {
374 out = instr->cross(inputs[0], inputs[1]);
375 }
376 break;
377 case TGSI_OPCODE_MULTIPLYMATRIX:
378 break;
379 case TGSI_OPCODE_ABS: {
380 out = instr->abs(inputs[0]);
381 }
382 break;
383 case TGSI_OPCODE_RCC:
384 break;
385 case TGSI_OPCODE_DPH: {
386 out = instr->dph(inputs[0], inputs[1]);
387 }
388 break;
389 case TGSI_OPCODE_COS: {
390 out = instr->cos(inputs[0]);
391 }
392 break;
393 case TGSI_OPCODE_DDX:
394 break;
395 case TGSI_OPCODE_DDY:
396 break;
397 case TGSI_OPCODE_KILP: {
398 out = instr->kilp(inputs[0]);
399 storage->setKilElement(out);
400 return;
401 }
402 break;
403 case TGSI_OPCODE_PK2H:
404 break;
405 case TGSI_OPCODE_PK2US:
406 break;
407 case TGSI_OPCODE_PK4B:
408 break;
409 case TGSI_OPCODE_PK4UB:
410 break;
411 case TGSI_OPCODE_RFL:
412 break;
413 case TGSI_OPCODE_SEQ:
414 break;
415 case TGSI_OPCODE_SFL:
416 break;
417 case TGSI_OPCODE_SGT: {
418 out = instr->sgt(inputs[0], inputs[1]);
419 }
420 break;
421 case TGSI_OPCODE_SIN: {
422 out = instr->sin(inputs[0]);
423 }
424 break;
425 case TGSI_OPCODE_SLE:
426 break;
427 case TGSI_OPCODE_SNE:
428 break;
429 case TGSI_OPCODE_STR:
430 break;
431 case TGSI_OPCODE_TEX:
432 break;
433 case TGSI_OPCODE_TXD:
434 break;
435 case TGSI_OPCODE_UP2H:
436 break;
437 case TGSI_OPCODE_UP2US:
438 break;
439 case TGSI_OPCODE_UP4B:
440 break;
441 case TGSI_OPCODE_UP4UB:
442 break;
443 case TGSI_OPCODE_X2D:
444 break;
445 case TGSI_OPCODE_ARA:
446 break;
447 case TGSI_OPCODE_ARR:
448 break;
449 case TGSI_OPCODE_BRA:
450 break;
451 case TGSI_OPCODE_CAL: {
452 instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr());
453 return;
454 }
455 break;
456 case TGSI_OPCODE_RET: {
457 instr->end();
458 return;
459 }
460 break;
461 case TGSI_OPCODE_SSG:
462 break;
463 case TGSI_OPCODE_CMP: {
464 out = instr->cmp(inputs[0], inputs[1], inputs[2]);
465 }
466 break;
467 case TGSI_OPCODE_SCS: {
468 out = instr->scs(inputs[0]);
469 }
470 break;
471 case TGSI_OPCODE_TXB:
472 break;
473 case TGSI_OPCODE_NRM:
474 break;
475 case TGSI_OPCODE_DIV:
476 break;
477 case TGSI_OPCODE_DP2:
478 break;
479 case TGSI_OPCODE_TXL:
480 break;
481 case TGSI_OPCODE_BRK: {
482 instr->brk();
483 return;
484 }
485 break;
486 case TGSI_OPCODE_IF: {
487 instr->ifop(inputs[0]);
488 storage->setCurrentBlock(instr->currentBlock());
489 return; //just update the state
490 }
491 break;
492 case TGSI_OPCODE_LOOP:
493 break;
494 case TGSI_OPCODE_REP:
495 break;
496 case TGSI_OPCODE_ELSE: {
497 instr->elseop();
498 storage->setCurrentBlock(instr->currentBlock());
499 return; //only state update
500 }
501 break;
502 case TGSI_OPCODE_ENDIF: {
503 instr->endif();
504 storage->setCurrentBlock(instr->currentBlock());
505 return; //just update the state
506 }
507 break;
508 case TGSI_OPCODE_ENDLOOP:
509 break;
510 case TGSI_OPCODE_ENDREP:
511 break;
512 case TGSI_OPCODE_PUSHA:
513 break;
514 case TGSI_OPCODE_POPA:
515 break;
516 case TGSI_OPCODE_CEIL:
517 break;
518 case TGSI_OPCODE_I2F:
519 break;
520 case TGSI_OPCODE_NOT:
521 break;
522 case TGSI_OPCODE_TRUNC: {
523 out = instr->trunc(inputs[0]);
524 }
525 break;
526 case TGSI_OPCODE_SHL:
527 break;
528 case TGSI_OPCODE_SHR:
529 break;
530 case TGSI_OPCODE_AND:
531 break;
532 case TGSI_OPCODE_OR:
533 break;
534 case TGSI_OPCODE_MOD:
535 break;
536 case TGSI_OPCODE_XOR:
537 break;
538 case TGSI_OPCODE_SAD:
539 break;
540 case TGSI_OPCODE_TXF:
541 break;
542 case TGSI_OPCODE_TXQ:
543 break;
544 case TGSI_OPCODE_CONT:
545 break;
546 case TGSI_OPCODE_EMIT:
547 break;
548 case TGSI_OPCODE_ENDPRIM:
549 break;
550 case TGSI_OPCODE_BGNLOOP2: {
551 instr->beginLoop();
552 storage->setCurrentBlock(instr->currentBlock());
553 return;
554 }
555 break;
556 case TGSI_OPCODE_BGNSUB: {
557 instr->bgnSub(instno);
558 storage->setCurrentBlock(instr->currentBlock());
559 storage->pushTemps();
560 return;
561 }
562 break;
563 case TGSI_OPCODE_ENDLOOP2: {
564 instr->endLoop();
565 storage->setCurrentBlock(instr->currentBlock());
566 return;
567 }
568 break;
569 case TGSI_OPCODE_ENDSUB: {
570 instr->endSub();
571 storage->setCurrentBlock(instr->currentBlock());
572 storage->popArguments();
573 storage->popTemps();
574 return;
575 }
576 break;
577 case TGSI_OPCODE_NOISE1:
578 break;
579 case TGSI_OPCODE_NOISE2:
580 break;
581 case TGSI_OPCODE_NOISE3:
582 break;
583 case TGSI_OPCODE_NOISE4:
584 break;
585 case TGSI_OPCODE_NOP:
586 break;
587 case TGSI_OPCODE_TEXBEM:
588 break;
589 case TGSI_OPCODE_TEXBEML:
590 break;
591 case TGSI_OPCODE_TEXREG2AR:
592 break;
593 case TGSI_OPCODE_TEXM3X2PAD:
594 break;
595 case TGSI_OPCODE_TEXM3X2TEX:
596 break;
597 case TGSI_OPCODE_TEXM3X3PAD:
598 break;
599 case TGSI_OPCODE_TEXM3X3TEX:
600 break;
601 case TGSI_OPCODE_TEXM3X3SPEC:
602 break;
603 case TGSI_OPCODE_TEXM3X3VSPEC:
604 break;
605 case TGSI_OPCODE_TEXREG2GB:
606 break;
607 case TGSI_OPCODE_TEXREG2RGB:
608 break;
609 case TGSI_OPCODE_TEXDP3TEX:
610 break;
611 case TGSI_OPCODE_TEXDP3:
612 break;
613 case TGSI_OPCODE_TEXM3X3:
614 break;
615 case TGSI_OPCODE_TEXM3X2DEPTH:
616 break;
617 case TGSI_OPCODE_TEXDEPTH:
618 break;
619 case TGSI_OPCODE_BEM:
620 break;
621 case TGSI_OPCODE_M4X3:
622 break;
623 case TGSI_OPCODE_M3X4:
624 break;
625 case TGSI_OPCODE_M3X3:
626 break;
627 case TGSI_OPCODE_M3X2:
628 break;
629 case TGSI_OPCODE_NRM4:
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 break;
639 case TGSI_OPCODE_END:
640 instr->end();
641 return;
642 break;
643 default:
644 fprintf(stderr, "ERROR: Unknown opcode %d\n",
645 inst->Instruction.Opcode);
646 assert(0);
647 break;
648 }
649
650 if (!out) {
651 fprintf(stderr, "ERROR: unsupported opcode %d\n",
652 inst->Instruction.Opcode);
653 assert(!"Unsupported opcode");
654 }
655
656 /* # not sure if we need this */
657 switch( inst->Instruction.Saturate ) {
658 case TGSI_SAT_NONE:
659 break;
660 case TGSI_SAT_ZERO_ONE:
661 /*TXT( "_SAT" );*/
662 break;
663 case TGSI_SAT_MINUS_PLUS_ONE:
664 /*TXT( "_SAT[-1,1]" );*/
665 break;
666 default:
667 assert( 0 );
668 }
669
670 /* store results */
671 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
672 struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
673
674 if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
675 storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
676 } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) {
677 storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
678 } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) {
679 storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
680 } else {
681 fprintf(stderr, "ERROR: unsupported LLVM destination!");
682 assert(!"wrong destination");
683 }
684 }
685 }
686
687
688 static void
689 translate_instructionir(llvm::Module *module,
690 StorageSoa *storage,
691 InstructionsSoa *instr,
692 struct tgsi_full_instruction *inst,
693 struct tgsi_full_instruction *fi,
694 unsigned instno)
695 {
696 std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs);
697
698 for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
699 struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
700 std::vector<llvm::Value*> val;
701 llvm::Value *indIdx = 0;
702 int swizzle = swizzleInt(src);
703
704 if (src->SrcRegister.Indirect) {
705 indIdx = storage->addrElement(src->SrcRegisterInd.Index);
706 indIdx = storage->extractIndex(indIdx);
707 }
708 if (src->SrcRegister.File == TGSI_FILE_CONSTANT) {
709 val = storage->constElement(src->SrcRegister.Index, swizzle, indIdx);
710 } else if (src->SrcRegister.File == TGSI_FILE_INPUT) {
711 val = storage->inputElement(src->SrcRegister.Index, swizzle, indIdx);
712 } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
713 val = storage->tempElement(src->SrcRegister.Index, swizzle);
714 } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) {
715 val = storage->outputElement(src->SrcRegister.Index, swizzle, indIdx);
716 } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
717 val = storage->immediateElement(src->SrcRegister.Index, swizzle);
718 } else {
719 fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
720 return;
721 }
722
723 inputs[i] = val;
724 }
725
726 std::vector<llvm::Value*> out(4);
727 switch (inst->Instruction.Opcode) {
728 case TGSI_OPCODE_ARL: {
729 }
730 break;
731 case TGSI_OPCODE_MOV: {
732 out = inputs[0];
733 }
734 break;
735 case TGSI_OPCODE_LIT: {
736 }
737 break;
738 case TGSI_OPCODE_RCP: {
739 }
740 break;
741 case TGSI_OPCODE_RSQ: {
742 }
743 break;
744 case TGSI_OPCODE_EXP:
745 break;
746 case TGSI_OPCODE_LOG:
747 break;
748 case TGSI_OPCODE_MUL: {
749 out = instr->mul(inputs[0], inputs[1]);
750 }
751 break;
752 case TGSI_OPCODE_ADD: {
753 out = instr->add(inputs[0], inputs[1]);
754 }
755 break;
756 case TGSI_OPCODE_DP3: {
757 }
758 break;
759 case TGSI_OPCODE_DP4: {
760 }
761 break;
762 case TGSI_OPCODE_DST: {
763 }
764 break;
765 case TGSI_OPCODE_MIN: {
766 }
767 break;
768 case TGSI_OPCODE_MAX: {
769 }
770 break;
771 case TGSI_OPCODE_SLT: {
772 }
773 break;
774 case TGSI_OPCODE_SGE: {
775 }
776 break;
777 case TGSI_OPCODE_MAD: {
778 }
779 break;
780 case TGSI_OPCODE_SUB: {
781 }
782 break;
783 case TGSI_OPCODE_LERP: {
784 }
785 break;
786 case TGSI_OPCODE_CND:
787 break;
788 case TGSI_OPCODE_CND0:
789 break;
790 case TGSI_OPCODE_DOT2ADD:
791 break;
792 case TGSI_OPCODE_INDEX:
793 break;
794 case TGSI_OPCODE_NEGATE:
795 break;
796 case TGSI_OPCODE_FRAC: {
797 }
798 break;
799 case TGSI_OPCODE_CLAMP:
800 break;
801 case TGSI_OPCODE_FLOOR: {
802 }
803 break;
804 case TGSI_OPCODE_ROUND:
805 break;
806 case TGSI_OPCODE_EXPBASE2: {
807 }
808 break;
809 case TGSI_OPCODE_LOGBASE2: {
810 }
811 break;
812 case TGSI_OPCODE_POWER: {
813 }
814 break;
815 case TGSI_OPCODE_CROSSPRODUCT: {
816 }
817 break;
818 case TGSI_OPCODE_MULTIPLYMATRIX:
819 break;
820 case TGSI_OPCODE_ABS: {
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 }
837 break;
838 case TGSI_OPCODE_PK2H:
839 break;
840 case TGSI_OPCODE_PK2US:
841 break;
842 case TGSI_OPCODE_PK4B:
843 break;
844 case TGSI_OPCODE_PK4UB:
845 break;
846 case TGSI_OPCODE_RFL:
847 break;
848 case TGSI_OPCODE_SEQ:
849 break;
850 case TGSI_OPCODE_SFL:
851 break;
852 case TGSI_OPCODE_SGT: {
853 }
854 break;
855 case TGSI_OPCODE_SIN: {
856 }
857 break;
858 case TGSI_OPCODE_SLE:
859 break;
860 case TGSI_OPCODE_SNE:
861 break;
862 case TGSI_OPCODE_STR:
863 break;
864 case TGSI_OPCODE_TEX:
865 break;
866 case TGSI_OPCODE_TXD:
867 break;
868 case TGSI_OPCODE_UP2H:
869 break;
870 case TGSI_OPCODE_UP2US:
871 break;
872 case TGSI_OPCODE_UP4B:
873 break;
874 case TGSI_OPCODE_UP4UB:
875 break;
876 case TGSI_OPCODE_X2D:
877 break;
878 case TGSI_OPCODE_ARA:
879 break;
880 case TGSI_OPCODE_ARR:
881 break;
882 case TGSI_OPCODE_BRA:
883 break;
884 case TGSI_OPCODE_CAL: {
885 }
886 break;
887 case TGSI_OPCODE_RET: {
888 }
889 break;
890 case TGSI_OPCODE_SSG:
891 break;
892 case TGSI_OPCODE_CMP: {
893 }
894 break;
895 case TGSI_OPCODE_SCS: {
896 }
897 break;
898 case TGSI_OPCODE_TXB:
899 break;
900 case TGSI_OPCODE_NRM:
901 break;
902 case TGSI_OPCODE_DIV:
903 break;
904 case TGSI_OPCODE_DP2:
905 break;
906 case TGSI_OPCODE_TXL:
907 break;
908 case TGSI_OPCODE_BRK: {
909 }
910 break;
911 case TGSI_OPCODE_IF: {
912 }
913 break;
914 case TGSI_OPCODE_LOOP:
915 break;
916 case TGSI_OPCODE_REP:
917 break;
918 case TGSI_OPCODE_ELSE: {
919 }
920 break;
921 case TGSI_OPCODE_ENDIF: {
922 }
923 break;
924 case TGSI_OPCODE_ENDLOOP:
925 break;
926 case TGSI_OPCODE_ENDREP:
927 break;
928 case TGSI_OPCODE_PUSHA:
929 break;
930 case TGSI_OPCODE_POPA:
931 break;
932 case TGSI_OPCODE_CEIL:
933 break;
934 case TGSI_OPCODE_I2F:
935 break;
936 case TGSI_OPCODE_NOT:
937 break;
938 case TGSI_OPCODE_TRUNC: {
939 }
940 break;
941 case TGSI_OPCODE_SHL:
942 break;
943 case TGSI_OPCODE_SHR:
944 break;
945 case TGSI_OPCODE_AND:
946 break;
947 case TGSI_OPCODE_OR:
948 break;
949 case TGSI_OPCODE_MOD:
950 break;
951 case TGSI_OPCODE_XOR:
952 break;
953 case TGSI_OPCODE_SAD:
954 break;
955 case TGSI_OPCODE_TXF:
956 break;
957 case TGSI_OPCODE_TXQ:
958 break;
959 case TGSI_OPCODE_CONT:
960 break;
961 case TGSI_OPCODE_EMIT:
962 break;
963 case TGSI_OPCODE_ENDPRIM:
964 break;
965 case TGSI_OPCODE_BGNLOOP2: {
966 }
967 break;
968 case TGSI_OPCODE_BGNSUB: {
969 }
970 break;
971 case TGSI_OPCODE_ENDLOOP2: {
972 }
973 break;
974 case TGSI_OPCODE_ENDSUB: {
975 }
976 break;
977 case TGSI_OPCODE_NOISE1:
978 break;
979 case TGSI_OPCODE_NOISE2:
980 break;
981 case TGSI_OPCODE_NOISE3:
982 break;
983 case TGSI_OPCODE_NOISE4:
984 break;
985 case TGSI_OPCODE_NOP:
986 break;
987 case TGSI_OPCODE_TEXBEM:
988 break;
989 case TGSI_OPCODE_TEXBEML:
990 break;
991 case TGSI_OPCODE_TEXREG2AR:
992 break;
993 case TGSI_OPCODE_TEXM3X2PAD:
994 break;
995 case TGSI_OPCODE_TEXM3X2TEX:
996 break;
997 case TGSI_OPCODE_TEXM3X3PAD:
998 break;
999 case TGSI_OPCODE_TEXM3X3TEX:
1000 break;
1001 case TGSI_OPCODE_TEXM3X3SPEC:
1002 break;
1003 case TGSI_OPCODE_TEXM3X3VSPEC:
1004 break;
1005 case TGSI_OPCODE_TEXREG2GB:
1006 break;
1007 case TGSI_OPCODE_TEXREG2RGB:
1008 break;
1009 case TGSI_OPCODE_TEXDP3TEX:
1010 break;
1011 case TGSI_OPCODE_TEXDP3:
1012 break;
1013 case TGSI_OPCODE_TEXM3X3:
1014 break;
1015 case TGSI_OPCODE_TEXM3X2DEPTH:
1016 break;
1017 case TGSI_OPCODE_TEXDEPTH:
1018 break;
1019 case TGSI_OPCODE_BEM:
1020 break;
1021 case TGSI_OPCODE_M4X3:
1022 break;
1023 case TGSI_OPCODE_M3X4:
1024 break;
1025 case TGSI_OPCODE_M3X3:
1026 break;
1027 case TGSI_OPCODE_M3X2:
1028 break;
1029 case TGSI_OPCODE_NRM4:
1030 break;
1031 case TGSI_OPCODE_CALLNZ:
1032 break;
1033 case TGSI_OPCODE_IFC:
1034 break;
1035 case TGSI_OPCODE_BREAKC:
1036 break;
1037 case TGSI_OPCODE_KIL:
1038 break;
1039 case TGSI_OPCODE_END:
1040 instr->end();
1041 return;
1042 break;
1043 default:
1044 fprintf(stderr, "ERROR: Unknown opcode %d\n",
1045 inst->Instruction.Opcode);
1046 assert(0);
1047 break;
1048 }
1049
1050 if (!out[0]) {
1051 fprintf(stderr, "ERROR: unsupported opcode %d\n",
1052 inst->Instruction.Opcode);
1053 assert(!"Unsupported opcode");
1054 }
1055
1056 /* store results */
1057 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
1058 struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
1059
1060 if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
1061 storage->storeOutput(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
1062 } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) {
1063 storage->storeTemp(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
1064 } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) {
1065 storage->storeAddress(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
1066 } else {
1067 fprintf(stderr, "ERROR: unsupported LLVM destination!");
1068 assert(!"wrong destination");
1069 }
1070 }
1071 }
1072
1073 llvm::Module *
1074 tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens)
1075 {
1076 llvm::Module *mod = new Module("shader");
1077 struct tgsi_parse_context parse;
1078 struct tgsi_full_instruction fi;
1079 struct tgsi_full_declaration fd;
1080 unsigned instno = 0;
1081 Function* shader = mod->getFunction("execute_shader");
1082 std::ostringstream stream;
1083 if (ir->type == GALLIVM_VS) {
1084 stream << "vs_shader";
1085 } else {
1086 stream << "fs_shader";
1087 }
1088 stream << ir->id;
1089 std::string func_name = stream.str();
1090 shader->setName(func_name.c_str());
1091
1092 Function::arg_iterator args = shader->arg_begin();
1093 Value *ptr_INPUT = args++;
1094 ptr_INPUT->setName("input");
1095
1096 BasicBlock *label_entry = new BasicBlock("entry", shader, 0);
1097
1098 tgsi_parse_init(&parse, tokens);
1099
1100 fi = tgsi_default_full_instruction();
1101 fd = tgsi_default_full_declaration();
1102 Storage storage(label_entry, ptr_INPUT);
1103 Instructions instr(mod, shader, label_entry, &storage);
1104 while(!tgsi_parse_end_of_tokens(&parse)) {
1105 tgsi_parse_token(&parse);
1106
1107 switch (parse.FullToken.Token.Type) {
1108 case TGSI_TOKEN_TYPE_DECLARATION:
1109 translate_declaration(ir, mod, &storage,
1110 &parse.FullToken.FullDeclaration,
1111 &fd);
1112 break;
1113
1114 case TGSI_TOKEN_TYPE_IMMEDIATE:
1115 translate_immediate(&storage,
1116 &parse.FullToken.FullImmediate);
1117 break;
1118
1119 case TGSI_TOKEN_TYPE_INSTRUCTION:
1120 translate_instruction(mod, &storage, &instr,
1121 &parse.FullToken.FullInstruction,
1122 &fi, instno);
1123 ++instno;
1124 break;
1125
1126 default:
1127 assert(0);
1128 }
1129 }
1130
1131 tgsi_parse_free(&parse);
1132
1133 ir->num_consts = storage.numConsts();
1134 return mod;
1135 }
1136
1137 llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir,
1138 const struct tgsi_token *tokens)
1139 {
1140 llvm::Module *mod = new Module("shader");
1141 struct tgsi_parse_context parse;
1142 struct tgsi_full_instruction fi;
1143 struct tgsi_full_declaration fd;
1144 unsigned instno = 0;
1145 std::ostringstream stream;
1146 if (ir->type == GALLIVM_VS) {
1147 stream << "vs_shader";
1148 } else {
1149 stream << "fs_shader";
1150 }
1151 //stream << ir->id;
1152 std::string func_name = stream.str();
1153 Function *shader = llvm::cast<Function>(mod->getOrInsertFunction(
1154 func_name.c_str(),
1155 vertexShaderFunctionType()));
1156
1157 Function::arg_iterator args = shader->arg_begin();
1158 Value *input = args++;
1159 input->setName("inputs");
1160 Value *output = args++;
1161 output->setName("outputs");
1162 Value *consts = args++;
1163 consts->setName("consts");
1164 Value *temps = args++;
1165 temps->setName("temps");
1166
1167 BasicBlock *label_entry = new BasicBlock("entry", shader, 0);
1168
1169 tgsi_parse_init(&parse, tokens);
1170
1171 fi = tgsi_default_full_instruction();
1172 fd = tgsi_default_full_declaration();
1173
1174 StorageSoa storage(label_entry, input, output, consts, temps);
1175 InstructionsSoa instr(mod, shader, label_entry, &storage);
1176
1177 while(!tgsi_parse_end_of_tokens(&parse)) {
1178 tgsi_parse_token(&parse);
1179
1180 switch (parse.FullToken.Token.Type) {
1181 case TGSI_TOKEN_TYPE_DECLARATION:
1182 translate_declarationir(ir, mod, &storage,
1183 &parse.FullToken.FullDeclaration,
1184 &fd);
1185 break;
1186
1187 case TGSI_TOKEN_TYPE_IMMEDIATE:
1188 translate_immediateir(&storage,
1189 &parse.FullToken.FullImmediate);
1190 break;
1191
1192 case TGSI_TOKEN_TYPE_INSTRUCTION:
1193 translate_instructionir(mod, &storage, &instr,
1194 &parse.FullToken.FullInstruction,
1195 &fi, instno);
1196 ++instno;
1197 break;
1198
1199 default:
1200 assert(0);
1201 }
1202 }
1203
1204 tgsi_parse_free(&parse);
1205
1206 return mod;
1207 }