tgsitollvm.cpp

Go to the documentation of this file.
00001 #include "tgsitollvm.h"
00002 
00003 #include "gallivm.h"
00004 #include "gallivm_p.h"
00005 
00006 #include "storage.h"
00007 #include "instructions.h"
00008 #include "storagesoa.h"
00009 #include "instructionssoa.h"
00010 
00011 #include "pipe/p_shader_tokens.h"
00012 
00013 #include "tgsi/tgsi_parse.h"
00014 #include "tgsi/tgsi_exec.h"
00015 #include "tgsi/tgsi_util.h"
00016 #include "tgsi/tgsi_build.h"
00017 #include "tgsi/tgsi_dump.h"
00018 
00019 
00020 #include <llvm/Module.h>
00021 #include <llvm/CallingConv.h>
00022 #include <llvm/Constants.h>
00023 #include <llvm/DerivedTypes.h>
00024 #include <llvm/Instructions.h>
00025 #include <llvm/ModuleProvider.h>
00026 #include <llvm/Pass.h>
00027 #include <llvm/PassManager.h>
00028 #include <llvm/ParameterAttributes.h>
00029 #include <llvm/Support/PatternMatch.h>
00030 #include <llvm/ExecutionEngine/JIT.h>
00031 #include <llvm/ExecutionEngine/Interpreter.h>
00032 #include <llvm/ExecutionEngine/GenericValue.h>
00033 #include <llvm/Support/MemoryBuffer.h>
00034 #include <llvm/LinkAllPasses.h>
00035 #include <llvm/Analysis/Verifier.h>
00036 #include <llvm/Analysis/LoopPass.h>
00037 #include <llvm/Target/TargetData.h>
00038 #include <llvm/Bitcode/ReaderWriter.h>
00039 #include <llvm/Transforms/Utils/Cloning.h>
00040 
00041 
00042 #include <sstream>
00043 #include <fstream>
00044 #include <iostream>
00045 
00046 using namespace llvm;
00047 
00048 static inline FunctionType *vertexShaderFunctionType()
00049 {
00050    //Function takes three arguments,
00051    // the calling code has to make sure the types it will
00052    // pass are castable to the following:
00053    // [4 x <4 x float>] inputs,
00054    // [4 x <4 x float>] output,
00055    // [4 x [4 x float]] consts,
00056    // [4 x <4 x float>] temps
00057 
00058    std::vector<const Type*> funcArgs;
00059    VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
00060    ArrayType *vectorArray = ArrayType::get(vectorType, 4);
00061    PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0);
00062 
00063    ArrayType   *floatArray     = ArrayType::get(Type::FloatTy, 4);
00064    ArrayType   *constsArray    = ArrayType::get(floatArray, 4);
00065    PointerType *constsArrayPtr = PointerType::get(constsArray, 0);
00066 
00067    funcArgs.push_back(vectorArrayPtr);//inputs
00068    funcArgs.push_back(vectorArrayPtr);//output
00069    funcArgs.push_back(constsArrayPtr);//consts
00070    funcArgs.push_back(vectorArrayPtr);//temps
00071 
00072    FunctionType *functionType = FunctionType::get(
00073       /*Result=*/Type::VoidTy,
00074       /*Params=*/funcArgs,
00075       /*isVarArg=*/false);
00076 
00077    return functionType;
00078 }
00079 
00080 static inline void
00081 add_interpolator(struct gallivm_ir *ir,
00082                  struct gallivm_interpolate *interp)
00083 {
00084    ir->interpolators[ir->num_interp] = *interp;
00085    ++ir->num_interp;
00086 }
00087 
00088 static void
00089 translate_declaration(struct gallivm_ir *prog,
00090                       llvm::Module *module,
00091                       Storage *storage,
00092                       struct tgsi_full_declaration *decl,
00093                       struct tgsi_full_declaration *fd)
00094 {
00095    if (decl->Declaration.File == TGSI_FILE_INPUT) {
00096       unsigned first, last, mask;
00097       uint interp_method;
00098 
00099       first = decl->DeclarationRange.First;
00100       last = decl->DeclarationRange.Last;
00101       mask = decl->Declaration.UsageMask;
00102 
00103       /* Do not touch WPOS.xy */
00104       if (first == 0) {
00105          mask &= ~TGSI_WRITEMASK_XY;
00106          if (mask == TGSI_WRITEMASK_NONE) {
00107             first++;
00108             if (first > last) {
00109                return;
00110             }
00111          }
00112       }
00113 
00114       interp_method = decl->Declaration.Interpolate;
00115 
00116       if (mask == TGSI_WRITEMASK_XYZW) {
00117          unsigned i, j;
00118 
00119          for (i = first; i <= last; i++) {
00120             for (j = 0; j < NUM_CHANNELS; j++) {
00121                //interp( mach, i, j );
00122                struct gallivm_interpolate interp;
00123                interp.type = interp_method;
00124                interp.attrib = i;
00125                interp.chan = j;
00126                add_interpolator(prog, &interp);
00127             }
00128          }
00129       } else {
00130          unsigned i, j;
00131          for( j = 0; j < NUM_CHANNELS; j++ ) {
00132             if( mask & (1 << j) ) {
00133                for( i = first; i <= last; i++ ) {
00134                   struct gallivm_interpolate interp;
00135                   interp.type = interp_method;
00136                   interp.attrib = i;
00137                   interp.chan = j;
00138                   add_interpolator(prog, &interp);
00139                }
00140             }
00141          }
00142       }
00143    }
00144 }
00145 
00146 static void
00147 translate_declarationir(struct gallivm_ir *,
00148                       llvm::Module *,
00149                       StorageSoa *storage,
00150                       struct tgsi_full_declaration *decl,
00151                       struct tgsi_full_declaration *)
00152 {
00153    if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
00154       int idx = decl->DeclarationRange.First;
00155       storage->addAddress(idx);
00156    }
00157 }
00158 
00159 static void
00160 translate_immediate(Storage *storage,
00161                     struct tgsi_full_immediate *imm)
00162 {
00163    float vec[4];
00164    int i;
00165    for (i = 0; i < imm->Immediate.Size - 1; ++i) {
00166       switch (imm->Immediate.DataType) {
00167       case TGSI_IMM_FLOAT32:
00168          vec[i] = imm->u.ImmediateFloat32[i].Float;
00169          break;
00170       default:
00171          assert(0);
00172       }
00173    }
00174    storage->addImmediate(vec);
00175 }
00176 
00177 
00178 static void
00179 translate_immediateir(StorageSoa *storage,
00180                       struct tgsi_full_immediate *imm)
00181 {
00182    float vec[4];
00183    int i;
00184    for (i = 0; i < imm->Immediate.Size - 1; ++i) {
00185       switch (imm->Immediate.DataType) {
00186       case TGSI_IMM_FLOAT32:
00187          vec[i] = imm->u.ImmediateFloat32[i].Float;
00188          break;
00189       default:
00190          assert(0);
00191       }
00192    }
00193    storage->addImmediate(vec);
00194 }
00195 
00196 static inline int
00197 swizzleInt(struct tgsi_full_src_register *src)
00198 {
00199    int swizzle = 0;
00200    int start = 1000;
00201 
00202    for (int k = 0; k < 4; ++k) {
00203       swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start;
00204       start /= 10;
00205    }
00206    return swizzle;
00207 }
00208 
00209 static inline llvm::Value *
00210 swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src,
00211               Storage *storage)
00212 {
00213    int swizzle = swizzleInt(src);
00214 
00215    if (gallivm_is_swizzle(swizzle)) {
00216       /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/
00217       val = storage->shuffleVector(val, swizzle);
00218    }
00219    return val;
00220 }
00221 
00222 static void
00223 translate_instruction(llvm::Module *module,
00224                       Storage *storage,
00225                       Instructions *instr,
00226                       struct tgsi_full_instruction *inst,
00227                       struct tgsi_full_instruction *fi,
00228                       unsigned instno)
00229 {
00230    llvm::Value *inputs[4];
00231    inputs[0] = 0;
00232    inputs[1] = 0;
00233    inputs[2] = 0;
00234    inputs[3] = 0;
00235 
00236    for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
00237       struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
00238       llvm::Value *val = 0;
00239       llvm::Value *indIdx = 0;
00240 
00241       if (src->SrcRegister.Indirect) {
00242          indIdx = storage->addrElement(src->SrcRegisterInd.Index);
00243          indIdx = storage->extractIndex(indIdx);
00244       }
00245       if (src->SrcRegister.File == TGSI_FILE_CONSTANT) {
00246          val = storage->constElement(src->SrcRegister.Index, indIdx);
00247       } else if (src->SrcRegister.File == TGSI_FILE_INPUT) {
00248          val = storage->inputElement(src->SrcRegister.Index, indIdx);
00249       } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
00250          val = storage->tempElement(src->SrcRegister.Index);
00251       } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) {
00252          val = storage->outputElement(src->SrcRegister.Index, indIdx);
00253       } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
00254          val = storage->immediateElement(src->SrcRegister.Index);
00255       } else {
00256          fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
00257          return;
00258       }
00259 
00260       inputs[i] = swizzleVector(val, src, storage);
00261    }
00262 
00263    /*if (inputs[0])
00264      instr->printVector(inputs[0]);
00265      if (inputs[1])
00266      instr->printVector(inputs[1]);*/
00267    llvm::Value *out = 0;
00268    switch (inst->Instruction.Opcode) {
00269    case TGSI_OPCODE_ARL: {
00270       out = instr->arl(inputs[0]);
00271    }
00272       break;
00273    case TGSI_OPCODE_MOV: {
00274       out = inputs[0];
00275    }
00276       break;
00277    case TGSI_OPCODE_LIT: {
00278       out = instr->lit(inputs[0]);
00279    }
00280       break;
00281    case TGSI_OPCODE_RCP: {
00282       out = instr->rcp(inputs[0]);
00283    }
00284       break;
00285    case TGSI_OPCODE_RSQ: {
00286       out = instr->rsq(inputs[0]);
00287    }
00288       break;
00289    case TGSI_OPCODE_EXP: {
00290       out = instr->exp(inputs[0]);
00291    }
00292       break;
00293    case TGSI_OPCODE_LOG: {
00294       out = instr->log(inputs[0]);
00295    }
00296       break;
00297    case TGSI_OPCODE_MUL: {
00298       out = instr->mul(inputs[0], inputs[1]);
00299    }
00300       break;
00301    case TGSI_OPCODE_ADD: {
00302       out = instr->add(inputs[0], inputs[1]);
00303    }
00304       break;
00305    case TGSI_OPCODE_DP3: {
00306       out = instr->dp3(inputs[0], inputs[1]);
00307    }
00308       break;
00309    case TGSI_OPCODE_DP4: {
00310       out = instr->dp4(inputs[0], inputs[1]);
00311    }
00312       break;
00313    case TGSI_OPCODE_DST: {
00314       out = instr->dst(inputs[0], inputs[1]);
00315    }
00316       break;
00317    case TGSI_OPCODE_MIN: {
00318       out = instr->min(inputs[0], inputs[1]);
00319    }
00320       break;
00321    case TGSI_OPCODE_MAX: {
00322       out = instr->max(inputs[0], inputs[1]);
00323    }
00324       break;
00325    case TGSI_OPCODE_SLT: {
00326       out = instr->slt(inputs[0], inputs[1]);
00327    }
00328       break;
00329    case TGSI_OPCODE_SGE: {
00330       out = instr->sge(inputs[0], inputs[1]);
00331    }
00332       break;
00333    case TGSI_OPCODE_MAD: {
00334       out = instr->madd(inputs[0], inputs[1], inputs[2]);
00335    }
00336       break;
00337    case TGSI_OPCODE_SUB: {
00338       out = instr->sub(inputs[0], inputs[1]);
00339    }
00340       break;
00341    case TGSI_OPCODE_LERP: {
00342       out = instr->lerp(inputs[0], inputs[1], inputs[2]);
00343    }
00344       break;
00345    case TGSI_OPCODE_CND: {
00346       out = instr->cnd(inputs[0], inputs[1], inputs[2]);
00347    }
00348       break;
00349    case TGSI_OPCODE_CND0: {
00350       out = instr->cnd0(inputs[0], inputs[1], inputs[2]);
00351    }
00352       break;
00353    case TGSI_OPCODE_DOT2ADD: {
00354       out = instr->dot2add(inputs[0], inputs[1], inputs[2]);
00355    }
00356       break;
00357    case TGSI_OPCODE_INDEX:
00358       break;
00359    case TGSI_OPCODE_NEGATE: {
00360       out = instr->neg(inputs[0]);
00361    }
00362       break;
00363    case TGSI_OPCODE_FRAC: {
00364       out = instr->frc(inputs[0]);
00365    }
00366       break;
00367    case TGSI_OPCODE_CLAMP: {
00368       out = instr->clamp(inputs[0]);
00369    }
00370       break;
00371    case TGSI_OPCODE_FLOOR: {
00372       out = instr->floor(inputs[0]);
00373    }
00374       break;
00375    case TGSI_OPCODE_ROUND:
00376       break;
00377    case TGSI_OPCODE_EXPBASE2: {
00378       out = instr->ex2(inputs[0]);
00379    }
00380       break;
00381    case TGSI_OPCODE_LOGBASE2: {
00382       out = instr->lg2(inputs[0]);
00383    }
00384       break;
00385    case TGSI_OPCODE_POWER: {
00386       out = instr->pow(inputs[0], inputs[1]);
00387    }
00388       break;
00389    case TGSI_OPCODE_CROSSPRODUCT: {
00390       out = instr->cross(inputs[0], inputs[1]);
00391    }
00392       break;
00393    case TGSI_OPCODE_MULTIPLYMATRIX:
00394       break;
00395    case TGSI_OPCODE_ABS: {
00396       out = instr->abs(inputs[0]);
00397    }
00398       break;
00399    case TGSI_OPCODE_RCC:
00400       break;
00401    case TGSI_OPCODE_DPH: {
00402       out = instr->dph(inputs[0], inputs[1]);
00403    }
00404       break;
00405    case TGSI_OPCODE_COS: {
00406       out = instr->cos(inputs[0]);
00407    }
00408       break;
00409    case TGSI_OPCODE_DDX: {
00410       out = instr->ddx(inputs[0]);
00411    }
00412       break;
00413    case TGSI_OPCODE_DDY: {
00414       out = instr->ddy(inputs[0]);
00415    }
00416       break;
00417    case TGSI_OPCODE_KILP:
00418       break;
00419    case TGSI_OPCODE_PK2H:
00420       break;
00421    case TGSI_OPCODE_PK2US:
00422       break;
00423    case TGSI_OPCODE_PK4B:
00424       break;
00425    case TGSI_OPCODE_PK4UB:
00426       break;
00427    case TGSI_OPCODE_RFL:
00428       break;
00429    case TGSI_OPCODE_SEQ: {
00430       out = instr->seq(inputs[0], inputs[1]);
00431    }
00432       break;
00433    case TGSI_OPCODE_SFL: {
00434       out = instr->sfl(inputs[0], inputs[1]);
00435    }
00436       break;
00437    case TGSI_OPCODE_SGT: {
00438       out = instr->sgt(inputs[0], inputs[1]);
00439    }
00440       break;
00441    case TGSI_OPCODE_SIN: {
00442       out = instr->sin(inputs[0]);
00443    }
00444       break;
00445    case TGSI_OPCODE_SLE: {
00446       out = instr->sle(inputs[0], inputs[1]);
00447    }
00448       break;
00449    case TGSI_OPCODE_SNE: {
00450       out = instr->sne(inputs[0], inputs[1]);
00451    }
00452       break;
00453    case TGSI_OPCODE_STR: {
00454       out = instr->str(inputs[0], inputs[1]);
00455    }
00456       break;
00457    case TGSI_OPCODE_TEX:
00458       break;
00459    case TGSI_OPCODE_TXD:
00460       break;
00461    case TGSI_OPCODE_UP2H:
00462       break;
00463    case TGSI_OPCODE_UP2US:
00464       break;
00465    case TGSI_OPCODE_UP4B:
00466       break;
00467    case TGSI_OPCODE_UP4UB:
00468       break;
00469    case TGSI_OPCODE_X2D: {
00470       out = instr->x2d(inputs[0], inputs[1], inputs[2]);
00471    }
00472       break;
00473    case TGSI_OPCODE_ARA:
00474       break;
00475    case TGSI_OPCODE_ARR:
00476       break;
00477    case TGSI_OPCODE_BRA:
00478       break;
00479    case TGSI_OPCODE_CAL: {
00480       instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr());
00481       return;
00482    }
00483       break;
00484    case TGSI_OPCODE_RET: {
00485       instr->end();
00486       return;
00487    }
00488       break;
00489    case TGSI_OPCODE_SSG:
00490       break;
00491    case TGSI_OPCODE_CMP: {
00492       out = instr->cmp(inputs[0], inputs[1], inputs[2]);
00493    }
00494       break;
00495    case TGSI_OPCODE_SCS: {
00496       out = instr->scs(inputs[0]);
00497    }
00498       break;
00499    case TGSI_OPCODE_TXB:
00500       break;
00501    case TGSI_OPCODE_NRM4:
00502    case TGSI_OPCODE_NRM: {
00503       out = instr->nrm(inputs[0]);
00504    }
00505       break;
00506    case TGSI_OPCODE_DIV: {
00507       out = instr->div(inputs[0], inputs[1]);
00508    }
00509       break;
00510    case TGSI_OPCODE_DP2: {
00511       out = instr->dp2(inputs[0], inputs[1]);
00512    }
00513       break;
00514    case TGSI_OPCODE_TXL:
00515       break;
00516    case TGSI_OPCODE_BRK: {
00517       instr->brk();
00518       return;
00519    }
00520       break;
00521    case TGSI_OPCODE_IF: {
00522       instr->ifop(inputs[0]);
00523       storage->setCurrentBlock(instr->currentBlock());
00524       return;  //just update the state
00525    }
00526       break;
00527    case TGSI_OPCODE_LOOP:
00528       break;
00529    case TGSI_OPCODE_REP:
00530       break;
00531    case TGSI_OPCODE_ELSE: {
00532       instr->elseop();
00533       storage->setCurrentBlock(instr->currentBlock());
00534       return; //only state update
00535    }
00536       break;
00537    case TGSI_OPCODE_ENDIF: {
00538       instr->endif();
00539       storage->setCurrentBlock(instr->currentBlock());
00540       return; //just update the state
00541    }
00542       break;
00543    case TGSI_OPCODE_ENDLOOP:
00544       break;
00545    case TGSI_OPCODE_ENDREP:
00546       break;
00547    case TGSI_OPCODE_PUSHA:
00548       break;
00549    case TGSI_OPCODE_POPA:
00550       break;
00551    case TGSI_OPCODE_CEIL:
00552       break;
00553    case TGSI_OPCODE_I2F:
00554       break;
00555    case TGSI_OPCODE_NOT:
00556       break;
00557    case TGSI_OPCODE_TRUNC: {
00558       out = instr->trunc(inputs[0]);
00559    }
00560       break;
00561    case TGSI_OPCODE_SHL:
00562       break;
00563    case TGSI_OPCODE_SHR:
00564       break;
00565    case TGSI_OPCODE_AND:
00566       break;
00567    case TGSI_OPCODE_OR:
00568       break;
00569    case TGSI_OPCODE_MOD:
00570       break;
00571    case TGSI_OPCODE_XOR:
00572       break;
00573    case TGSI_OPCODE_SAD:
00574       break;
00575    case TGSI_OPCODE_TXF:
00576       break;
00577    case TGSI_OPCODE_TXQ:
00578       break;
00579    case TGSI_OPCODE_CONT:
00580       break;
00581    case TGSI_OPCODE_EMIT:
00582       break;
00583    case TGSI_OPCODE_ENDPRIM:
00584       break;
00585    case TGSI_OPCODE_BGNLOOP2: {
00586       instr->beginLoop();
00587       storage->setCurrentBlock(instr->currentBlock());
00588       return;
00589    }
00590       break;
00591    case TGSI_OPCODE_BGNSUB: {
00592       instr->bgnSub(instno);
00593       storage->setCurrentBlock(instr->currentBlock());
00594       storage->pushTemps();
00595       return;
00596    }
00597       break;
00598    case TGSI_OPCODE_ENDLOOP2: {
00599       instr->endLoop();
00600       storage->setCurrentBlock(instr->currentBlock());
00601       return;
00602    }
00603       break;
00604    case TGSI_OPCODE_ENDSUB: {
00605       instr->endSub();
00606       storage->setCurrentBlock(instr->currentBlock());
00607       storage->popArguments();
00608       storage->popTemps();
00609       return;
00610    }
00611       break;
00612    case TGSI_OPCODE_NOISE1:
00613       break;
00614    case TGSI_OPCODE_NOISE2:
00615       break;
00616    case TGSI_OPCODE_NOISE3:
00617       break;
00618    case TGSI_OPCODE_NOISE4:
00619       break;
00620    case TGSI_OPCODE_NOP:
00621       break;
00622    case TGSI_OPCODE_M4X3:
00623       break;
00624    case TGSI_OPCODE_M3X4:
00625       break;
00626    case TGSI_OPCODE_M3X3:
00627       break;
00628    case TGSI_OPCODE_M3X2:
00629       break;
00630    case TGSI_OPCODE_CALLNZ:
00631       break;
00632    case TGSI_OPCODE_IFC:
00633       break;
00634    case TGSI_OPCODE_BREAKC:
00635       break;
00636    case TGSI_OPCODE_KIL: {
00637       out = instr->kil(inputs[0]);
00638       storage->setKilElement(out);
00639       return;
00640    }
00641       break;
00642    case TGSI_OPCODE_END:
00643       instr->end();
00644       return;
00645       break;
00646    default:
00647       fprintf(stderr, "ERROR: Unknown opcode %d\n",
00648               inst->Instruction.Opcode);
00649       assert(0);
00650       break;
00651    }
00652 
00653    if (!out) {
00654       fprintf(stderr, "ERROR: unsupported opcode %d\n",
00655               inst->Instruction.Opcode);
00656       assert(!"Unsupported opcode");
00657    }
00658 
00659    /* # not sure if we need this */
00660    switch( inst->Instruction.Saturate ) {
00661    case TGSI_SAT_NONE:
00662       break;
00663    case TGSI_SAT_ZERO_ONE:
00664       /*TXT( "_SAT" );*/
00665       break;
00666    case TGSI_SAT_MINUS_PLUS_ONE:
00667       /*TXT( "_SAT[-1,1]" );*/
00668       break;
00669    default:
00670       assert( 0 );
00671    }
00672 
00673    /* store results  */
00674    for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
00675       struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
00676 
00677       if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
00678          storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
00679       } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) {
00680          storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
00681       } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) {
00682          storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
00683       } else {
00684          fprintf(stderr, "ERROR: unsupported LLVM destination!");
00685          assert(!"wrong destination");
00686       }
00687    }
00688 }
00689 
00690 
00691 static void
00692 translate_instructionir(llvm::Module *module,
00693                         StorageSoa *storage,
00694                         InstructionsSoa *instr,
00695                         struct tgsi_full_instruction *inst,
00696                         struct tgsi_full_instruction *fi,
00697                         unsigned instno)
00698 {
00699    std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs);
00700 
00701    for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
00702       struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
00703       std::vector<llvm::Value*> val;
00704       llvm::Value *indIdx = 0;
00705       int swizzle = swizzleInt(src);
00706 
00707       if (src->SrcRegister.Indirect) {
00708          indIdx = storage->addrElement(src->SrcRegisterInd.Index);
00709       }
00710 
00711       val = storage->load((enum tgsi_file_type)src->SrcRegister.File,
00712                           src->SrcRegister.Index, swizzle, indIdx);
00713 
00714       inputs[i] = val;
00715    }
00716 
00717    std::vector<llvm::Value*> out(4);
00718    switch (inst->Instruction.Opcode) {
00719    case TGSI_OPCODE_ARL: {
00720       out = instr->arl(inputs[0]);
00721    }
00722       break;
00723    case TGSI_OPCODE_MOV: {
00724       out = inputs[0];
00725    }
00726       break;
00727    case TGSI_OPCODE_LIT: {
00728       out = instr->lit(inputs[0]);
00729    }
00730       break;
00731    case TGSI_OPCODE_RCP: {
00732    }
00733       break;
00734    case TGSI_OPCODE_RSQ: {
00735       out = instr->rsq(inputs[0]);
00736    }
00737       break;
00738    case TGSI_OPCODE_EXP:
00739       break;
00740    case TGSI_OPCODE_LOG:
00741       break;
00742    case TGSI_OPCODE_MUL: {
00743       out = instr->mul(inputs[0], inputs[1]);
00744    }
00745       break;
00746    case TGSI_OPCODE_ADD: {
00747       out = instr->add(inputs[0], inputs[1]);
00748    }
00749       break;
00750    case TGSI_OPCODE_DP3: {
00751       out = instr->dp3(inputs[0], inputs[1]);
00752    }
00753       break;
00754    case TGSI_OPCODE_DP4: {
00755       out = instr->dp4(inputs[0], inputs[1]);
00756    }
00757       break;
00758    case TGSI_OPCODE_DST: {
00759    }
00760       break;
00761    case TGSI_OPCODE_MIN: {
00762       out = instr->min(inputs[0], inputs[1]);
00763    }
00764       break;
00765    case TGSI_OPCODE_MAX: {
00766       out = instr->max(inputs[0], inputs[1]);
00767    }
00768       break;
00769    case TGSI_OPCODE_SLT: {
00770       out = instr->slt(inputs[0], inputs[1]);
00771    }
00772       break;
00773    case TGSI_OPCODE_SGE: {
00774    }
00775       break;
00776    case TGSI_OPCODE_MAD: {
00777       out = instr->madd(inputs[0], inputs[1], inputs[2]);
00778    }
00779       break;
00780    case TGSI_OPCODE_SUB: {
00781       out = instr->sub(inputs[0], inputs[1]);
00782    }
00783       break;
00784    case TGSI_OPCODE_LERP: {
00785    }
00786       break;
00787    case TGSI_OPCODE_CND:
00788       break;
00789    case TGSI_OPCODE_CND0:
00790       break;
00791    case TGSI_OPCODE_DOT2ADD:
00792       break;
00793    case TGSI_OPCODE_INDEX:
00794       break;
00795    case TGSI_OPCODE_NEGATE:
00796       break;
00797    case TGSI_OPCODE_FRAC: {
00798    }
00799       break;
00800    case TGSI_OPCODE_CLAMP:
00801       break;
00802    case TGSI_OPCODE_FLOOR: {
00803    }
00804       break;
00805    case TGSI_OPCODE_ROUND:
00806       break;
00807    case TGSI_OPCODE_EXPBASE2: {
00808    }
00809       break;
00810    case TGSI_OPCODE_LOGBASE2: {
00811    }
00812       break;
00813    case TGSI_OPCODE_POWER: {
00814       out = instr->pow(inputs[0], inputs[1]);
00815    }
00816       break;
00817    case TGSI_OPCODE_CROSSPRODUCT: {
00818    }
00819       break;
00820    case TGSI_OPCODE_MULTIPLYMATRIX:
00821       break;
00822    case TGSI_OPCODE_ABS: {
00823       out = instr->abs(inputs[0]);
00824    }
00825       break;
00826    case TGSI_OPCODE_RCC:
00827       break;
00828    case TGSI_OPCODE_DPH: {
00829    }
00830       break;
00831    case TGSI_OPCODE_COS: {
00832    }
00833       break;
00834    case TGSI_OPCODE_DDX:
00835       break;
00836    case TGSI_OPCODE_DDY:
00837       break;
00838    case TGSI_OPCODE_KILP:
00839       break;
00840    case TGSI_OPCODE_PK2H:
00841       break;
00842    case TGSI_OPCODE_PK2US:
00843       break;
00844    case TGSI_OPCODE_PK4B:
00845       break;
00846    case TGSI_OPCODE_PK4UB:
00847       break;
00848    case TGSI_OPCODE_RFL:
00849       break;
00850    case TGSI_OPCODE_SEQ:
00851       break;
00852    case TGSI_OPCODE_SFL:
00853       break;
00854    case TGSI_OPCODE_SGT: {
00855    }
00856       break;
00857    case TGSI_OPCODE_SIN: {
00858    }
00859       break;
00860    case TGSI_OPCODE_SLE:
00861       break;
00862    case TGSI_OPCODE_SNE:
00863       break;
00864    case TGSI_OPCODE_STR:
00865       break;
00866    case TGSI_OPCODE_TEX:
00867       break;
00868    case TGSI_OPCODE_TXD:
00869       break;
00870    case TGSI_OPCODE_UP2H:
00871       break;
00872    case TGSI_OPCODE_UP2US:
00873       break;
00874    case TGSI_OPCODE_UP4B:
00875       break;
00876    case TGSI_OPCODE_UP4UB:
00877       break;
00878    case TGSI_OPCODE_X2D:
00879       break;
00880    case TGSI_OPCODE_ARA:
00881       break;
00882    case TGSI_OPCODE_ARR:
00883       break;
00884    case TGSI_OPCODE_BRA:
00885       break;
00886    case TGSI_OPCODE_CAL: {
00887    }
00888       break;
00889    case TGSI_OPCODE_RET: {
00890    }
00891       break;
00892    case TGSI_OPCODE_SSG:
00893       break;
00894    case TGSI_OPCODE_CMP: {
00895    }
00896       break;
00897    case TGSI_OPCODE_SCS: {
00898    }
00899       break;
00900    case TGSI_OPCODE_TXB:
00901       break;
00902    case TGSI_OPCODE_NRM:
00903       break;
00904    case TGSI_OPCODE_DIV:
00905       break;
00906    case TGSI_OPCODE_DP2:
00907       break;
00908    case TGSI_OPCODE_TXL:
00909       break;
00910    case TGSI_OPCODE_BRK: {
00911    }
00912       break;
00913    case TGSI_OPCODE_IF: {
00914    }
00915       break;
00916    case TGSI_OPCODE_LOOP:
00917       break;
00918    case TGSI_OPCODE_REP:
00919       break;
00920    case TGSI_OPCODE_ELSE: {
00921    }
00922       break;
00923    case TGSI_OPCODE_ENDIF: {
00924    }
00925       break;
00926    case TGSI_OPCODE_ENDLOOP:
00927       break;
00928    case TGSI_OPCODE_ENDREP:
00929       break;
00930    case TGSI_OPCODE_PUSHA:
00931       break;
00932    case TGSI_OPCODE_POPA:
00933       break;
00934    case TGSI_OPCODE_CEIL:
00935       break;
00936    case TGSI_OPCODE_I2F:
00937       break;
00938    case TGSI_OPCODE_NOT:
00939       break;
00940    case TGSI_OPCODE_TRUNC: {
00941    }
00942       break;
00943    case TGSI_OPCODE_SHL:
00944       break;
00945    case TGSI_OPCODE_SHR:
00946       break;
00947    case TGSI_OPCODE_AND:
00948       break;
00949    case TGSI_OPCODE_OR:
00950       break;
00951    case TGSI_OPCODE_MOD:
00952       break;
00953    case TGSI_OPCODE_XOR:
00954       break;
00955    case TGSI_OPCODE_SAD:
00956       break;
00957    case TGSI_OPCODE_TXF:
00958       break;
00959    case TGSI_OPCODE_TXQ:
00960       break;
00961    case TGSI_OPCODE_CONT:
00962       break;
00963    case TGSI_OPCODE_EMIT:
00964       break;
00965    case TGSI_OPCODE_ENDPRIM:
00966       break;
00967    case TGSI_OPCODE_BGNLOOP2: {
00968    }
00969       break;
00970    case TGSI_OPCODE_BGNSUB: {
00971    }
00972       break;
00973    case TGSI_OPCODE_ENDLOOP2: {
00974    }
00975       break;
00976    case TGSI_OPCODE_ENDSUB: {
00977    }
00978       break;
00979    case TGSI_OPCODE_NOISE1:
00980       break;
00981    case TGSI_OPCODE_NOISE2:
00982       break;
00983    case TGSI_OPCODE_NOISE3:
00984       break;
00985    case TGSI_OPCODE_NOISE4:
00986       break;
00987    case TGSI_OPCODE_NOP:
00988       break;
00989    case TGSI_OPCODE_M4X3:
00990       break;
00991    case TGSI_OPCODE_M3X4:
00992       break;
00993    case TGSI_OPCODE_M3X3:
00994       break;
00995    case TGSI_OPCODE_M3X2:
00996       break;
00997    case TGSI_OPCODE_NRM4:
00998       break;
00999    case TGSI_OPCODE_CALLNZ:
01000       break;
01001    case TGSI_OPCODE_IFC:
01002       break;
01003    case TGSI_OPCODE_BREAKC:
01004       break;
01005    case TGSI_OPCODE_KIL: {
01006    }
01007       break;
01008    case TGSI_OPCODE_END:
01009       instr->end();
01010       return;
01011       break;
01012    default:
01013       fprintf(stderr, "ERROR: Unknown opcode %d\n",
01014               inst->Instruction.Opcode);
01015       assert(0);
01016       break;
01017    }
01018 
01019    if (!out[0]) {
01020       fprintf(stderr, "ERROR: unsupported opcode %d\n",
01021               inst->Instruction.Opcode);
01022       assert(!"Unsupported opcode");
01023    }
01024 
01025    /* store results  */
01026    for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
01027       struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
01028 
01029       storage->store((enum tgsi_file_type)dst->DstRegister.File,
01030                      dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
01031    }
01032 }
01033 
01034 llvm::Module *
01035 tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens)
01036 {
01037    llvm::Module *mod = new Module("shader");
01038    struct tgsi_parse_context parse;
01039    struct tgsi_full_instruction fi;
01040    struct tgsi_full_declaration fd;
01041    unsigned instno = 0;
01042    Function* shader = mod->getFunction("execute_shader");
01043    std::ostringstream stream;
01044    if (ir->type == GALLIVM_VS) {
01045       stream << "vs_shader";
01046    } else {
01047       stream << "fs_shader";
01048    }
01049    stream << ir->id;
01050    std::string func_name = stream.str();
01051    shader->setName(func_name.c_str());
01052 
01053    Function::arg_iterator args = shader->arg_begin();
01054    Value *ptr_INPUT = args++;
01055    ptr_INPUT->setName("input");
01056 
01057    BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0);
01058 
01059    tgsi_parse_init(&parse, tokens);
01060 
01061    fi = tgsi_default_full_instruction();
01062    fd = tgsi_default_full_declaration();
01063    Storage storage(label_entry, ptr_INPUT);
01064    Instructions instr(mod, shader, label_entry, &storage);
01065    while(!tgsi_parse_end_of_tokens(&parse)) {
01066       tgsi_parse_token(&parse);
01067 
01068       switch (parse.FullToken.Token.Type) {
01069       case TGSI_TOKEN_TYPE_DECLARATION:
01070          translate_declaration(ir, mod, &storage,
01071                                &parse.FullToken.FullDeclaration,
01072                                &fd);
01073          break;
01074 
01075       case TGSI_TOKEN_TYPE_IMMEDIATE:
01076          translate_immediate(&storage,
01077                              &parse.FullToken.FullImmediate);
01078          break;
01079 
01080       case TGSI_TOKEN_TYPE_INSTRUCTION:
01081          translate_instruction(mod, &storage, &instr,
01082                                &parse.FullToken.FullInstruction,
01083                                &fi, instno);
01084          ++instno;
01085          break;
01086 
01087       default:
01088          assert(0);
01089       }
01090    }
01091 
01092    tgsi_parse_free(&parse);
01093 
01094    ir->num_consts = storage.numConsts();
01095    return mod;
01096 }
01097 
01098 llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir,
01099                               const struct tgsi_token *tokens)
01100 {
01101    llvm::Module *mod = new Module("shader");
01102    struct tgsi_parse_context parse;
01103    struct tgsi_full_instruction fi;
01104    struct tgsi_full_declaration fd;
01105    unsigned instno = 0;
01106    std::ostringstream stream;
01107    if (ir->type == GALLIVM_VS) {
01108       stream << "vs_shader";
01109    } else {
01110       stream << "fs_shader";
01111    }
01112    //stream << ir->id;
01113    std::string func_name = stream.str();
01114    Function *shader = llvm::cast<Function>(mod->getOrInsertFunction(
01115                                               func_name.c_str(),
01116                                               vertexShaderFunctionType()));
01117 
01118    Function::arg_iterator args = shader->arg_begin();
01119    Value *input = args++;
01120    input->setName("inputs");
01121    Value *output = args++;
01122    output->setName("outputs");
01123    Value *consts = args++;
01124    consts->setName("consts");
01125    Value *temps = args++;
01126    temps->setName("temps");
01127 
01128    BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0);
01129 
01130    tgsi_parse_init(&parse, tokens);
01131 
01132    fi = tgsi_default_full_instruction();
01133    fd = tgsi_default_full_declaration();
01134 
01135    StorageSoa storage(label_entry, input, output, consts, temps);
01136    InstructionsSoa instr(mod, shader, label_entry, &storage);
01137 
01138    while(!tgsi_parse_end_of_tokens(&parse)) {
01139       tgsi_parse_token(&parse);
01140 
01141       switch (parse.FullToken.Token.Type) {
01142       case TGSI_TOKEN_TYPE_DECLARATION:
01143          translate_declarationir(ir, mod, &storage,
01144                                  &parse.FullToken.FullDeclaration,
01145                                  &fd);
01146          break;
01147 
01148       case TGSI_TOKEN_TYPE_IMMEDIATE:
01149          translate_immediateir(&storage,
01150                              &parse.FullToken.FullImmediate);
01151          break;
01152 
01153       case TGSI_TOKEN_TYPE_INSTRUCTION:
01154          storage.declareImmediates();
01155          translate_instructionir(mod, &storage, &instr,
01156                                  &parse.FullToken.FullInstruction,
01157                                  &fi, instno);
01158          ++instno;
01159          break;
01160 
01161       default:
01162          assert(0);
01163       }
01164    }
01165 
01166    tgsi_parse_free(&parse);
01167 
01168    return mod;
01169 }

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4