lab-04-Rushilwiz/lab04.c
2024-03-22 17:25:02 -04:00

141 lines
4.0 KiB
C

// PID: 730677144
// I pledge the COMP 211 honor code.
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "instructions.h"
#define REGISTER_SIZE 32
void execute_r_instruction(r_instruction* instruct);
void execute_i_instruction(i_instruction* instruct);
static uint16_t registers[REGISTER_SIZE] = {0};
int main() {
uint32_t instruct;
while (true) {
printf("Please enter your instruction as a 32-bit integer: ");
if (scanf("%u", &instruct) != 1) {
printf("\n");
fprintf(stderr, "Failed to read instruction!\n");
return EXIT_FAILURE;
}
if (instruct == UINT_MAX)
return EXIT_SUCCESS;
if (get_type_of_instruction(instruct) == R_TYPE) {
r_instruction* r_instruct = create_r_instruction(instruct);
execute_r_instruction(r_instruct);
free(r_instruct);
} else { // I_TYPE
i_instruction* i_instruct = create_i_instruction(instruct);
execute_i_instruction(i_instruct);
free(i_instruct);
}
printf("Current register status:\n");
printf("[");
for (int i = 0; i < REGISTER_SIZE; i++) {
printf("%d", registers[i]);
if (i != REGISTER_SIZE - 1)
printf(", ");
}
printf("]\n");
}
}
// ------------------------------------
// Takes the r_instruction
// you created in Part 1 and, based on the MIPS instruction,
// performs the operation and updates the 'registers' array
// (see top of file).
//
// Hint: the "func" bits determine the operation (i.e., SLL,
// SRA, ADD, SUB, AND, OR).
//
// Arguments: r_instruction structure
//
// Return: None
//
void execute_r_instruction(r_instruction* instruct) {
switch (instruct->func) {
case SLL_FUNC:
registers[instruct->rd] = registers[instruct->rt]
<< instruct->shamt;
break;
case SRA_FUNC:
registers[instruct->rd] =
registers[instruct->rt] >> instruct->shamt;
break;
case ADD_FUNC:
registers[instruct->rd] =
registers[instruct->rs] + registers[instruct->rt];
break;
case SUB_FUNC:
registers[instruct->rd] =
registers[instruct->rs] - registers[instruct->rt];
break;
case AND_FUNC:
registers[instruct->rd] =
registers[instruct->rs] & registers[instruct->rt];
break;
case OR_FUNC:
registers[instruct->rd] =
registers[instruct->rs] | registers[instruct->rt];
break;
case NOR_FUNC:
registers[instruct->rd] =
~(registers[instruct->rs] | registers[instruct->rt]);
break;
default:
fprintf(stderr, "Invalid function code!\n");
exit(EXIT_FAILURE);
}
} // end execute_r_instruction() function
// ------------------------------------
// Takes the i_instruction
// you created in Part 1 and, based on the MIPS instruction,
// performs the operation and updates the 'registers' array
// (see top of file).
//
// Hint: the "opcode" bits determine the operation (.e., ADDI,
// ANDI, ORI).
//
// Arguments: i_instruction structure
//
// Return: None
//
void execute_i_instruction(i_instruction* instruct) {
switch (instruct->opcode) {
case ADDI_OPCODE:
registers[instruct->rt] =
registers[instruct->rs] + instruct->immediate;
break;
case ANDI_OPCODE:
registers[instruct->rt] =
registers[instruct->rs] & instruct->immediate;
break;
case ORI_OPCODE:
registers[instruct->rt] =
registers[instruct->rs] | instruct->immediate;
break;
default:
fprintf(stderr, "Invalid opcode!\n");
exit(EXIT_FAILURE);
}
} // end execute_i_instruction() function