Esempio n. 1
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;
}
Esempio n. 2
0
    //TODO: need to rework
    //Parse whole line first
    //Get number of arguments
    //Get base op code
    //Get first argument register offset if exists
    //Get second argument register offset if exists
    //Calculate op_code
    //Get first value argument if exists (i.e. RAM address)
    //Get second value argument if exists (i.e. register or value)
    void AssemblyParser::Parse(const ASSEMBLY &assembly, Model::Memory &memory, PROGRAM_ASSEMBLY_MAP &program_map)
    {
        ADDRESS byte_address = memory.GetTopAddress();
        std::map<std::string, ADDRESS> tag_map;
        unsigned int line_number = 0;
        bool found_begin = false;
        bool found_end = false;

        for (auto line : assembly) 
        {
            line_number++;

            if (line == PROGRAM_BEGIN && !found_begin)
            {
                found_begin = true;
                memory.SetValue(byte_address++, Model::OpCode::GetOpCode(OP_BEGIN, 0));
            }
            else if (line == PROGRAM_END && !found_end)
            {
                found_end = true;
                memory.SetValue(byte_address++, Model::OpCode::GetOpCode(OP_END, 0));
            }
            else if (found_begin && !line.empty())
            {
                std::istringstream strstream(line);
                std::string token;
                std::getline(strstream, token, ' ');

                //TODO: tags are any strings (a-z, A-Z, ending with :)
                //Tags must be defined before use

                //TODO: subroutines are blocks beginning with a tag and ending with ROUTINE_RET

                if (token.substr(0,1) == COMMENT_BEGIN)
                {
                    continue;
                }
                else if (token.back() == TAG_END)
                {
                    tag_map[token.substr(0,token.length() - 1)] = byte_address;
                    memory.SetValue(byte_address++, OP_NOP);
                }
                else
                {
                    program_map[line_number] = byte_address;

                    auto base_op_code = ParseInstruction(token);


                    auto num_arguments = Model::OpCode::GetNumArguments(base_op_code);

                    if (num_arguments >= 1)
                    {
                        std::getline(strstream, token, ' ');
                        int register_index = 0;
                        auto op_code = Model::OpCode::GetOpCode(base_op_code, register_index);

                        //TODO: get rid of comma
                        if (base_op_code == OP_JMP)
                        {
                            if (tag_map.find(token) != tag_map.end())
                            {
                                memory.SetValue(byte_address++, op_code);
                                memory.SetValue(byte_address++, tag_map[token]);
                            }
                        }
                        else
                        {
                            register_index = ParseRegister(token);
                            op_code = Model::OpCode::GetOpCode(base_op_code, register_index);
                            memory.SetValue(byte_address++, op_code);
                        }

                        if (num_arguments >= 2)
                        {
                            std::getline(strstream, token, ' ');
                            auto value = ParseRegValue(token);
                            memory.SetValue(byte_address++, value);
                        }

                        //TODO: what if more arguments? i.e. what about inline comments
                    }
                    else
                    {
                        memory.SetValue(byte_address++, base_op_code);
                    }
                }
            }
        }
    }
Esempio n. 3
0
/**
 * Disassembles one instruction; only fully disassembly an instruction if it matches the filter criteria
 *
 * @returns VBox error code
 * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
 *                          set correctly.
 * @param   pu8Instruction  Pointer to the structure to disassemble.
 * @param   u32EipOffset    Offset to add to instruction address to get the real virtual address
 * @param   pcbSize         Where to store the size of the instruction.
 *                          NULL is allowed.
 * @param   pszOutput       Storage for disassembled instruction
 * @param   uFilter         Instruction type filter
 *
 * @todo    Define output callback.
 */
DISDECL(int) DISInstrEx(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, unsigned u32EipOffset, unsigned *pcbSize,
                        char *pszOutput, unsigned uFilter)
{
    unsigned i = 0, prefixbytes;
    unsigned idx, inc;
    const OPCODE *paOneByteMap;
#ifdef __L4ENV__
    jmp_buf jumpbuffer;
#endif

    //reset instruction settings
    pCpu->prefix        = PREFIX_NONE;
    pCpu->enmPrefixSeg  = DIS_SELREG_DS;
    pCpu->ModRM.u       = 0;
    pCpu->SIB.u         = 0;
    pCpu->lastprefix    = 0;
    pCpu->param1.parval = 0;
    pCpu->param2.parval = 0;
    pCpu->param3.parval = 0;
    pCpu->param1.szParam[0] = 0;
    pCpu->param2.szParam[0] = 0;
    pCpu->param3.szParam[0] = 0;
    pCpu->param1.size   = 0;
    pCpu->param2.size   = 0;
    pCpu->param3.size   = 0;
    pCpu->param1.flags  = 0;
    pCpu->param2.flags  = 0;
    pCpu->param3.flags  = 0;
    pCpu->uFilter       = uFilter;
    pCpu->pfnDisasmFnTable = pfnFullDisasm;

    if (pszOutput)
        *pszOutput = '\0';

    if (pCpu->mode == CPUMODE_64BIT)
    {
        paOneByteMap     = g_aOneByteMapX64;
        pCpu->addrmode   = CPUMODE_64BIT;
        pCpu->opmode     = CPUMODE_32BIT;
    }
    else
    {
        paOneByteMap     = g_aOneByteMapX86;
        pCpu->addrmode   = pCpu->mode;
        pCpu->opmode     = pCpu->mode;
    }

    prefixbytes = 0;
#ifndef __L4ENV__  /* Unfortunately, we have no exception handling in l4env */
    try
#else
    pCpu->pJumpBuffer = &jumpbuffer;
    if (setjmp(jumpbuffer) == 0)
#endif
    {
        while(1)
        {
            uint8_t codebyte = DISReadByte(pCpu, pu8Instruction+i);
            uint8_t opcode   = paOneByteMap[codebyte].opcode;

            /* Hardcoded assumption about OP_* values!! */
            if (opcode <= OP_LAST_PREFIX)
            {
                /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
                if (opcode != OP_REX)
                {
                    pCpu->lastprefix = opcode;
                    pCpu->prefix &= ~PREFIX_REX;
                }

                switch(opcode)
                {
                case OP_INVALID:
#if 0 //defined (DEBUG_Sander)
                    AssertMsgFailed(("Invalid opcode!!\n"));
#endif
                    return VERR_DIS_INVALID_OPCODE;

                // segment override prefix byte
                case OP_SEG:
                    pCpu->enmPrefixSeg = (DIS_SELREG)(paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START);
                    /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
                    if (   pCpu->mode != CPUMODE_64BIT
                        || pCpu->enmPrefixSeg >= DIS_SELREG_FS)
                    {
                        pCpu->prefix    |= PREFIX_SEG;
                    }
                    i += sizeof(uint8_t);
                    prefixbytes++;
                    continue;   //fetch the next byte

                // lock prefix byte
                case OP_LOCK:
                    pCpu->prefix |= PREFIX_LOCK;
                    i += sizeof(uint8_t);
                    prefixbytes++;
                    continue;   //fetch the next byte

                // address size override prefix byte
                case OP_ADDRSIZE:
                    pCpu->prefix |= PREFIX_ADDRSIZE;
                    if (pCpu->mode == CPUMODE_16BIT)
                        pCpu->addrmode = CPUMODE_32BIT;
                    else
                    if (pCpu->mode == CPUMODE_32BIT)
                        pCpu->addrmode = CPUMODE_16BIT;
                    else
                        pCpu->addrmode = CPUMODE_32BIT;     /* 64 bits */

                    i += sizeof(uint8_t);
                    prefixbytes++;
                    continue;   //fetch the next byte

                // operand size override prefix byte
                case OP_OPSIZE:
                    pCpu->prefix |= PREFIX_OPSIZE;
                    if (pCpu->mode == CPUMODE_16BIT)
                        pCpu->opmode = CPUMODE_32BIT;
                    else
                        pCpu->opmode = CPUMODE_16BIT;  /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */

                    i += sizeof(uint8_t);
                    prefixbytes++;
                    continue;   //fetch the next byte

                // rep and repne are not really prefixes, but we'll treat them as such
                case OP_REPE:
                    pCpu->prefix |= PREFIX_REP;
                    i += sizeof(uint8_t);
                    prefixbytes += sizeof(uint8_t);
                    continue;   //fetch the next byte

                case OP_REPNE:
                    pCpu->prefix |= PREFIX_REPNE;
                    i += sizeof(uint8_t);
                    prefixbytes += sizeof(uint8_t);
                    continue;   //fetch the next byte

                case OP_REX:
                    Assert(pCpu->mode == CPUMODE_64BIT);
                    /* REX prefix byte */
                    pCpu->prefix    |= PREFIX_REX;
                    pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
                    i += sizeof(uint8_t);
                    prefixbytes += sizeof(uint8_t);

                    if (pCpu->prefix_rex & PREFIX_REX_FLAGS_W)
                        pCpu->opmode = CPUMODE_64BIT;  /* overrides size prefix byte */
                    continue;   //fetch the next byte
                }
            }

            idx = i;
            i += sizeof(uint8_t); //first opcode byte

            pCpu->opcode = codebyte;
            /* Prefix byte(s) is/are part of the instruction. */
            pCpu->opaddr = pu8Instruction + idx + u32EipOffset - prefixbytes;

            inc = ParseInstruction(pu8Instruction + i, &paOneByteMap[pCpu->opcode], pCpu);

            pCpu->opsize = prefixbytes + inc + sizeof(uint8_t);

            if(pszOutput) {
                disasmSprintf(pszOutput, pu8Instruction+i-1-prefixbytes, pCpu, &pCpu->param1, &pCpu->param2, &pCpu->param3);
            }

            i += inc;
            prefixbytes = 0;
            break;
        }
    }
#ifndef __L4ENV__
    catch(...)
#else
    else  /* setjmp has returned a non-zero value: an exception occurred */
#endif
    {
        if (pcbSize)
            *pcbSize = 0;
        return VERR_DIS_GEN_FAILURE;
    }

    if (pcbSize)
        *pcbSize = i;

    if (pCpu->prefix & PREFIX_LOCK)
        disValidateLockSequence(pCpu);

    return VINF_SUCCESS;
}
Esempio n. 4
0
bool Player::UpdateInstruction()
{
	m_CurrentInstruction.ReadFromConsole("Which direction to go in?");

	return ParseInstruction();
}
Esempio n. 5
0
int CFPParser::Parse(const char *str)
{
	int i,iline = 0;
	bool inProgram = false;
	std::stringstream input(str);

	while(!input.eof()) {
		char line[256];
		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,"!!FP2.0",7)==0)
				inProgram = true;
			else if(strncmp(line,"!!ARBfp1.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(opcode) {
			char *param_str = SkipSpaces(strtok(NULL,"\0"));
			if(strcasecmp(opcode,"OPTION")==0) {
				if(strncasecmp(param_str,"NV_fragment_program2",20)==0)
					m_nOption |= NV_OPTION_FP2;
				continue;
			} else if(strcasecmp(opcode,"PARAM")==0)
				continue;
			else if(strcasecmp(opcode,"TEMP")==0)
				continue;
			else if(strcasecmp(opcode,"OUTPUT")==0) {
				ParseOutput(param_str);
				continue;
			} else {
				struct _opcode opc = FindOpcode(opcode);
				insn = &m_pInstructions[m_nInstructions];

				if(opc.opcode>=MAX_OPCODE) continue;

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

				ParseInstruction(insn,&opc,param_str);
				m_nInstructions++;
			}
		}
	}
	return 0;
}