예제 #1
0
파일: parser.c 프로젝트: melentyev/main
Register getRegister(const char *s)
{
    int pos = findRegister(s);
    if (pos != -1)
    {
        return registers[pos].reg;
    }
    else
    {
        error(ET_EXPECTED_REGISTER);
        return R_R1;
    }
}
예제 #2
0
파일: parser.c 프로젝트: melentyev/main
CommandArg parseCommandArg(int allowRecursive)
{
    CommandArg res;
    if (currentToken().type == TT_BRACKET_OPEN)
    {
        if (allowRecursive)
        {
            nextToken();
            CommandArg *inner = (CommandArg*)ALLOCATE(sizeof(CommandArg) );
            *inner = parseCommandArg(0);
            res.type = AT_ADDRESS;
            res.argv.addr = inner;
            if (currentToken().type != TT_BRACKET_CLOSE)
            {
                error(ET_EXPECTED_BRACKET_CLOSE);
            }
        }
        else
        {
            error(ET_UNEXPECTED_TOKEN);
        }
    }
    else if (currentToken().type == TT_NUMBER)
    {
        res.type = AT_CONST;
        res.argv._const = currentToken().value._int;
    }
    else if (currentToken().type == TT_WORD)
    {
        int reg;
        if ( (reg = findRegister(currentToken().value.str) ) != -1)
        {
            res.type = AT_REGISTER;
            res.argv.r = reg;
        }
        else
        {
            res.type = AT_LABEL;
            res.argv.label = currentToken().value.str;
        }
    }
    nextToken();
    return res;
}
예제 #3
0
//Translate the instruction to binary
char* mountBinary(char instruction[],int nRegisters,int nConstants,int nLabels, char type, char *opcode, char *function, int currentAddress)
{
    int i = 0, j = 0, nRegsAux = 0, nConstAux = 0, nLabAux = 0;
    static char binary[32];
    char param[10], name[10];
    int isRegister = 0, isLabel = 0, isConstant = 0;

    //Define the initial binary
    for(i = 0; i < 32; i++)
        binary[i] = '0';
    i = 0;

    //Push the opcode
    concatBinary(0, 6, binary, opcode);
    
    //Takes the instruction name
    while(instruction[i] != ' '){
    	name[i] = instruction[i];
		i++;	
	}
    name[i] = '\0';
    i = 0;
    
    //Formats the instruction
    instruction = strchr(instruction, ' ');
    instruction = ++instruction;

    while(instruction[i] != '\0'){
        //Push the current instruction parameter
        if(instruction[i] != ','){
            param[j] = instruction[i];
            j++;
        }

        //If the char is comma or it is the instruction final
        if(instruction[i] == ',' || i == strlen(instruction) - 1){
            param[j] = '\0';
            
            //If the parameter is a register
            if(nRegisters != nRegsAux){
                isRegister = 1;
                isLabel = 0;
                isConstant = 0;
                nRegsAux++;
            }
            //If the parameter is a constant
            else if(nConstants != nConstAux){
                isRegister = 0;
                isLabel = 0;
                isConstant = 1;
                nConstAux++;
            }
            //If the parameter is a label
            else if(nLabels != nLabAux){
                isRegister = 0;
                isLabel = 1;
                isConstant = 0;
                nLabAux++;
            }

            //Operation for register
            if(isRegister == 1){
            	
            	//To load and store
            	char copy[10];
            	
            	//Load and Store
            	if(nRegsAux == 2 && (strcmp(name, "lw") == 0 || strcmp(name, "lh") == 0 || strcmp(name, "lb") == 0 || strcmp(name, "sw") == 0 || strcmp(name, "sh") == 0 || strcmp(name, "sb") == 0) )
				{ 
					strcpy(copy, param);
					
            		strcpy(param, strchr(param, '$'));
            		param[strlen(param) - 1] = '\0';   
					isRegister = 0;
                	isLabel = 0;
                	isConstant = 1;
               	    nConstAux++;	
				}
            	
                //Find the register code
                strcpy(param, findRegister(param));
                //If is not exists
                if(strcmp(param, "NULL") == 0)
                    return "1";

                //Push on correct position
                if(type == 'R'){
	                if(nRegsAux == 1){
						if(strcmp(name, "ext") == 0 || strcmp(name, "ins") == 0)
							concatBinary(11, 5, binary, param);
						else if(strcmp(name, "div") == 0 || strcmp(name, "divu") == 0 || strcmp(name, "madd") == 0  || strcmp(name, "maddu") == 0 || strcmp(name, "msub") == 0 || strcmp(name, "msubu") == 0  || strcmp(name, "mult") == 0  || strcmp(name, "multu") == 0 || strcmp(name, "mthi") == 0 || strcmp(name, "mtlo") == 0 || strcmp(name, "jr") == 0)
							concatBinary(6, 5, binary, param);
						else
	                		concatBinary(16, 5, binary, param);
	            	}
	                else if(nRegsAux == 2){
	                	if(strcmp(name, "wsbh") == 0 || strcmp(name, "seh") == 0 || strcmp(name, "seb") == 0 || strcmp(name, "div") == 0 || strcmp(name, "divu") == 0 || strcmp(name, "madd") == 0  || strcmp(name, "maddu") == 0 || strcmp(name, "msub") == 0 || strcmp(name, "msubu") == 0 || strcmp(name, "mult") == 0  || strcmp(name, "multu") == 0 || strcmp(name, "sll") == 0 || strcmp(name, "srl") == 0   || strcmp(name, "sra") == 0   || strcmp(name, "rotr") == 0  || strcmp(name, "sllv") == 0 || strcmp(name, "srav") == 0 || strcmp(name, "srlv") == 0 || strcmp(name, "rotrv") == 0)
	                		concatBinary(11, 5, binary, param);
	                	else
	                		concatBinary(6, 5, binary, param);
					}
	                	
	                else if(nRegsAux == 3){
	                	if(strcmp(name, "sllv") == 0 || strcmp(name, "srav") == 0 || strcmp(name, "srlv") == 0 || strcmp(name, "rotrv") == 0)
							concatBinary(6, 5, binary, param);
						else
							concatBinary(11, 5, binary, param);
					}
	                 	
	        	}
	        	else if(type == 'I'){
	        		if(nRegsAux == 1){
	        			if(strcmp(name, "beq") == 0 || strcmp(name, "bne") == 0  || strcmp(name, "bgtz") == 0  || strcmp(name, "bltz") == 0)
	        				concatBinary(6, 5, binary, param);
	        			else
	        				concatBinary(11, 5, binary, param);
	        			
					}
	                else if(nRegsAux == 2){
	                	if(strcmp(name, "beq") == 0 || strcmp(name, "bne") == 0  || strcmp(name, "bgtz") == 0  || strcmp(name, "bltz") == 0)
	        				concatBinary(11, 5, binary, param);
	        			else
	        				concatBinary(6, 5, binary, param);
					}
	                	
				}
                
                //To load and store
                if(isConstant == 1){
                	strcpy(param, copy);
                	strcpy(param, strchr(strrev(param), '('));
					strcpy(param, strrev(strchr(param, param[1])));
					while(param[0] == ' ' || param[0] == '\t')
						strcpy(param, strchr(param, param[1]));	
				}

            }
            //Operation for label
            else if(isLabel == 1){

                //Find the label code
                strcpy(param, findLabel(param));
                				
                //If is not valid
                if(strcmp(param, "NULL") == 0)
                    return "2";
                
				//Branchs instructions   
                if(strcmp(name, "beq") == 0 || strcmp(name, "bgtz") == 0 || strcmp(name, "bne") == 0 || strcmp(name, "bltz") == 0)
				{ 		
						int labelAddress = 0, i = 0;
						for(i; i < 16; i++){
							if(param[i] == '1')
								labelAddress++;
							if(i != 15)
								labelAddress = labelAddress << 1;
						}
						itoa(labelAddress - currentAddress, param, 2);
						strcpy(param, completeBinary(16, param));
						
				}

                //Push on correct position
                concatBinary(16, 16, binary, param);
            }
            //Operation for constant
            if(isConstant == 1){
            	//Convert to integer
               int constValue = atoi(param);
               
                //Verify if is valid
               if(constValue == 0 && param[0] != '0')
                    return "3";
               
			   if(type != 'R'){
			   		
			   		//Unsigned instructions
			   		if(strcmp(name, "addiu") == 0 || strcmp(name, "sltiu") == 0)
					{ 
						if(constValue < 0)
							return "7";
						if(constValue > getBinaryRange(17, '+'))
							return "6";

					}
					//Signed
					else{
				   	   if(constValue > getBinaryRange(16, '+') || constValue < getBinaryRange(16, '-'))
				   	  	 return "6";
		        	}
		        	 //Converts to binary and push to instruction
		            char constant[16];
		            itoa(constValue, constant, 2);
		            strcpy(constant, completeBinary(16, constant));
		            concatBinary(16, 16, binary, constant);
	           }
	           else{
	           	
	           	   if(constValue > getBinaryRange(5, '+') || constValue < getBinaryRange(5, '-'))
			   	  	 	return "6";

	           	   //Shamt, ins and ext
	               char constant[5];
	               int pos, size;
	               
	               if(strcmp(name, "ext") == 0 && nConstAux == 2)
				   		constValue--;
	               itoa(constValue, constant, 2);
	               strcpy(constant, completeBinary(5, constant));
	               
	               if(strcmp(name, "ext") == 0 && nConstAux == 1)
	               		concatBinary(21, 5, binary, constant);
	               else if(strcmp(name, "ext") == 0 && nConstAux == 2)
	               		concatBinary(16, 5, binary, constant);
	               else	if(strcmp(name, "ins") == 0 && nConstAux == 1)
	               		pos = constValue;
	                else if(strcmp(name, "ins") == 0 && nConstAux == 2){
	               		size = constValue;
	                	int msb = (pos + size) - 1;	               			
	               		itoa(msb, constant, 2);
	               		strcpy(constant, completeBinary(5, constant));
	               		concatBinary(16, 5, binary, constant);
	               		
	               		itoa(pos, constant, 2);
	               		strcpy(constant, completeBinary(5, constant));
	               		concatBinary(21, 5, binary, constant);
					}
	               else
	               		concatBinary(21, 5, binary, constant);
				   
			   }
            }
            param[0] = '\0';
            j = 0;
        }
        i++;
    }

    //Minus arguments
    if(nConstants != nConstAux || nRegisters != nRegsAux || nLabels != nLabAux)
        return "5";

    //Place the shamt and function on binary
    if(type == 'R'){
        concatBinary(26, 6, binary, function);
		
		//seh, seb and wsbh instructions
		if(strcmp(opcode, "011111") == 0 && strcmp(function, "100000") == 0){
			if(strcmp(name, "seh") == 0) 
				concatBinary(21, 5, binary, "11000");
			else if(strcmp(name, "seb") == 0) 
				concatBinary(21, 5, binary, "10000");
			else if(strcmp(name, "wsbh") == 0) 
				concatBinary(21, 5, binary, "00010");	
		}
		
		if(strcmp(name, "rotr") == 0)
			concatBinary(6, 5, binary, "00001");
		else if(strcmp(name, "rotrv") == 0)
			concatBinary(21, 5, binary, "00001");
	}

    binary[32] = '\0';
    return binary;
}
예제 #4
0
파일: parser.c 프로젝트: melentyev/main
int isRegister (const char *s)
{
    return (findRegister(s) != -1);
}