Register getRegister(const char *s) { int pos = findRegister(s); if (pos != -1) { return registers[pos].reg; } else { error(ET_EXPECTED_REGISTER); return R_R1; } }
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; }
//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; }
int isRegister (const char *s) { return (findRegister(s) != -1); }