blob: 8f7d3b71004b1793f9d06d3fc07b3d43aab88844 [file] [log] [blame]
Zack Rusin7d690902008-02-04 10:07:02 -05001#include "tgsitollvm.h"
2
3#include "gallivm.h"
4#include "gallivm_p.h"
5
6#include "storage.h"
7#include "instructions.h"
Zack Rusine7611612008-02-11 09:43:59 -05008#include "storagesoa.h"
9#include "instructionssoa.h"
Zack Rusin7d690902008-02-04 10:07:02 -050010
11#include "pipe/p_shader_tokens.h"
12
José Fonsecac208a2c2008-07-28 12:42:13 +090013#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"
Zack Rusin7d690902008-02-04 10:07:02 -050018
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>
Michel Dänzerf586c312009-01-12 12:34:27 +010028#include <llvm/Attributes.h>
Zack Rusin7d690902008-02-04 10:07:02 -050029#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
46using namespace llvm;
Zack Rusin7d690902008-02-04 10:07:02 -050047
Zack Rusin9b6532f2008-02-13 00:21:24 -050048static 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,
Stephane Marchesin94ba48b2008-10-07 21:11:01 +020055 // [4 x [1 x float]] consts,
Zack Rusin4bb1a142008-02-13 04:38:10 -050056
Zack Rusin9b6532f2008-02-13 00:21:24 -050057 std::vector<const Type*> funcArgs;
Zack Rusin4bb1a142008-02-13 04:38:10 -050058 VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
59 ArrayType *vectorArray = ArrayType::get(vectorType, 4);
60 PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0);
Zack Rusin9b6532f2008-02-13 00:21:24 -050061
Zack Rusin4bb1a142008-02-13 04:38:10 -050062 ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4);
Stephane Marchesin94ba48b2008-10-07 21:11:01 +020063 ArrayType *constsArray = ArrayType::get(floatArray, 1);
Zack Rusin4bb1a142008-02-13 04:38:10 -050064 PointerType *constsArrayPtr = PointerType::get(constsArray, 0);
Zack Rusin9b6532f2008-02-13 00:21:24 -050065
Zack Rusin4bb1a142008-02-13 04:38:10 -050066 funcArgs.push_back(vectorArrayPtr);//inputs
67 funcArgs.push_back(vectorArrayPtr);//output
68 funcArgs.push_back(constsArrayPtr);//consts
Zack Rusin4bb1a142008-02-13 04:38:10 -050069
Zack Rusin9b6532f2008-02-13 00:21:24 -050070 FunctionType *functionType = FunctionType::get(
71 /*Result=*/Type::VoidTy,
72 /*Params=*/funcArgs,
73 /*isVarArg=*/false);
74
75 return functionType;
76}
77
Zack Rusin7d690902008-02-04 10:07:02 -050078static inline void
79add_interpolator(struct gallivm_ir *ir,
80 struct gallivm_interpolate *interp)
81{
82 ir->interpolators[ir->num_interp] = *interp;
83 ++ir->num_interp;
84}
85
86static void
87translate_declaration(struct gallivm_ir *prog,
88 llvm::Module *module,
89 Storage *storage,
90 struct tgsi_full_declaration *decl,
91 struct tgsi_full_declaration *fd)
92{
93 if (decl->Declaration.File == TGSI_FILE_INPUT) {
94 unsigned first, last, mask;
95 uint interp_method;
96
Keith Whitwellfe2b31e2009-11-24 15:04:18 +000097 first = decl->Range.First;
98 last = decl->Range.Last;
Zack Rusin7d690902008-02-04 10:07:02 -050099 mask = decl->Declaration.UsageMask;
100
101 /* Do not touch WPOS.xy */
102 if (first == 0) {
103 mask &= ~TGSI_WRITEMASK_XY;
104 if (mask == TGSI_WRITEMASK_NONE) {
105 first++;
106 if (first > last) {
107 return;
108 }
109 }
110 }
111
Michal Krol3de18c22008-05-31 19:41:29 +0200112 interp_method = decl->Declaration.Interpolate;
Zack Rusin7d690902008-02-04 10:07:02 -0500113
114 if (mask == TGSI_WRITEMASK_XYZW) {
115 unsigned i, j;
116
117 for (i = first; i <= last; i++) {
118 for (j = 0; j < NUM_CHANNELS; j++) {
119 //interp( mach, i, j );
120 struct gallivm_interpolate interp;
121 interp.type = interp_method;
122 interp.attrib = i;
123 interp.chan = j;
124 add_interpolator(prog, &interp);
125 }
126 }
127 } else {
128 unsigned i, j;
129 for( j = 0; j < NUM_CHANNELS; j++ ) {
130 if( mask & (1 << j) ) {
131 for( i = first; i <= last; i++ ) {
132 struct gallivm_interpolate interp;
133 interp.type = interp_method;
134 interp.attrib = i;
135 interp.chan = j;
136 add_interpolator(prog, &interp);
137 }
138 }
139 }
140 }
141 }
142}
143
Zack Rusine7611612008-02-11 09:43:59 -0500144static void
145translate_declarationir(struct gallivm_ir *,
146 llvm::Module *,
Zack Rusinf70cc892008-02-14 22:42:57 -0500147 StorageSoa *storage,
148 struct tgsi_full_declaration *decl,
Zack Rusine7611612008-02-11 09:43:59 -0500149 struct tgsi_full_declaration *)
150{
Zack Rusinf70cc892008-02-14 22:42:57 -0500151 if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
Keith Whitwellfe2b31e2009-11-24 15:04:18 +0000152 int idx = decl->Range.First;
Zack Rusinf70cc892008-02-14 22:42:57 -0500153 storage->addAddress(idx);
154 }
Zack Rusine7611612008-02-11 09:43:59 -0500155}
Zack Rusin7d690902008-02-04 10:07:02 -0500156
157static void
158translate_immediate(Storage *storage,
159 struct tgsi_full_immediate *imm)
160{
161 float vec[4];
162 int i;
Keith Whitwellfd31f922009-07-22 00:39:00 +0100163 assert( imm->Immediate.NrTokens <= 4 + 1 );
Michal Krola872b512009-02-10 15:16:35 +0100164 for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) {
Zack Rusine7611612008-02-11 09:43:59 -0500165 switch (imm->Immediate.DataType) {
Zack Rusin7d690902008-02-04 10:07:02 -0500166 case TGSI_IMM_FLOAT32:
Keith Whitwellfd31f922009-07-22 00:39:00 +0100167 vec[i] = imm->u[i].Float;
Zack Rusin7d690902008-02-04 10:07:02 -0500168 break;
169 default:
Zack Rusine7611612008-02-11 09:43:59 -0500170 assert(0);
Zack Rusin7d690902008-02-04 10:07:02 -0500171 }
172 }
173 storage->addImmediate(vec);
174}
175
Zack Rusine7611612008-02-11 09:43:59 -0500176
177static void
178translate_immediateir(StorageSoa *storage,
179 struct tgsi_full_immediate *imm)
180{
181 float vec[4];
182 int i;
Keith Whitwellfd31f922009-07-22 00:39:00 +0100183 assert( imm->Immediate.NrTokens <= 4 + 1 );
Michal Krola872b512009-02-10 15:16:35 +0100184 for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) {
Zack Rusine7611612008-02-11 09:43:59 -0500185 switch (imm->Immediate.DataType) {
186 case TGSI_IMM_FLOAT32:
Keith Whitwellfd31f922009-07-22 00:39:00 +0100187 vec[i] = imm->u[i].Float;
Zack Rusine7611612008-02-11 09:43:59 -0500188 break;
189 default:
190 assert(0);
191 }
192 }
193 storage->addImmediate(vec);
194}
195
196static inline int
197swizzleInt(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
Zack Rusin7d690902008-02-04 10:07:02 -0500209static inline llvm::Value *
210swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src,
211 Storage *storage)
212{
Zack Rusine7611612008-02-11 09:43:59 -0500213 int swizzle = swizzleInt(src);
Zack Rusin3c3c1ff2008-02-12 23:08:42 -0500214
215 if (gallivm_is_swizzle(swizzle)) {
Zack Rusin7d690902008-02-04 10:07:02 -0500216 /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/
217 val = storage->shuffleVector(val, swizzle);
218 }
219 return val;
220}
221
222static void
223translate_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) {
Keith Whitwell7d6c8f92009-11-24 15:02:23 +0000237 struct tgsi_full_src_register *src = &inst->Src[i];
Zack Rusin7d690902008-02-04 10:07:02 -0500238 llvm::Value *val = 0;
239 llvm::Value *indIdx = 0;
240
Keith Whitwell91a4e6d2009-11-24 15:13:17 +0000241 if (src->Register.Indirect) {
242 indIdx = storage->addrElement(src->Indirect.Index);
Zack Rusin7d690902008-02-04 10:07:02 -0500243 indIdx = storage->extractIndex(indIdx);
244 }
Keith Whitwell91a4e6d2009-11-24 15:13:17 +0000245 if (src->Register.File == TGSI_FILE_CONSTANT) {
246 val = storage->constElement(src->Register.Index, indIdx);
247 } else if (src->Register.File == TGSI_FILE_INPUT) {
248 val = storage->inputElement(src->Register.Index, indIdx);
249 } else if (src->Register.File == TGSI_FILE_TEMPORARY) {
250 val = storage->tempElement(src->Register.Index);
251 } else if (src->Register.File == TGSI_FILE_OUTPUT) {
252 val = storage->outputElement(src->Register.Index, indIdx);
253 } else if (src->Register.File == TGSI_FILE_IMMEDIATE) {
254 val = storage->immediateElement(src->Register.Index);
Zack Rusin7d690902008-02-04 10:07:02 -0500255 } else {
Keith Whitwell91a4e6d2009-11-24 15:13:17 +0000256 fprintf(stderr, "ERROR: not supported llvm source %d\n", src->Register.File);
Zack Rusin7d690902008-02-04 10:07:02 -0500257 return;
258 }
259
260 inputs[i] = swizzleVector(val, src, storage);
261 }
262
263 /*if (inputs[0])
264 instr->printVector(inputs[0]);
265 if (inputs[1])
266 instr->printVector(inputs[1]);*/
267 llvm::Value *out = 0;
268 switch (inst->Instruction.Opcode) {
269 case TGSI_OPCODE_ARL: {
270 out = instr->arl(inputs[0]);
271 }
272 break;
273 case TGSI_OPCODE_MOV: {
274 out = inputs[0];
275 }
276 break;
277 case TGSI_OPCODE_LIT: {
278 out = instr->lit(inputs[0]);
279 }
280 break;
281 case TGSI_OPCODE_RCP: {
282 out = instr->rcp(inputs[0]);
283 }
284 break;
285 case TGSI_OPCODE_RSQ: {
286 out = instr->rsq(inputs[0]);
287 }
288 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200289 case TGSI_OPCODE_EXP: {
290 out = instr->exp(inputs[0]);
291 }
Zack Rusin7d690902008-02-04 10:07:02 -0500292 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200293 case TGSI_OPCODE_LOG: {
294 out = instr->log(inputs[0]);
295 }
Zack Rusin7d690902008-02-04 10:07:02 -0500296 break;
297 case TGSI_OPCODE_MUL: {
298 out = instr->mul(inputs[0], inputs[1]);
299 }
300 break;
301 case TGSI_OPCODE_ADD: {
302 out = instr->add(inputs[0], inputs[1]);
303 }
304 break;
305 case TGSI_OPCODE_DP3: {
306 out = instr->dp3(inputs[0], inputs[1]);
307 }
308 break;
309 case TGSI_OPCODE_DP4: {
310 out = instr->dp4(inputs[0], inputs[1]);
311 }
312 break;
313 case TGSI_OPCODE_DST: {
314 out = instr->dst(inputs[0], inputs[1]);
315 }
316 break;
317 case TGSI_OPCODE_MIN: {
318 out = instr->min(inputs[0], inputs[1]);
319 }
320 break;
321 case TGSI_OPCODE_MAX: {
322 out = instr->max(inputs[0], inputs[1]);
323 }
324 break;
325 case TGSI_OPCODE_SLT: {
326 out = instr->slt(inputs[0], inputs[1]);
327 }
328 break;
329 case TGSI_OPCODE_SGE: {
330 out = instr->sge(inputs[0], inputs[1]);
331 }
332 break;
333 case TGSI_OPCODE_MAD: {
334 out = instr->madd(inputs[0], inputs[1], inputs[2]);
335 }
336 break;
337 case TGSI_OPCODE_SUB: {
338 out = instr->sub(inputs[0], inputs[1]);
339 }
340 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100341 case TGSI_OPCODE_LRP: {
Zack Rusin7d690902008-02-04 10:07:02 -0500342 out = instr->lerp(inputs[0], inputs[1], inputs[2]);
343 }
344 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200345 case TGSI_OPCODE_CND: {
346 out = instr->cnd(inputs[0], inputs[1], inputs[2]);
347 }
Zack Rusin7d690902008-02-04 10:07:02 -0500348 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200349 case TGSI_OPCODE_CND0: {
350 out = instr->cnd0(inputs[0], inputs[1], inputs[2]);
351 }
Zack Rusin7d690902008-02-04 10:07:02 -0500352 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100353 case TGSI_OPCODE_DP2A: {
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200354 out = instr->dot2add(inputs[0], inputs[1], inputs[2]);
355 }
Zack Rusin7d690902008-02-04 10:07:02 -0500356 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100357 case TGSI_OPCODE_FRC: {
Zack Rusin7d690902008-02-04 10:07:02 -0500358 out = instr->frc(inputs[0]);
359 }
360 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200361 case TGSI_OPCODE_CLAMP: {
362 out = instr->clamp(inputs[0]);
363 }
Zack Rusin7d690902008-02-04 10:07:02 -0500364 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100365 case TGSI_OPCODE_FLR: {
Zack Rusin7d690902008-02-04 10:07:02 -0500366 out = instr->floor(inputs[0]);
367 }
368 break;
369 case TGSI_OPCODE_ROUND:
370 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100371 case TGSI_OPCODE_EX2: {
Zack Rusin7d690902008-02-04 10:07:02 -0500372 out = instr->ex2(inputs[0]);
373 }
374 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100375 case TGSI_OPCODE_LG2: {
Zack Rusin7d690902008-02-04 10:07:02 -0500376 out = instr->lg2(inputs[0]);
377 }
378 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100379 case TGSI_OPCODE_POW: {
Zack Rusin7d690902008-02-04 10:07:02 -0500380 out = instr->pow(inputs[0], inputs[1]);
381 }
382 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100383 case TGSI_OPCODE_XPD: {
Zack Rusin7d690902008-02-04 10:07:02 -0500384 out = instr->cross(inputs[0], inputs[1]);
385 }
386 break;
Zack Rusin7d690902008-02-04 10:07:02 -0500387 case TGSI_OPCODE_ABS: {
388 out = instr->abs(inputs[0]);
389 }
390 break;
391 case TGSI_OPCODE_RCC:
392 break;
393 case TGSI_OPCODE_DPH: {
394 out = instr->dph(inputs[0], inputs[1]);
395 }
396 break;
397 case TGSI_OPCODE_COS: {
398 out = instr->cos(inputs[0]);
399 }
400 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200401 case TGSI_OPCODE_DDX: {
402 out = instr->ddx(inputs[0]);
403 }
Zack Rusin7d690902008-02-04 10:07:02 -0500404 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200405 case TGSI_OPCODE_DDY: {
406 out = instr->ddy(inputs[0]);
407 }
Zack Rusin7d690902008-02-04 10:07:02 -0500408 break;
Michal Krolf633b142008-08-13 10:58:54 +0200409 case TGSI_OPCODE_KILP:
Zack Rusin7d690902008-02-04 10:07:02 -0500410 break;
411 case TGSI_OPCODE_PK2H:
412 break;
413 case TGSI_OPCODE_PK2US:
414 break;
415 case TGSI_OPCODE_PK4B:
416 break;
417 case TGSI_OPCODE_PK4UB:
418 break;
419 case TGSI_OPCODE_RFL:
420 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200421 case TGSI_OPCODE_SEQ: {
422 out = instr->seq(inputs[0], inputs[1]);
423 }
Zack Rusin7d690902008-02-04 10:07:02 -0500424 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200425 case TGSI_OPCODE_SFL: {
426 out = instr->sfl(inputs[0], inputs[1]);
427 }
Zack Rusin7d690902008-02-04 10:07:02 -0500428 break;
429 case TGSI_OPCODE_SGT: {
430 out = instr->sgt(inputs[0], inputs[1]);
431 }
432 break;
433 case TGSI_OPCODE_SIN: {
434 out = instr->sin(inputs[0]);
435 }
436 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200437 case TGSI_OPCODE_SLE: {
438 out = instr->sle(inputs[0], inputs[1]);
439 }
Zack Rusin7d690902008-02-04 10:07:02 -0500440 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200441 case TGSI_OPCODE_SNE: {
442 out = instr->sne(inputs[0], inputs[1]);
443 }
Zack Rusin7d690902008-02-04 10:07:02 -0500444 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200445 case TGSI_OPCODE_STR: {
446 out = instr->str(inputs[0], inputs[1]);
447 }
Zack Rusin7d690902008-02-04 10:07:02 -0500448 break;
449 case TGSI_OPCODE_TEX:
450 break;
451 case TGSI_OPCODE_TXD:
452 break;
453 case TGSI_OPCODE_UP2H:
454 break;
455 case TGSI_OPCODE_UP2US:
456 break;
457 case TGSI_OPCODE_UP4B:
458 break;
459 case TGSI_OPCODE_UP4UB:
460 break;
Stephane Marchesin3f477e12008-09-28 18:33:23 +0200461 case TGSI_OPCODE_X2D: {
462 out = instr->x2d(inputs[0], inputs[1], inputs[2]);
463 }
Zack Rusin7d690902008-02-04 10:07:02 -0500464 break;
465 case TGSI_OPCODE_ARA:
466 break;
467 case TGSI_OPCODE_ARR:
468 break;
469 case TGSI_OPCODE_BRA:
470 break;
471 case TGSI_OPCODE_CAL: {
472 instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr());
473 return;
474 }
475 break;
476 case TGSI_OPCODE_RET: {
477 instr->end();
478 return;
479 }
480 break;
481 case TGSI_OPCODE_SSG:
482 break;
483 case TGSI_OPCODE_CMP: {
484 out = instr->cmp(inputs[0], inputs[1], inputs[2]);
485 }
486 break;
487 case TGSI_OPCODE_SCS: {
488 out = instr->scs(inputs[0]);
489 }
490 break;
491 case TGSI_OPCODE_TXB:
492 break;
Stephane Marchesin0116ea32008-09-28 19:48:26 +0200493 case TGSI_OPCODE_NRM4:
494 case TGSI_OPCODE_NRM: {
495 out = instr->nrm(inputs[0]);
496 }
Zack Rusin7d690902008-02-04 10:07:02 -0500497 break;
Stephane Marchesin0116ea32008-09-28 19:48:26 +0200498 case TGSI_OPCODE_DIV: {
499 out = instr->div(inputs[0], inputs[1]);
500 }
Zack Rusin7d690902008-02-04 10:07:02 -0500501 break;
Stephane Marchesin0116ea32008-09-28 19:48:26 +0200502 case TGSI_OPCODE_DP2: {
503 out = instr->dp2(inputs[0], inputs[1]);
504 }
Zack Rusin7d690902008-02-04 10:07:02 -0500505 break;
506 case TGSI_OPCODE_TXL:
507 break;
508 case TGSI_OPCODE_BRK: {
509 instr->brk();
510 return;
511 }
512 break;
513 case TGSI_OPCODE_IF: {
514 instr->ifop(inputs[0]);
515 storage->setCurrentBlock(instr->currentBlock());
516 return; //just update the state
517 }
518 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200519 case TGSI_OPCODE_BGNFOR:
Zack Rusin7d690902008-02-04 10:07:02 -0500520 break;
521 case TGSI_OPCODE_REP:
522 break;
523 case TGSI_OPCODE_ELSE: {
524 instr->elseop();
525 storage->setCurrentBlock(instr->currentBlock());
526 return; //only state update
527 }
528 break;
529 case TGSI_OPCODE_ENDIF: {
530 instr->endif();
531 storage->setCurrentBlock(instr->currentBlock());
532 return; //just update the state
533 }
534 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200535 case TGSI_OPCODE_ENDFOR:
Zack Rusin7d690902008-02-04 10:07:02 -0500536 break;
537 case TGSI_OPCODE_ENDREP:
538 break;
539 case TGSI_OPCODE_PUSHA:
540 break;
541 case TGSI_OPCODE_POPA:
542 break;
543 case TGSI_OPCODE_CEIL:
544 break;
545 case TGSI_OPCODE_I2F:
546 break;
547 case TGSI_OPCODE_NOT:
548 break;
549 case TGSI_OPCODE_TRUNC: {
550 out = instr->trunc(inputs[0]);
551 }
552 break;
553 case TGSI_OPCODE_SHL:
554 break;
Michal Krol2c046032009-12-23 17:02:03 +0100555 case TGSI_OPCODE_ISHR:
Zack Rusin7d690902008-02-04 10:07:02 -0500556 break;
557 case TGSI_OPCODE_AND:
558 break;
559 case TGSI_OPCODE_OR:
560 break;
561 case TGSI_OPCODE_MOD:
562 break;
563 case TGSI_OPCODE_XOR:
564 break;
565 case TGSI_OPCODE_SAD:
566 break;
567 case TGSI_OPCODE_TXF:
568 break;
569 case TGSI_OPCODE_TXQ:
570 break;
571 case TGSI_OPCODE_CONT:
572 break;
573 case TGSI_OPCODE_EMIT:
574 break;
575 case TGSI_OPCODE_ENDPRIM:
576 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200577 case TGSI_OPCODE_BGNLOOP: {
Zack Rusin7d690902008-02-04 10:07:02 -0500578 instr->beginLoop();
579 storage->setCurrentBlock(instr->currentBlock());
580 return;
581 }
582 break;
583 case TGSI_OPCODE_BGNSUB: {
584 instr->bgnSub(instno);
585 storage->setCurrentBlock(instr->currentBlock());
586 storage->pushTemps();
587 return;
588 }
589 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200590 case TGSI_OPCODE_ENDLOOP: {
Zack Rusin7d690902008-02-04 10:07:02 -0500591 instr->endLoop();
592 storage->setCurrentBlock(instr->currentBlock());
593 return;
594 }
595 break;
596 case TGSI_OPCODE_ENDSUB: {
597 instr->endSub();
598 storage->setCurrentBlock(instr->currentBlock());
599 storage->popArguments();
600 storage->popTemps();
601 return;
602 }
603 break;
604 case TGSI_OPCODE_NOISE1:
605 break;
606 case TGSI_OPCODE_NOISE2:
607 break;
608 case TGSI_OPCODE_NOISE3:
609 break;
610 case TGSI_OPCODE_NOISE4:
611 break;
612 case TGSI_OPCODE_NOP:
613 break;
Zack Rusin7d690902008-02-04 10:07:02 -0500614 case TGSI_OPCODE_CALLNZ:
615 break;
616 case TGSI_OPCODE_IFC:
617 break;
618 case TGSI_OPCODE_BREAKC:
619 break;
Michal Krolf633b142008-08-13 10:58:54 +0200620 case TGSI_OPCODE_KIL: {
621 out = instr->kil(inputs[0]);
622 storage->setKilElement(out);
623 return;
624 }
Zack Rusin7d690902008-02-04 10:07:02 -0500625 break;
626 case TGSI_OPCODE_END:
627 instr->end();
628 return;
629 break;
630 default:
631 fprintf(stderr, "ERROR: Unknown opcode %d\n",
632 inst->Instruction.Opcode);
633 assert(0);
634 break;
635 }
636
637 if (!out) {
638 fprintf(stderr, "ERROR: unsupported opcode %d\n",
639 inst->Instruction.Opcode);
640 assert(!"Unsupported opcode");
641 }
642
643 /* # not sure if we need this */
644 switch( inst->Instruction.Saturate ) {
645 case TGSI_SAT_NONE:
646 break;
647 case TGSI_SAT_ZERO_ONE:
648 /*TXT( "_SAT" );*/
649 break;
650 case TGSI_SAT_MINUS_PLUS_ONE:
651 /*TXT( "_SAT[-1,1]" );*/
652 break;
653 default:
654 assert( 0 );
655 }
656
657 /* store results */
658 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
Keith Whitwell7d6c8f92009-11-24 15:02:23 +0000659 struct tgsi_full_dst_register *dst = &inst->Dst[i];
Zack Rusin7d690902008-02-04 10:07:02 -0500660
Keith Whitwell5b0824d2009-11-24 15:08:55 +0000661 if (dst->Register.File == TGSI_FILE_OUTPUT) {
662 storage->setOutputElement(dst->Register.Index, out, dst->Register.WriteMask);
663 } else if (dst->Register.File == TGSI_FILE_TEMPORARY) {
664 storage->setTempElement(dst->Register.Index, out, dst->Register.WriteMask);
665 } else if (dst->Register.File == TGSI_FILE_ADDRESS) {
666 storage->setAddrElement(dst->Register.Index, out, dst->Register.WriteMask);
Zack Rusin7d690902008-02-04 10:07:02 -0500667 } else {
668 fprintf(stderr, "ERROR: unsupported LLVM destination!");
669 assert(!"wrong destination");
670 }
671 }
672}
673
Zack Rusine7611612008-02-11 09:43:59 -0500674
675static void
676translate_instructionir(llvm::Module *module,
677 StorageSoa *storage,
678 InstructionsSoa *instr,
679 struct tgsi_full_instruction *inst,
680 struct tgsi_full_instruction *fi,
681 unsigned instno)
682{
683 std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs);
684
685 for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
Keith Whitwell7d6c8f92009-11-24 15:02:23 +0000686 struct tgsi_full_src_register *src = &inst->Src[i];
Zack Rusine7611612008-02-11 09:43:59 -0500687 std::vector<llvm::Value*> val;
688 llvm::Value *indIdx = 0;
689 int swizzle = swizzleInt(src);
690
Keith Whitwell91a4e6d2009-11-24 15:13:17 +0000691 if (src->Register.Indirect) {
692 indIdx = storage->addrElement(src->Indirect.Index);
Zack Rusine7611612008-02-11 09:43:59 -0500693 }
Keith Whitwell91a4e6d2009-11-24 15:13:17 +0000694 val = storage->load((enum tgsi_file_type)src->Register.File,
695 src->Register.Index, swizzle, instr->getIRBuilder(), indIdx);
Zack Rusine7611612008-02-11 09:43:59 -0500696
697 inputs[i] = val;
698 }
699
700 std::vector<llvm::Value*> out(4);
701 switch (inst->Instruction.Opcode) {
702 case TGSI_OPCODE_ARL: {
Zack Rusinf70cc892008-02-14 22:42:57 -0500703 out = instr->arl(inputs[0]);
Zack Rusine7611612008-02-11 09:43:59 -0500704 }
705 break;
706 case TGSI_OPCODE_MOV: {
707 out = inputs[0];
708 }
709 break;
710 case TGSI_OPCODE_LIT: {
Zack Rusin1d1cf8e2008-05-16 16:06:59 -0400711 out = instr->lit(inputs[0]);
Zack Rusine7611612008-02-11 09:43:59 -0500712 }
713 break;
714 case TGSI_OPCODE_RCP: {
715 }
716 break;
717 case TGSI_OPCODE_RSQ: {
Zack Rusin02e45b22008-05-16 17:10:52 -0400718 out = instr->rsq(inputs[0]);
Zack Rusine7611612008-02-11 09:43:59 -0500719 }
720 break;
721 case TGSI_OPCODE_EXP:
722 break;
723 case TGSI_OPCODE_LOG:
724 break;
725 case TGSI_OPCODE_MUL: {
726 out = instr->mul(inputs[0], inputs[1]);
727 }
728 break;
729 case TGSI_OPCODE_ADD: {
730 out = instr->add(inputs[0], inputs[1]);
731 }
732 break;
733 case TGSI_OPCODE_DP3: {
Zack Rusine884c7e2008-03-01 08:04:21 -0500734 out = instr->dp3(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500735 }
736 break;
737 case TGSI_OPCODE_DP4: {
Zack Rusina9c40f82008-03-01 09:50:41 -0500738 out = instr->dp4(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500739 }
740 break;
741 case TGSI_OPCODE_DST: {
742 }
743 break;
744 case TGSI_OPCODE_MIN: {
Zack Rusinea1a6072008-05-16 14:54:40 -0400745 out = instr->min(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500746 }
747 break;
748 case TGSI_OPCODE_MAX: {
Zack Rusinea1a6072008-05-16 14:54:40 -0400749 out = instr->max(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500750 }
751 break;
752 case TGSI_OPCODE_SLT: {
Stephane Marchesin8bdb4d22008-10-01 00:00:58 +0200753 out = instr->slt(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500754 }
755 break;
756 case TGSI_OPCODE_SGE: {
757 }
758 break;
759 case TGSI_OPCODE_MAD: {
Zack Rusinf70cc892008-02-14 22:42:57 -0500760 out = instr->madd(inputs[0], inputs[1], inputs[2]);
Zack Rusine7611612008-02-11 09:43:59 -0500761 }
762 break;
763 case TGSI_OPCODE_SUB: {
Zack Rusin59766ac2008-05-15 17:46:20 -0400764 out = instr->sub(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500765 }
766 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100767 case TGSI_OPCODE_LRP: {
Zack Rusine7611612008-02-11 09:43:59 -0500768 }
769 break;
770 case TGSI_OPCODE_CND:
771 break;
772 case TGSI_OPCODE_CND0:
773 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100774 case TGSI_OPCODE_DP2A:
Zack Rusine7611612008-02-11 09:43:59 -0500775 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100776 case TGSI_OPCODE_FRC: {
Zack Rusine7611612008-02-11 09:43:59 -0500777 }
778 break;
779 case TGSI_OPCODE_CLAMP:
780 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100781 case TGSI_OPCODE_FLR: {
Zack Rusine7611612008-02-11 09:43:59 -0500782 }
783 break;
784 case TGSI_OPCODE_ROUND:
785 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100786 case TGSI_OPCODE_EX2: {
Zack Rusine7611612008-02-11 09:43:59 -0500787 }
788 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100789 case TGSI_OPCODE_LG2: {
Zack Rusine7611612008-02-11 09:43:59 -0500790 }
791 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100792 case TGSI_OPCODE_POW: {
Zack Rusincac037d2008-03-12 22:51:57 -0400793 out = instr->pow(inputs[0], inputs[1]);
Zack Rusine7611612008-02-11 09:43:59 -0500794 }
795 break;
Keith Whitwelladc6f8c2009-07-23 17:56:41 +0100796 case TGSI_OPCODE_XPD: {
Zack Rusine7611612008-02-11 09:43:59 -0500797 }
798 break;
Zack Rusine7611612008-02-11 09:43:59 -0500799 case TGSI_OPCODE_ABS: {
Zack Rusin59766ac2008-05-15 17:46:20 -0400800 out = instr->abs(inputs[0]);
Zack Rusine7611612008-02-11 09:43:59 -0500801 }
802 break;
803 case TGSI_OPCODE_RCC:
804 break;
805 case TGSI_OPCODE_DPH: {
806 }
807 break;
808 case TGSI_OPCODE_COS: {
809 }
810 break;
811 case TGSI_OPCODE_DDX:
812 break;
813 case TGSI_OPCODE_DDY:
814 break;
Michal Krolf633b142008-08-13 10:58:54 +0200815 case TGSI_OPCODE_KILP:
Zack Rusine7611612008-02-11 09:43:59 -0500816 break;
817 case TGSI_OPCODE_PK2H:
818 break;
819 case TGSI_OPCODE_PK2US:
820 break;
821 case TGSI_OPCODE_PK4B:
822 break;
823 case TGSI_OPCODE_PK4UB:
824 break;
825 case TGSI_OPCODE_RFL:
826 break;
827 case TGSI_OPCODE_SEQ:
828 break;
829 case TGSI_OPCODE_SFL:
830 break;
831 case TGSI_OPCODE_SGT: {
832 }
833 break;
834 case TGSI_OPCODE_SIN: {
835 }
836 break;
837 case TGSI_OPCODE_SLE:
838 break;
839 case TGSI_OPCODE_SNE:
840 break;
841 case TGSI_OPCODE_STR:
842 break;
843 case TGSI_OPCODE_TEX:
844 break;
845 case TGSI_OPCODE_TXD:
846 break;
847 case TGSI_OPCODE_UP2H:
848 break;
849 case TGSI_OPCODE_UP2US:
850 break;
851 case TGSI_OPCODE_UP4B:
852 break;
853 case TGSI_OPCODE_UP4UB:
854 break;
855 case TGSI_OPCODE_X2D:
856 break;
857 case TGSI_OPCODE_ARA:
858 break;
859 case TGSI_OPCODE_ARR:
860 break;
861 case TGSI_OPCODE_BRA:
862 break;
863 case TGSI_OPCODE_CAL: {
864 }
865 break;
866 case TGSI_OPCODE_RET: {
867 }
868 break;
869 case TGSI_OPCODE_SSG:
870 break;
871 case TGSI_OPCODE_CMP: {
872 }
873 break;
874 case TGSI_OPCODE_SCS: {
875 }
876 break;
877 case TGSI_OPCODE_TXB:
878 break;
879 case TGSI_OPCODE_NRM:
880 break;
881 case TGSI_OPCODE_DIV:
882 break;
883 case TGSI_OPCODE_DP2:
884 break;
885 case TGSI_OPCODE_TXL:
886 break;
887 case TGSI_OPCODE_BRK: {
888 }
889 break;
890 case TGSI_OPCODE_IF: {
891 }
892 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200893 case TGSI_OPCODE_BGNFOR:
Zack Rusine7611612008-02-11 09:43:59 -0500894 break;
895 case TGSI_OPCODE_REP:
896 break;
897 case TGSI_OPCODE_ELSE: {
898 }
899 break;
900 case TGSI_OPCODE_ENDIF: {
901 }
902 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200903 case TGSI_OPCODE_ENDFOR:
Zack Rusine7611612008-02-11 09:43:59 -0500904 break;
905 case TGSI_OPCODE_ENDREP:
906 break;
907 case TGSI_OPCODE_PUSHA:
908 break;
909 case TGSI_OPCODE_POPA:
910 break;
911 case TGSI_OPCODE_CEIL:
912 break;
913 case TGSI_OPCODE_I2F:
914 break;
915 case TGSI_OPCODE_NOT:
916 break;
917 case TGSI_OPCODE_TRUNC: {
918 }
919 break;
920 case TGSI_OPCODE_SHL:
921 break;
Michal Krol2c046032009-12-23 17:02:03 +0100922 case TGSI_OPCODE_ISHR:
Zack Rusine7611612008-02-11 09:43:59 -0500923 break;
924 case TGSI_OPCODE_AND:
925 break;
926 case TGSI_OPCODE_OR:
927 break;
928 case TGSI_OPCODE_MOD:
929 break;
930 case TGSI_OPCODE_XOR:
931 break;
932 case TGSI_OPCODE_SAD:
933 break;
934 case TGSI_OPCODE_TXF:
935 break;
936 case TGSI_OPCODE_TXQ:
937 break;
938 case TGSI_OPCODE_CONT:
939 break;
940 case TGSI_OPCODE_EMIT:
941 break;
942 case TGSI_OPCODE_ENDPRIM:
943 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200944 case TGSI_OPCODE_BGNLOOP: {
Zack Rusine7611612008-02-11 09:43:59 -0500945 }
946 break;
947 case TGSI_OPCODE_BGNSUB: {
948 }
949 break;
Michal Krolcb90c432009-07-31 18:12:53 +0200950 case TGSI_OPCODE_ENDLOOP: {
Zack Rusine7611612008-02-11 09:43:59 -0500951 }
952 break;
953 case TGSI_OPCODE_ENDSUB: {
954 }
955 break;
956 case TGSI_OPCODE_NOISE1:
957 break;
958 case TGSI_OPCODE_NOISE2:
959 break;
960 case TGSI_OPCODE_NOISE3:
961 break;
962 case TGSI_OPCODE_NOISE4:
963 break;
964 case TGSI_OPCODE_NOP:
965 break;
Zack Rusine7611612008-02-11 09:43:59 -0500966 case TGSI_OPCODE_NRM4:
967 break;
968 case TGSI_OPCODE_CALLNZ:
969 break;
970 case TGSI_OPCODE_IFC:
971 break;
972 case TGSI_OPCODE_BREAKC:
973 break;
Michal Krolf633b142008-08-13 10:58:54 +0200974 case TGSI_OPCODE_KIL: {
975 }
Zack Rusine7611612008-02-11 09:43:59 -0500976 break;
977 case TGSI_OPCODE_END:
978 instr->end();
979 return;
980 break;
981 default:
982 fprintf(stderr, "ERROR: Unknown opcode %d\n",
983 inst->Instruction.Opcode);
984 assert(0);
985 break;
986 }
987
988 if (!out[0]) {
989 fprintf(stderr, "ERROR: unsupported opcode %d\n",
990 inst->Instruction.Opcode);
991 assert(!"Unsupported opcode");
992 }
993
994 /* store results */
995 for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
Keith Whitwell7d6c8f92009-11-24 15:02:23 +0000996 struct tgsi_full_dst_register *dst = &inst->Dst[i];
Keith Whitwell5b0824d2009-11-24 15:08:55 +0000997 storage->store((enum tgsi_file_type)dst->Register.File,
998 dst->Register.Index, out, dst->Register.WriteMask,
Stephane Marchesinb81a7dc2008-10-30 23:52:59 +0100999 instr->getIRBuilder() );
Zack Rusine7611612008-02-11 09:43:59 -05001000 }
1001}
1002
Zack Rusin7d690902008-02-04 10:07:02 -05001003llvm::Module *
1004tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens)
1005{
Zack Rusin12d5b072008-02-13 08:46:05 -05001006 llvm::Module *mod = new Module("shader");
Zack Rusin7d690902008-02-04 10:07:02 -05001007 struct tgsi_parse_context parse;
1008 struct tgsi_full_instruction fi;
1009 struct tgsi_full_declaration fd;
1010 unsigned instno = 0;
1011 Function* shader = mod->getFunction("execute_shader");
1012 std::ostringstream stream;
1013 if (ir->type == GALLIVM_VS) {
1014 stream << "vs_shader";
1015 } else {
1016 stream << "fs_shader";
1017 }
1018 stream << ir->id;
1019 std::string func_name = stream.str();
1020 shader->setName(func_name.c_str());
1021
1022 Function::arg_iterator args = shader->arg_begin();
1023 Value *ptr_INPUT = args++;
1024 ptr_INPUT->setName("input");
1025
Zack Rusinfb1c0932008-04-21 15:15:31 -04001026 BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0);
Zack Rusin7d690902008-02-04 10:07:02 -05001027
1028 tgsi_parse_init(&parse, tokens);
1029
1030 fi = tgsi_default_full_instruction();
1031 fd = tgsi_default_full_declaration();
1032 Storage storage(label_entry, ptr_INPUT);
1033 Instructions instr(mod, shader, label_entry, &storage);
1034 while(!tgsi_parse_end_of_tokens(&parse)) {
1035 tgsi_parse_token(&parse);
1036
1037 switch (parse.FullToken.Token.Type) {
1038 case TGSI_TOKEN_TYPE_DECLARATION:
1039 translate_declaration(ir, mod, &storage,
1040 &parse.FullToken.FullDeclaration,
1041 &fd);
1042 break;
1043
1044 case TGSI_TOKEN_TYPE_IMMEDIATE:
1045 translate_immediate(&storage,
1046 &parse.FullToken.FullImmediate);
1047 break;
1048
1049 case TGSI_TOKEN_TYPE_INSTRUCTION:
1050 translate_instruction(mod, &storage, &instr,
1051 &parse.FullToken.FullInstruction,
1052 &fi, instno);
1053 ++instno;
1054 break;
1055
1056 default:
1057 assert(0);
1058 }
1059 }
1060
1061 tgsi_parse_free(&parse);
1062
1063 ir->num_consts = storage.numConsts();
1064 return mod;
1065}
Zack Rusine7611612008-02-11 09:43:59 -05001066
1067llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir,
1068 const struct tgsi_token *tokens)
1069{
Zack Rusin3c3c1ff2008-02-12 23:08:42 -05001070 llvm::Module *mod = new Module("shader");
Zack Rusine7611612008-02-11 09:43:59 -05001071 struct tgsi_parse_context parse;
1072 struct tgsi_full_instruction fi;
1073 struct tgsi_full_declaration fd;
1074 unsigned instno = 0;
Zack Rusine7611612008-02-11 09:43:59 -05001075 std::ostringstream stream;
1076 if (ir->type == GALLIVM_VS) {
1077 stream << "vs_shader";
1078 } else {
1079 stream << "fs_shader";
1080 }
Zack Rusin4c845622008-02-13 00:48:08 -05001081 //stream << ir->id;
Zack Rusine7611612008-02-11 09:43:59 -05001082 std::string func_name = stream.str();
Zack Rusin3c3c1ff2008-02-12 23:08:42 -05001083 Function *shader = llvm::cast<Function>(mod->getOrInsertFunction(
1084 func_name.c_str(),
Zack Rusin9b6532f2008-02-13 00:21:24 -05001085 vertexShaderFunctionType()));
Zack Rusine7611612008-02-11 09:43:59 -05001086
1087 Function::arg_iterator args = shader->arg_begin();
1088 Value *input = args++;
Zack Rusin9b6532f2008-02-13 00:21:24 -05001089 input->setName("inputs");
Zack Rusine7611612008-02-11 09:43:59 -05001090 Value *output = args++;
Zack Rusin9b6532f2008-02-13 00:21:24 -05001091 output->setName("outputs");
Zack Rusine7611612008-02-11 09:43:59 -05001092 Value *consts = args++;
1093 consts->setName("consts");
1094
Zack Rusinfb1c0932008-04-21 15:15:31 -04001095 BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0);
Zack Rusine7611612008-02-11 09:43:59 -05001096
1097 tgsi_parse_init(&parse, tokens);
1098
1099 fi = tgsi_default_full_instruction();
1100 fd = tgsi_default_full_declaration();
1101
Stephane Marchesinb81a7dc2008-10-30 23:52:59 +01001102 StorageSoa storage(label_entry, input, output, consts);
Zack Rusine7611612008-02-11 09:43:59 -05001103 InstructionsSoa instr(mod, shader, label_entry, &storage);
1104
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_declarationir(ir, mod, &storage,
1111 &parse.FullToken.FullDeclaration,
1112 &fd);
1113 break;
1114
1115 case TGSI_TOKEN_TYPE_IMMEDIATE:
1116 translate_immediateir(&storage,
1117 &parse.FullToken.FullImmediate);
1118 break;
1119
1120 case TGSI_TOKEN_TYPE_INSTRUCTION:
Zack Rusinf70cc892008-02-14 22:42:57 -05001121 storage.declareImmediates();
Zack Rusine7611612008-02-11 09:43:59 -05001122 translate_instructionir(mod, &storage, &instr,
1123 &parse.FullToken.FullInstruction,
1124 &fi, instno);
1125 ++instno;
1126 break;
1127
1128 default:
1129 assert(0);
1130 }
1131 }
1132
1133 tgsi_parse_free(&parse);
1134
1135 return mod;
1136}