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