Ejemplo n.º 1
0
static struct nvfx_reg
constant(struct nvfx_vpc *vpc, int pipe, float x, float y, float z, float w)
{
   struct nv30_vertprog *vp = vpc->vp;
   struct nv30_vertprog_data *vpd;
   int idx;

   if (pipe >= 0) {
      for (idx = 0; idx < vp->nr_consts; idx++) {
         if (vp->consts[idx].index == pipe)
            return nvfx_reg(NVFXSR_CONST, idx);
      }
   }

   idx = vp->nr_consts++;
   vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts);
   vpd = &vp->consts[idx];

   vpd->index = pipe;
   vpd->value[0] = x;
   vpd->value[1] = y;
   vpd->value[2] = z;
   vpd->value[3] = w;
   return nvfx_reg(NVFXSR_CONST, idx);
}
Ejemplo n.º 2
0
struct nvfx_reg CCompilerFP::temp()
{
	s32 idx = ffs(~m_rTemps) - 1;

	if(idx<0) return nvfx_reg(NVFXSR_TEMP,0);

	m_rTemps |= (1<<idx);
	m_rTempsDiscard |= (1<<idx);

	return nvfx_reg(NVFXSR_TEMP,idx);
}
Ejemplo n.º 3
0
struct nvfx_reg CCompiler::temp()
{
	s32 idx = ffs(~m_rTemps) - 1;

	if(idx<0) return nvfx_reg(NVFXSR_NONE,0);

	m_rTemps |= (1<<idx);
	m_rTempsDiscard |= (1<<idx);

	if((s32)m_nNumRegs<idx) m_nNumRegs = idx;

	return nvfx_reg(NVFXSR_TEMP,idx);
}
Ejemplo n.º 4
0
static struct nvfx_reg
temp(struct nvfx_vpc *vpc)
{
   int idx = ffs(~vpc->r_temps) - 1;

   if (idx < 0 || (!vpc->is_nv4x && idx >= 16)) {
      NOUVEAU_ERR("out of temps!!\n");
      return nvfx_reg(NVFXSR_TEMP, 0);
   }

   vpc->r_temps |= (1 << idx);
   vpc->r_temps_discard |= (1 << idx);
   return nvfx_reg(NVFXSR_TEMP, idx);
}
Ejemplo n.º 5
0
void CVPParser::ParseInstruction(struct nvfx_insn *insn,opcode *opc,const char *param_str)
{
	u32 i;
	char *token = SkipSpaces(strtok((char*)param_str,","));

	if(opc->is_imm)
		ParseMaskedDstAddr(token,insn);
	else
		ParseMaskedDstReg(token,insn);

	for(i=0;i<opc->nr_src;i++) {
		token = SkipSpaces(strtok(NULL,","));
		ParseSwizzledSrcReg(token,&insn->src[opc->src_slots[i]]);
	}

	if(opc->opcode == OPCODE_TEX) {
	  uint8_t unit = ~0, target = ~0;

	  token = SkipSpaces(strtok(NULL,","));
	  ParseTextureUnit(token,&unit);
	  
	  token = SkipSpaces(strtok(NULL,","));
	  ParseTextureTarget(token,&target);

	  insn->src[1] = nvfx_src(nvfx_reg(NVFXSR_VPTEXINPUT,unit));
	}
}
Ejemplo n.º 6
0
void CParser::InitInstruction(struct nvfx_insn *insn,u8 op)
{
	insn->op = op;
	insn->scale = 0;
	insn->unit = -1;
	insn->precision = FLOAT32;
	insn->mask = NVFX_VP_MASK_ALL;
	insn->cc_swz[0] = 0; insn->cc_swz[1] = 1; insn->cc_swz[2] = 2; insn->cc_swz[3] = 3;
	insn->sat = FALSE;
	insn->cc_update = FALSE;
	insn->cc_update_reg = 0;
	insn->cc_cond = NVFX_COND_TR;
	insn->cc_test = 0;
	insn->cc_test_reg = 0;
	insn->dst = nvfx_reg(NVFXSR_NONE,0);
	insn->src[0] = nvfx_src(nvfx_reg(NVFXSR_NONE,0)); insn->src[1] = nvfx_src(nvfx_reg(NVFXSR_NONE,0)); insn->src[2] = nvfx_src(nvfx_reg(NVFXSR_NONE,0));
}
Ejemplo n.º 7
0
struct nvfx_reg CCompiler::constant(s32 pipe, f32 x, f32 y, f32 z, f32 w)
{
	int idx;
	struct vertex_program_data *vpd;

	if(pipe>=0) {
		for(idx=0;idx<m_nConsts;idx++) {
			if(m_pConstData[idx].index==pipe) return nvfx_reg(NVFXSR_CONST,idx);
		}
	}

	idx = m_nConsts++;
	m_pConstData = (struct vertex_program_data*)realloc(m_pConstData,sizeof(struct vertex_program_data)*m_nConsts);

	vpd = &m_pConstData[idx];
	vpd->index = pipe;
	vpd->value[0] = x;
	vpd->value[1] = y;
	vpd->value[2] = z;
	vpd->value[3] = w;
	return nvfx_reg(NVFXSR_CONST,idx);
}
Ejemplo n.º 8
0
void CCompiler::Compile(CParser *pParser)
{
	struct nvfx_src tmp;
	struct nvfx_relocation reloc;
	std::vector<u32> insns_pos;
	std::list<struct nvfx_relocation> label_reloc;
	int i,nICount = pParser->GetInstructionCount();
	struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE,0));
	struct nvfx_insn tmp_insn,*insns = pParser->GetInstructions();

	Prepare(pParser);

	for(i=0;i<nICount;i++) {
                /* u32 idx = (u32)insns_pos.size(); */
		struct nvfx_insn *insn = &insns[i];

		insns_pos.push_back(m_nInstructions);
		switch(insn->op) {
			case OPCODE_NOP:
				tmp_insn = arith(0,none.reg,0,none,none,none);
				emit_insn(gen_op(NOP,VEC),&tmp_insn);
				break;
			case OPCODE_ABS:
				tmp_insn = arith_ctor(insn,insn->dst,abs(insn->src[0]),none,none);
				emit_insn(gen_op(MOV,VEC),&tmp_insn);
				break;
			case OPCODE_ADD:
				emit_insn(gen_op(ADD,VEC),insn);
				break;
			case OPCODE_ARA:
				break;
			case OPCODE_ARL:
				break;
			case OPCODE_ARR:
				break;
			case OPCODE_BRA:
				reloc.location = m_nInstructions;
				reloc.target = insn->dst.index;
				label_reloc.push_back(reloc);

				tmp_insn = arith(0,none.reg,0,none,none,none);
				emit_insn(gen_op(BRA,SCA),&tmp_insn);
				break;
			case OPCODE_CAL:
				reloc.location = m_nInstructions;
				reloc.target = insn->dst.index;
				label_reloc.push_back(reloc);

				tmp_insn = arith(0,none.reg,0,none,none,none);
				emit_insn(gen_op(CAL,SCA),&tmp_insn);
				break;
			case OPCODE_COS:
				emit_insn(gen_op(COS,SCA),insn);
				break;
			case OPCODE_DP3:
				emit_insn(gen_op(DP3,VEC),insn);
				break;
			case OPCODE_DP4:
				emit_insn(gen_op(DP4,VEC),insn);
				break;
			case OPCODE_DPH:
				emit_insn(gen_op(DPH,VEC),insn);
				break;
			case OPCODE_DST:
				emit_insn(gen_op(DST,VEC),insn);
				break;
			case OPCODE_EX2:
				emit_insn(gen_op(EX2,SCA),insn);
				break;
			case OPCODE_EXP:
				emit_insn(gen_op(EXP,SCA),insn);
				break;
			case OPCODE_FLR:
				emit_insn(gen_op(FLR,VEC),insn);
				break;
			case OPCODE_FRC:
				emit_insn(gen_op(FRC,VEC),insn);
				break;
			case OPCODE_LG2:
				emit_insn(gen_op(LG2,SCA),insn);
				break;
			case OPCODE_LIT:
				emit_insn(gen_op(LIT,SCA),insn);
				break;
			case OPCODE_LOG:
				emit_insn(gen_op(LOG,SCA),insn);
				break;
			case OPCODE_MAD:
				emit_insn(gen_op(MAD,VEC),insn);
				break;
			case OPCODE_MAX:
				emit_insn(gen_op(MAX,VEC),insn);
				break;
			case OPCODE_MIN:
				emit_insn(gen_op(MIN,VEC),insn);
				break;
			case OPCODE_MOV:
				emit_insn(gen_op(MOV,VEC),insn);
				break;
			case OPCODE_MUL:
				emit_insn(gen_op(MUL,VEC),insn);
				break;
			case OPCODE_POW:
				tmp = nvfx_src(temp());
				
				tmp_insn = arith(0, tmp.reg, NVFX_VP_MASK_X, none, none, insn->src[0]);
				emit_insn(gen_op(LG2,SCA),&tmp_insn);

				tmp_insn = arith(0, tmp.reg, NVFX_VP_MASK_X, swz(tmp, X, X, X, X), insn->src[1], none);
				emit_insn(gen_op(MUL,VEC),&tmp_insn);
				
				tmp_insn = arith_ctor(insn, insn->dst, none, none, swz(tmp, X, X, X, X));
				emit_insn(gen_op(EX2,SCA),&tmp_insn);
				break;
			case OPCODE_RCC:
				emit_insn(gen_op(RCC,SCA),insn);
				break;
			case OPCODE_RCP:
				emit_insn(gen_op(RCP,SCA),insn);
				break;
			case OPCODE_RSQ:
				emit_insn(gen_op(RSQ,SCA),insn);
				break;
			case OPCODE_SEQ:
				emit_insn(gen_op(SEQ,VEC),insn);
				break;
			case OPCODE_SFL:
				emit_insn(gen_op(SFL,VEC),insn);
				break;
			case OPCODE_SGE:
				emit_insn(gen_op(SGE,VEC),insn);
				break;
			case OPCODE_SGT:
				emit_insn(gen_op(SGT,VEC),insn);
				break;
			case OPCODE_SIN:
				emit_insn(gen_op(SIN,SCA),insn);
				break;
			case OPCODE_SLE:
				emit_insn(gen_op(SLE,VEC),insn);
				break;
			case OPCODE_SLT:
				emit_insn(gen_op(SLT,VEC),insn);
				break;
			case OPCODE_SNE:
				emit_insn(gen_op(SNE,VEC),insn);
				break;
			case OPCODE_SSG:
				emit_insn(gen_op(SSG,VEC),insn);
				break;
			case OPCODE_STR:
				emit_insn(gen_op(STR,VEC),insn);
				break;
			case OPCODE_SUB:
				tmp_insn = arith_ctor(insn,insn->dst,insn->src[0],none,neg(insn->src[2]));
				emit_insn(gen_op(ADD,VEC),&tmp_insn);
				break;
			case OPCODE_END:
				if(m_nInstructions) m_pInstructions[m_nCurInstruction].data[3] |= NVFX_VP_INST_LAST;
				else {
					tmp_insn = arith(0,none.reg,0,none,none,none);
					emit_insn(gen_op(NOP,VEC),&tmp_insn);
					m_pInstructions[m_nCurInstruction].data[3] |= NVFX_VP_INST_LAST;
				}
				break;
		}
		release_temps();
	}

	for(std::list<struct nvfx_relocation>::iterator it = label_reloc.begin();it!=label_reloc.end();it++) {
		struct nvfx_relocation hw_reloc;

		hw_reloc.location = it->location;
		hw_reloc.target = insns_pos[it->target];

		m_lBranchRelocation.push_back(hw_reloc);
	}
}
Ejemplo n.º 9
0
int CVPParser::Parse(const char *str)
{
    int i,iline = 0;
    bool inProgram = false;
    std::stringstream input(str);
    struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE,0));

    while(!input.eof()) {
        char line[256];
        opcode *opc = NULL;
        struct nvfx_insn *insn = NULL;

        input.getline(line,255);
        iline++;

        for(i=0; i<256; i++) {
            char c = line[i];

            if(c=='\n' || c=='\r' || c==';')
                c = 0;
            if(c=='\t')
                c = ' ';

            line[i] = c;
            if(c==0) break;
        }

        if(line[0]=='#') {
            ParseComment(line);
            continue;
        }

        if(!inProgram) {
            if(strncmp(line,"!!VP2.0",7)==0)
                inProgram = true;
            else if(strncmp(line,"!!ARBvp1.0",10)==0)
                inProgram = true;

            continue;
        }

        char *label = NULL;
        char *col_ptr = NULL;
        char *opcode = NULL;
        char *ptr = line;

        if((col_ptr = strstr((char*)ptr,":"))!=NULL) {
            int j = 0;
            bool valid = true;

            while((ptr+j)<col_ptr) {
                if(j==0 && !(isLetter(ptr[j]) || ptr[j]=='_')) valid = false;
                if(!(isLetter(ptr[j]) || isDigit(ptr[j]) || ptr[j]=='_')) valid = false;
                j++;
            }

            if(valid) {
                label = strtok(ptr,":\x20");
                ptr = col_ptr + 1;
            }
        }

        opcode = strtok(ptr," ");

        if(label) {
            jmpdst d;

            strcpy(d.ident,label);
            d.location = m_nInstructions;
            m_lIdent.push_back(d);
        }

        if(opcode) {
            char *param_str = SkipSpaces(strtok(NULL,"\0"));
            if(strcasecmp(opcode,"OPTION")==0) {
                if(strncasecmp(param_str,"NV_vertex_program3",18)==0)
                    m_nOption |= NV_OPTION_VP3;
                continue;
            } else if(strcasecmp(opcode,"PARAM")==0)
                continue;
            else if(strcasecmp(opcode,"TEMP")==0)
                continue;
            else {
                opc = FindOpcode(opcode);

                insn = &m_pInstructions[m_nInstructions];

                if(!opc) continue;

                InitInstruction(insn,opc->opcode);
                if(opc->opcode==OPCODE_END) {
                    m_nInstructions++;
                    break;
                }

                char *opc_ext = opcode + strlen(opc->mnemonic);
                if(m_nOption&(NV_OPTION_VP2|NV_OPTION_VP3)) {
                    if(opc_ext[0]=='C') {
                        insn->cc_update = TRUE;

                        if(m_nOption&NV_OPTION_VP3 && (opc_ext[1]=='0' || opc_ext[1]=='1')) {
                            switch(opc_ext[1]) {
                            case '0':
                                insn->cc_update_reg = 0;
                                break;
                            case '1':
                                insn->cc_update_reg = 1;
                                break;
                            }
                            opc_ext++;
                        }
                        opc_ext++;
                    }
                }
                if(opc_ext[0]=='_') {
                    if(strncasecmp(opc_ext,"_sat",4)==0) insn->sat = TRUE;
                }
                ParseInstruction(insn,opc,param_str);
                m_nInstructions++;
            }
        }
    }

    for(std::list<jmpdst>::iterator r=m_lJmpDst.begin(); r!=m_lJmpDst.end(); r++) {
        bool found = false;

        for(std::list<jmpdst>::iterator i=m_lIdent.begin(); i!=m_lIdent.end(); i++) {
            if(strcmp(r->ident,i->ident)==0) {
                found = true;
                m_pInstructions[r->location].dst = nvfx_reg(NVFXSR_RELOCATED,i->location);
                break;
            }
        }

        if(found==false) {
            fprintf(stderr,"Identifier \'%s\' not found.\n",r->ident);
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}
Ejemplo n.º 10
0
void CCompilerFP::Compile(CParser *pParser)
{
	int i,nCount = pParser->GetInstructionCount();
	struct nvfx_insn tmp_insn,*insns = pParser->GetInstructions();
	struct nvfx_src tmp,none = nvfx_src(nvfx_reg(NVFXSR_NONE,0));

	Prepare(pParser);

	for(i=0;i<nCount;i++) {
		struct nvfx_insn *insn = &insns[i];

		switch(insn->op) {
			case OPCODE_ADD:
				emit_insn(NVFX_FP_OP_OPCODE_ADD,insn);
				break;
			case OPCODE_BRK:
				emit_brk(insn);
				break;
			case OPCODE_COS:
				emit_insn(NVFX_FP_OP_OPCODE_COS,insn);
				break;
			case OPCODE_DP3:
				emit_insn(NVFX_FP_OP_OPCODE_DP3,insn);
				break;
			case OPCODE_DP4:
				emit_insn(NVFX_FP_OP_OPCODE_DP4,insn);
				break;
			case OPCODE_EX2:
				emit_insn(NVFX_FP_OP_OPCODE_EX2,insn);
				break;
			case OPCODE_LG2:
				emit_insn(NVFX_FP_OP_OPCODE_LG2,insn);
				break;
			case OPCODE_LRP:
				tmp = nvfx_src(temp());
				tmp_insn = arith(0,tmp.reg,insn->mask,neg(insn->src[0]),insn->src[2],insn->src[2]);
				emit_insn(NVFX_FP_OP_OPCODE_MAD,&tmp_insn);

				tmp_insn = arith(insn->sat,insn->dst,insn->mask,insn->src[0],insn->src[1],tmp);
				emit_insn(NVFX_FP_OP_OPCODE_MAD,&tmp_insn);
				break;
			case OPCODE_MAX:
				emit_insn(NVFX_FP_OP_OPCODE_MAX,insn);
				break;
			case OPCODE_MIN:
				emit_insn(NVFX_FP_OP_OPCODE_MIN,insn);
				break;
			case OPCODE_MAD:
				emit_insn(NVFX_FP_OP_OPCODE_MAD,insn);
				break;
			case OPCODE_MOV:
				emit_insn(NVFX_FP_OP_OPCODE_MOV,insn);
				break;
			case OPCODE_MUL:
				emit_insn(NVFX_FP_OP_OPCODE_MUL,insn);
				break;
			case OPCODE_POW:
				tmp = nvfx_src(temp());

				tmp_insn = arith(0,tmp.reg, NVFX_FP_MASK_X, insn->src[0], none, none);
				emit_insn(NVFX_FP_OP_OPCODE_LG2,&tmp_insn);

				tmp_insn = arith(0,tmp.reg, NVFX_FP_MASK_X, swz(tmp, X, X, X, X),insn->src[1], none);
				emit_insn(NVFX_FP_OP_OPCODE_MUL,&tmp_insn);

				tmp_insn = arith_ctor(insn,insn->dst,swz(tmp, X, X, X, X), none, none);
				emit_insn(NVFX_FP_OP_OPCODE_EX2,&tmp_insn);
				break;
			case OPCODE_RCP:
				emit_insn(NVFX_FP_OP_OPCODE_RCP,insn);
				break;
			case OPCODE_RSQ:
				tmp = nvfx_src(temp());
				tmp_insn = arith(0,tmp.reg,NVFX_FP_MASK_X,abs(insn->src[0]),none,none);
				tmp_insn.scale = NVFX_FP_OP_DST_SCALE_INV_2X;
				emit_insn(NVFX_FP_OP_OPCODE_LG2,&tmp_insn);

				tmp_insn = arith_ctor(insn,insn->dst,neg(swz(tmp,X,X,X,X)),none,none);
				emit_insn(NVFX_FP_OP_OPCODE_EX2,&tmp_insn);
				break;
			case OPCODE_SEQ:
				emit_insn(NVFX_FP_OP_OPCODE_SEQ,insn);
				break;
			case OPCODE_SFL:
				emit_insn(NVFX_FP_OP_OPCODE_SFL,insn);
				break;
			case OPCODE_SGE:
				emit_insn(NVFX_FP_OP_OPCODE_SGE,insn);
				break;
			case OPCODE_SGT:
				emit_insn(NVFX_FP_OP_OPCODE_SGT,insn);
				break;
			case OPCODE_SIN:
				emit_insn(NVFX_FP_OP_OPCODE_SIN,insn);
				break;
			case OPCODE_SLE:
				emit_insn(NVFX_FP_OP_OPCODE_SLE,insn);
				break;
			case OPCODE_SLT:
				emit_insn(NVFX_FP_OP_OPCODE_SLT,insn);
				break;
			case OPCODE_SNE:
				emit_insn(NVFX_FP_OP_OPCODE_SNE,insn);
				break;
			case OPCODE_TEX:
				emit_insn(NVFX_FP_OP_OPCODE_TEX,insn);
				break;
			case OPCODE_TXB:
				emit_insn(NVFX_FP_OP_OPCODE_TXB,insn);
				break;
			case OPCODE_TXL:
				emit_insn(NVFX_FP_OP_OPCODE_TXL_NV40,insn);
				break;
			case OPCODE_TXP:
				emit_insn(NVFX_FP_OP_OPCODE_TXP,insn);
				break;
			case OPCODE_BGNREP:
				emit_rep(insn);
				break;
			case OPCODE_ENDREP:
				fixup_rep();
				break;
			case OPCODE_END:
				if(m_nInstructions) m_pInstructions[m_nCurInstruction].data[0] |= NVFX_FP_OP_PROGRAM_END;
				else {
					m_nCurInstruction = m_nInstructions;
					grow_insns(1);
					m_pInstructions[m_nCurInstruction].data[0] = 0x00000001;
					m_pInstructions[m_nCurInstruction].data[1] = 0x00000000;
					m_pInstructions[m_nCurInstruction].data[2] = 0x00000000;
					m_pInstructions[m_nCurInstruction].data[3] = 0x00000000;
				}
		}
		release_temps();
	}
}