#include #include #include #include #define MAX_PROGRAM_LENGTH 1000 #define MAX_LABELS 1000 #define MAX_SYMBOLS 1000 // Struct to hold instruction names and their corresponding opcodes and length of space separated instruction typedef struct { char instruction[7]; // instruction name (5 characters + null terminator) unsigned int opcode; // corresponding opcode unsigned int length; } RV32I_Instruction; // Struct for labels typedef struct { char name[50]; unsigned int address; } Label; // Struct for symbols typedef struct { char name[50]; unsigned int value; } Symbol; // Instructions defined RV32IM RV32I_Instruction instruction_set[] = { {"ADDI", 0x13, 3}, {"SLTI", 0x13, 3}, {"SLTIU", 0x13, 3}, {"XORI", 0x13, 3}, {"ORI", 0x13, 3}, {"ANDI", 0x13, 3}, {"LUI", 0x37, 2}, {"AUIPC", 0x17, 2}, {"LW", 0x03, 3}, {"LH", 0x03, 3}, {"LB", 0x03, 3}, {"LHU", 0x03, 3}, {"LBU", 0x03, 3}, {"SW", 0x23, 3}, {"SB", 0x23, 3}, {"SH", 0x23, 3}, {"ADD", 0x33, 3}, {"SUB", 0x33, 3}, {"SLL", 0x33, 3}, {"SLT", 0x33, 3}, {"MUL", 0x33, 3}, {"MULH", 0x33, 3}, {"MULHSU", 0x33, 3}, {"MULHU", 0x33, 3}, {"DIV", 0x33, 3}, {"DIVU", 0x33, 3}, {"REM", 0x33, 3}, {"REMU", 0x33, 3}, {"SLTU", 0x33, 3}, {"XOR", 0x33, 3}, {"SRL", 0x33, 3}, {"SRA", 0x33, 3}, {"SLLI", 0x13, 3}, {"SRLI", 0x13, 3}, {"SRAI", 0x13, 3}, {"OR", 0x33, 3}, {"AND", 0x33, 3}, {"BEQ", 0x63, 3}, {"BNE", 0x63, 3}, {"BLT", 0x63, 3}, {"BGE", 0x63, 3}, {"BLTU", 0x63, 3}, {"BGEU", 0x63, 3}, {"JAL", 0x6f, 2}, {"JALR", 0x67, 2}, {"FENCE", 0x0F, 2}, {"FENCE.I", 0x0F, 0}, {"ECALL", 0x73, 0}, {"EBREAK", 0x73, 0}, {"CSRRW", 0x73, 3}, {"CSRRS", 0x73, 3}, {"CSRRC", 0x73, 3}, {"CSRRWI", 0x73, 3}, {"CSRRSI", 0x73, 3}, {"CSRRCI", 0x73, 3}, {"WFI", 0x73, 0} }; Label labels[MAX_LABELS]; Symbol symbols[MAX_SYMBOLS]; int label_count = 0; int symbol_count = 0; unsigned int current_address = 0; int reghex(char* reg) { if ((strcmp(reg, "x0") == 0) || (strcmp(reg, "zero") == 0)) return 0x00; else if ((strcmp(reg, "x1") == 0) || (strcmp(reg, "ra") == 0)) return 0x01; else if ((strcmp(reg, "x2") == 0) || (strcmp(reg, "sp") == 0)) return 0x02; else if ((strcmp(reg, "x3") == 0) || (strcmp(reg, "gp") == 0)) return 0x03; else if ((strcmp(reg, "x4") == 0) || (strcmp(reg, "tp") == 0)) return 0x04; else if ((strcmp(reg, "x5") == 0) || (strcmp(reg, "t0") == 0)) return 0x05; else if ((strcmp(reg, "x6") == 0) || (strcmp(reg, "t1") == 0)) return 0x06; else if ((strcmp(reg, "x7") == 0) || (strcmp(reg, "t2") == 0)) return 0x07; else if ((strcmp(reg, "x8") == 0) || (strcmp(reg, "fp") == 0) || (strcmp(reg, "s0") == 0)) return 0x08; else if ((strcmp(reg, "x9") == 0) || (strcmp(reg, "s1") == 0)) return 0x09; else if ((strcmp(reg, "x10") == 0) || (strcmp(reg, "a0") == 0)) return 0x0A; else if ((strcmp(reg, "x11") == 0) || (strcmp(reg, "a1") == 0)) return 0x0B; else if ((strcmp(reg, "x12") == 0) || (strcmp(reg, "a2") == 0)) return 0x0C; else if ((strcmp(reg, "x13") == 0) || (strcmp(reg, "a3") == 0)) return 0x0D; else if ((strcmp(reg, "x14") == 0) || (strcmp(reg, "a4") == 0)) return 0x0E; else if ((strcmp(reg, "x15") == 0) || (strcmp(reg, "a5") == 0)) return 0x0F; else if ((strcmp(reg, "x16") == 0) || (strcmp(reg, "a6") == 0)) return 0x10; else if ((strcmp(reg, "x17") == 0) || (strcmp(reg, "a7") == 0)) return 0x11; else if ((strcmp(reg, "x18") == 0) || (strcmp(reg, "s2") == 0)) return 0x12; else if ((strcmp(reg, "x19") == 0) || (strcmp(reg, "s3") == 0)) return 0x13; else if ((strcmp(reg, "x20") == 0) || (strcmp(reg, "s4") == 0)) return 0x14; else if ((strcmp(reg, "x21") == 0) || (strcmp(reg, "s5") == 0)) return 0x15; else if ((strcmp(reg, "x22") == 0) || (strcmp(reg, "s6") == 0)) return 0x16; else if ((strcmp(reg, "x23") == 0) || (strcmp(reg, "s7") == 0)) return 0x17; else if ((strcmp(reg, "x24") == 0) || (strcmp(reg, "s8") == 0)) return 0x18; else if ((strcmp(reg, "x25") == 0) || (strcmp(reg, "s9") == 0)) return 0x19; else if ((strcmp(reg, "x26") == 0) || (strcmp(reg, "s10") == 0)) return 0x1A; else if ((strcmp(reg, "x27") == 0) || (strcmp(reg, "s11") == 0)) return 0x1B; else if ((strcmp(reg, "x28") == 0) || (strcmp(reg, "t3") == 0)) return 0x1C; else if ((strcmp(reg, "x29") == 0) || (strcmp(reg, "t4") == 0)) return 0x1D; else if ((strcmp(reg, "x30") == 0) || (strcmp(reg, "t5") == 0)) return 0x1E; else if ((strcmp(reg, "x31") == 0) || (strcmp(reg, "t6") == 0)) return 0x1F; else return 0x00; } unsigned int get_opcode(const char* instruction) { for (int i = 0; i < sizeof(instruction_set) / sizeof(instruction_set[0]); i++) { if (strcmp(instruction, instruction_set[i].instruction) == 0) { return instruction_set[i].opcode; } } return 0xFFFFFFFF; } int is_directive(const char* token) { return (token[0] == '.'); } int is_label(const char* token) { int len = strlen(token); return (len > 0 && token[len-1] == ':'); } int get_label_address(const char* label_name) { for (int i = 0; i < label_count; i++) { if (strcmp(labels[i].name, label_name) == 0) { return labels[i].address; } } return -1; } int get_symbol_value(const char* symbol_name) { for (int i = 0; i < symbol_count; i++) { if (strcmp(symbols[i].name, symbol_name) == 0) { return symbols[i].value; } } return -1; } int parse_immediate(const char* imm_str, int current_addr) { // Check if it's a hex number if (imm_str[0] == '0' && (imm_str[1] == 'x' || imm_str[1] == 'X')) { return (int)strtol(imm_str, NULL, 16); } // Check if it's a label/symbol else if ((imm_str[0] >= 'a' && imm_str[0] <= 'z') || (imm_str[0] >= 'A' && imm_str[0] <= 'Z') || imm_str[0] == '_') { int value = get_symbol_value(imm_str); if (value != -1) return value; value = get_label_address(imm_str); if (value != -1) return value - current_addr; // For PC-relative addressing printf("Error: Undefined symbol/label '%s'\n", imm_str); return 0; } // Decimal number else { return atoi(imm_str); } } void process_directive(char* directive, char* operands) { if (strcmp(directive, ".text") == 0) { current_address = 0x00000000; // Reset to text segment } else if (strcmp(directive, ".data") == 0) { current_address = 0x10000000; // Data segment start } else if (strcmp(directive, ".word") == 0) { char* token = strtok(operands, ","); while (token != NULL) { // Remove whitespace while (*token == ' ' || *token == '\t') token++; int value = parse_immediate(token, current_address); // Store the word (implementation depends on your memory model) printf(".word %d at address 0x%08X\n", value, current_address); current_address += 4; token = strtok(NULL, ","); } } else if (strcmp(directive, ".half") == 0) { char* token = strtok(operands, ","); while (token != NULL) { while (*token == ' ' || *token == '\t') token++; int value = parse_immediate(token, current_address); printf(".half %d at address 0x%08X\n", value, current_address); current_address += 2; token = strtok(NULL, ","); } } else if (strcmp(directive, ".byte") == 0) { char* token = strtok(operands, ","); while (token != NULL) { while (*token == ' ' || *token == '\t') token++; int value = parse_immediate(token, current_address); printf(".byte %d at address 0x%08X\n", value, current_address); current_address += 1; token = strtok(NULL, ","); } } else if (strcmp(directive, ".asciiz") == 0) { // Remove quotes char* start = strchr(operands, '"'); if (start) { start++; char* end = strchr(start, '"'); if (end) { *end = '\0'; int len = strlen(start); printf(".asciiz \"%s\" at address 0x%08X\n", start, current_address); current_address += len + 1; // +1 for null terminator } } } else if (strcmp(directive, ".space") == 0) { int size = parse_immediate(operands, current_address); printf(".space %d bytes at address 0x%08X\n", size, current_address); current_address += size; } else if (strcmp(directive, ".align") == 0) { int alignment = parse_immediate(operands, current_address); if (alignment > 0) { unsigned int mask = alignment - 1; if (current_address & mask) { current_address = (current_address + alignment) & ~mask; } } } else if (strcmp(directive, ".set") == 0) { char* symbol = strtok(operands, ","); char* value_str = strtok(NULL, ","); if (symbol && value_str) { while (*symbol == ' ' || *symbol == '\t') symbol++; while (*value_str == ' ' || *value_str == '\t') value_str++; int value = parse_immediate(value_str, current_address); // Add to symbols table if (symbol_count < MAX_SYMBOLS) { strcpy(symbols[symbol_count].name, symbol); symbols[symbol_count].value = value; symbol_count++; printf("Set symbol %s = %d (0x%X)\n", symbol, value, value); } } } else if (strcmp(directive, ".equ") == 0) { char* symbol = strtok(operands, ","); char* value_str = strtok(NULL, ","); if (symbol && value_str) { while (*symbol == ' ' || *symbol == '\t') symbol++; while (*value_str == ' ' || *value_str == '\t') value_str++; int value = parse_immediate(value_str, current_address); if (symbol_count < MAX_SYMBOLS) { strcpy(symbols[symbol_count].name, symbol); symbols[symbol_count].value = value; symbol_count++; printf("Equate symbol %s = %d (0x%X)\n", symbol, value, value); } } } else { printf("Warning: Unknown directive '%s'\n", directive); } } void clean_token(char* dest, const char* src) { int j = 0; for (int i = 0; src[i] != '\0' && j < 7; i++) { if ((src[i] >= '0' && src[i] <= '9') || (src[i] >= 'a' && src[i] <= 'z') || (src[i] >= 'A' && src[i] <= 'Z') || src[i] == '.' || src[i] == '_' || src[i] == '-') { dest[j++] = src[i]; } } dest[j] = '\0'; } // First pass: collect labels and symbols void first_pass(FILE* file) { char line[MAX_PROGRAM_LENGTH]; current_address = 0; rewind(file); while (fgets(line, sizeof(line), file)) { // Remove comments char* comment = strchr(line, '#'); if (comment) *comment = '\0'; // Skip empty lines int empty = 1; for (int i = 0; line[i] != '\0'; i++) { if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n' && line[i] != '\r') { empty = 0; break; } } if (empty) continue; // Check for label char* label_end = strchr(line, ':'); if (label_end) { char label_name[50]; int i = 0; while (line[i] != ':' && line[i] != ' ' && line[i] != '\t' && i < 49) { label_name[i] = line[i]; i++; } label_name[i] = '\0'; if (label_count < MAX_LABELS) { strcpy(labels[label_count].name, label_name); labels[label_count].address = current_address; label_count++; printf("Label '%s' at address 0x%08X\n", label_name, current_address); } } // Check for directive char temp[4][8]; for (int i = 0; i < 4; i++) memset(temp[i], 0, 8); char line_copy[MAX_PROGRAM_LENGTH]; strcpy(line_copy, line); char* token = strtok(line_copy, " ,\t\n"); int i = 0; while (token != NULL && i < 4) { clean_token(temp[i], token); token = strtok(NULL, " ,\t\n"); i++; } if (i > 0 && is_directive(temp[0])) { // Process directive but don't advance address for data directives in first pass if (strcmp(temp[0], ".text") == 0) { current_address = 0x00000000; } else if (strcmp(temp[0], ".data") == 0) { current_address = 0x10000000; } } else if (i > 0 && !is_label(temp[0]) && get_opcode(temp[0]) != 0xFFFFFFFF) { // Regular instruction current_address += 4; } } } int write_bin(uint32_t *instr, int num_instr) { FILE *file = fopen("final", "wb"); if (file == NULL) { perror("Error opening file"); return 1; } fwrite(instr, sizeof(uint32_t), num_instr, file); fclose(file); printf("Successfully wrote %d instructions (4 bytes each) to the file 'final'.\n", num_instr); return 0; } int ihex(char foo[8]) { if (foo[0] == '0' && foo[1]=='x') { return (int)strtol(foo, NULL, 16); } else { return atoi(foo); } } int main() { FILE *file = fopen("/home/anonymous/dcc/boot_sd.S", "r"); char line[MAX_PROGRAM_LENGTH]; int num_instr = 0; uint32_t instruction[MAX_PROGRAM_LENGTH]; if (file == NULL) { perror("Error opening file"); return 1; } // First pass: collect labels printf("First pass: collecting labels...\n"); first_pass(file); // Second pass: actual assembly printf("\nSecond pass: assembling...\n"); rewind(file); current_address = 0; while (fgets(line, sizeof(line), file)) { // Remove comments and clean the line char* comment = strchr(line, '#'); if (comment) *comment = '\0'; int len = strlen(line); int empty = 1; for (int i = 0; i < len; i++) { if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n' && line[i] != '\r') { empty = 0; break; } } if (empty) continue; char temp[4][8]; char temp2[4][8]; for (int i = 0; i < 4; i++) { memset(temp[i], 0, 8); memset(temp2[i], 0, 8); } // Tokenize the line char line_copy[MAX_PROGRAM_LENGTH]; strcpy(line_copy, line); char* token = strtok(line_copy, " ,\t\n"); int i = 0; while (token != NULL && i < 4) { strncpy(temp[i], token, 7); token = strtok(NULL, " ,\t\n"); i++; } // Clean tokens for (int i = 0; i < 4; i++) { clean_token(temp2[i], temp[i]); } // Skip if it's just a label if (i == 1 && is_label(temp2[0])) { continue; } // Handle directives if (i > 0 && is_directive(temp2[0])) { // Combine remaining tokens as operands char operands[100] = ""; for (int j = 1; j < i; j++) { strcat(operands, temp2[j]); if (j < i-1) strcat(operands, " "); } process_directive(temp2[0], operands); continue; } // Skip label if present at beginning int start_index = 0; if (i > 0 && is_label(temp2[0])) { start_index = 1; // Shift tokens left for (int j = 0; j < 3; j++) { strcpy(temp2[j], temp2[j+1]); } strcpy(temp2[3], ""); i--; } if (i == 0) continue; // No instruction after label unsigned int opcode = get_opcode(temp2[0]); if (opcode == 0xFFFFFFFF) { printf("Unknown instruction: %s\n", temp2[0]); continue; } // Parse immediates that might be labels/symbols for (int j = 1; j < i; j++) { if (temp2[j][0] != '\0' && !(temp2[j][0] >= '0' && temp2[j][0] <= '9') && temp2[j][0] != 'x' && temp2[j][0] != '-') { int value = parse_immediate(temp2[j], current_address); if (value != -1) { // Convert the value back to string for processing snprintf(temp2[j], 8, "%d", value); } } } // Your existing instruction encoding logic here (same as before) // [Keep all your existing instruction encoding code from the original file] // This part remains exactly the same as your original code if (opcode==0x03) { if (strcmp(temp2[0], "LB")==0) { instruction[num_instr] = (ihex(temp2[3])<<20) + (reghex(temp2[2])<<15) + (reghex(temp2[1])<<7) + opcode; num_instr++; } else if (strcmp(temp2[0], "LH")==0) { instruction[num_instr] = (ihex(temp2[3])<<20) + (((reghex(temp2[2])<<3)+1)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "LW")==0) { instruction[num_instr] = (ihex(temp2[3])<<20) + (((reghex(temp2[2])<<3)+2)<<12) + (reghex(temp2[1])<<7) + opcode; num_instr++; } else if (strcmp(temp2[0], "LBU")==0) { instruction[num_instr] = (ihex(temp2[3])<<20) + (((reghex(temp2[2])<<3)+4)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "LHU")==0) { instruction[num_instr] = (ihex(temp2[3])<<20) + (((reghex(temp2[2])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } } else if (opcode==0x0f) { if (strcmp(temp2[0], "FENCE")==0) { instruction[num_instr] = (reghex(temp2[1])<<25)+ (reghex(temp2[2])<<20) + opcode; num_instr++; } else if (strcmp(temp2[0], "FENCE.I")==0) { instruction[num_instr] = 0x0000100F; num_instr++; } } else if (opcode==0x13) { if (strcmp(temp2[0], "ADDI")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (reghex(temp2[2])<<15) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SLTI")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+2)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SLTIU")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+3)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "XORI")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+4)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "ORI")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+6)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "ANDI")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+7)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SLLI")==0) { if(atoi(temp2[3])>=32) { printf("Illegal instruction for SLLI. Shamt or offset should be less than 32. "); } else { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+1)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } } else if (strcmp(temp2[0], "SRLI")==0) { if(atoi(temp2[3])>=32) { printf("Illegal instruction for SLLI. Shamt or offset should be less than 32. "); } else { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } } else if (strcmp(temp2[0], "SRAI")==0) { if(atoi(temp2[3])>=32) { printf("Illegal instruction for SLLI. Shamt or offset should be less than 32. "); } else { instruction[num_instr] = (1<<30)+(atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } } } else if (opcode==0x17) { instruction[num_instr] = (atoi(temp2[2])<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (opcode==0x23) { int split = (reghex(temp2[3]) >> 5)<<5; int lower = reghex(temp2[3]) - split; if (strcmp(temp2[0], "SB")==0) { //Split imm into 5 bits + 7 bits instruction[num_instr] = (split<< 20) + (atoi(temp2[1])<<20) + (reghex(temp2[2])<<15) + (lower << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SH")==0) { instruction[num_instr] = (split<< 20) + (atoi(temp2[1])<<20) + (((reghex(temp2[2])<<3)+1)<<12) + (lower << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SW")==0) { instruction[num_instr] = (split<< 20) + (atoi(temp2[1])<<20) + (((reghex(temp2[2])<<3)+2)<<12) + (lower << 7) + opcode; num_instr++; } } else if (opcode==0x33) { if (strcmp(temp2[0], "ADD")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (reghex(temp2[2])<<15) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SUB")==0) { instruction[num_instr] = (1<<30) + (atoi(temp2[3])<<20) + (reghex(temp2[2])<<15) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SLL")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+1)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SLT")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+2)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SLTU")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+3)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "XOR")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+4)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SRL")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "SRA")==0) { instruction[num_instr] = (1<<30) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "OR")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+6)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "AND")==0) { instruction[num_instr] = (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+7)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "MUL")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (reghex(temp2[2])<<15) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "MULH")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+1)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "MULHSU")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+2)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "MULHU")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+3)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "DIV")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+4)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "DIVU")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "REM")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+6)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "REMU")==0) { instruction[num_instr] = (1<<25) + (atoi(temp2[3])<<20) + (((reghex(temp2[2])<<3)+7)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } } else if (opcode==0x37) { instruction[num_instr] = (atoi(temp2[2])<<12) + (reghex(temp2[1])<< 7) + opcode; num_instr++; } else if (opcode==0x63) { long left=0, right=0; left = (atoi(temp2[2])>>12); right = (atoi(temp2[2])>>11) - (left<<1); left = (left<<6) + (atoi(temp2[2])>>5) -(right<<6)-(left<<7); //left ready [12][10:5] right = ((atoi(temp2[2])>>1) - ((atoi(temp2[2])>>5)<<4))<<1 + right; //right ready [4:1][11] if (strcmp(temp2[0], "BEQ")==0) { instruction[num_instr] = (left<<25) + (atoi(temp2[2])<<20) + (reghex(temp2[1])<<15) + (right<<7) + opcode; num_instr++; } else if (strcmp(temp2[0], "BNE")==0) { instruction[num_instr] = (left<<25) + (atoi(temp2[2])<<20) + (((reghex(temp2[1])<<3)+1)<<12) + (right<<7) + opcode; num_instr++; } else if (strcmp(temp2[0], "BLT")==0) { instruction[num_instr] = (left<<25) + (atoi(temp2[2])<<20) + (((reghex(temp2[1])<<3)+4)<<12) + (right<<7) + opcode; num_instr++; } else if (strcmp(temp2[0], "BGE")==0) { instruction[num_instr] = (left<<25) + (atoi(temp2[2])<<20) + (((reghex(temp2[1])<<3)+5)<<12) + (right<<7) + opcode; num_instr++; } else if (strcmp(temp2[0], "BLTU")==0) { instruction[num_instr] = (left<<25) + (atoi(temp2[2])<<20) + (((reghex(temp2[1])<<3)+6)<<12) + (right<<7) + opcode; num_instr++; }else if (strcmp(temp2[0], "BGEU")==0) { instruction[num_instr] = (left<<25) + (atoi(temp2[2])<<20) + (((reghex(temp2[1])<<3)+7)<<12) + (right<<7) + opcode; num_instr++; } } else if (opcode==0x67) { instruction[num_instr] = (atoi(temp2[3])<<20) + (reghex(temp2[2])<<15) + (reghex(temp2[1])<<7) + opcode; num_instr++; } else if (opcode==0x6f) { instruction[num_instr] = (atoi(temp2[2])<<12) + (reghex(temp2[1])<<7) + opcode; num_instr++; } else if (opcode==0x73) { if (strcmp(temp2[0], "ECALL")==0) { instruction[num_instr] = 0x00000073; num_instr++; } else if (strcmp(temp2[0], "EBREAK")==0) { instruction[num_instr] = 0x00100073; num_instr++; } else if (strcmp(temp2[0], "CSRRW")==0) { instruction[num_instr] = (atoi(temp2[2])<<20) + (((reghex(temp2[3])<<3)+1)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "CSRRS")==0) { instruction[num_instr] = (atoi(temp2[2])<<20) + (((reghex(temp2[3])<<3)+2)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "CSRRC")==0) { instruction[num_instr] = (atoi(temp2[2])<<20) + (((reghex(temp2[3])<<3)+3)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "CSRRWI")==0) { instruction[num_instr] = (atoi(temp2[2])<<20) + (((reghex(temp2[3])<<3)+5)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "CSRRSI")==0) { instruction[num_instr] = (atoi(temp2[2])<<20) + (((reghex(temp2[3])<<3)+6)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } else if (strcmp(temp2[0], "CSRRCI")==0) { instruction[num_instr] = (atoi(temp2[2])<<20) + (((reghex(temp2[3])<<3)+7)<<12) + (reghex(temp2[1]) << 7) + opcode; num_instr++; } } current_address += 4; } write_bin(instruction, num_instr); fclose(file); return 0; }