CS计算机代考程序代写 computer architecture mips /***************************************************************/

/***************************************************************/
/* */
/* MIPS Instruction Level Simulator */
/* */
/* CMSC-22200 Computer Architecture */
/* University of Chicago */
/* */
/***************************************************************/

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/* DO NOT MODIFY THIS FILE! */
/* You should only change sim.c! */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

#include
#include
#include
#include
#include
#include “shell.h”

/***************************************************************/
/* Main memory. */
/***************************************************************/

#define MEM_DATA_START 0x10000000
#define MEM_DATA_SIZE 0x00100000
#define MEM_TEXT_START 0x00400000
#define MEM_TEXT_SIZE 0x00100000
#define MEM_STACK_START 0xffffffff
#define MEM_STACK_SIZE 0x00100000

typedef struct {
uint32_t start, size; //change from 64 bit to 32 bit
uint8_t *mem;
} mem_region_t;

/* memory will be dynamically allocated at initialization */
mem_region_t MEM_REGIONS[] = {
{ MEM_TEXT_START, MEM_TEXT_SIZE, NULL },
{ MEM_DATA_START, MEM_DATA_SIZE, NULL },
{ MEM_STACK_START, MEM_STACK_SIZE, NULL },
};

#define MEM_NREGIONS (sizeof(MEM_REGIONS)/sizeof(mem_region_t))

/***************************************************************/
/* CPU State info. */
/***************************************************************/

CPU_State CURRENT_STATE, NEXT_STATE;
int RUN_BIT; /* run bit */
int INSTRUCTION_COUNT;

FILE * dumpsim_file;

/***************************************************************/
/* */
/* Procedure: mem_read_32 */
/* */
/* Purpose: Read a 32-bit word from memory */
/* */
/***************************************************************/
uint32_t mem_read_32(uint32_t address)
{
int i;
for (i = 0; i < MEM_NREGIONS; i++) { if (address >= MEM_REGIONS[i].start &&
address < (MEM_REGIONS[i].start + MEM_REGIONS[i].size)) { uint32_t offset = address - MEM_REGIONS[i].start; return (MEM_REGIONS[i].mem[offset+3] << 0) | (MEM_REGIONS[i].mem[offset+2] << 8) | (MEM_REGIONS[i].mem[offset+1] << 16) | (MEM_REGIONS[i].mem[offset+0] << 24); } } return 0; } /***************************************************************/ /* */ /* Procedure: mem_write_32 */ /* */ /* Purpose: Write a 32-bit word to memory */ /* Implemnted using Big Endian */ /* */ /***************************************************************/ void mem_write_32(uint32_t address, uint32_t value) { int i; for (i = 0; i < MEM_NREGIONS; i++) { if (address >= MEM_REGIONS[i].start &&
address < (MEM_REGIONS[i].start + MEM_REGIONS[i].size)) { uint32_t offset = address - MEM_REGIONS[i].start; MEM_REGIONS[i].mem[offset+3] = (value >> 0) & 0xFF;
MEM_REGIONS[i].mem[offset+2] = (value >> 8) & 0xFF;
MEM_REGIONS[i].mem[offset+1] = (value >> 16) & 0xFF;
MEM_REGIONS[i].mem[offset+0] = (value >> 24) & 0xFF;
return;
}
}
}
/***************************************************************/
/* */
/* Procedure : help */
/* */
/* Purpose : Print out a list of commands */
/* */
/***************************************************************/
int help(char **args) {
printf(“—————–MIPS SIM Help———————–\n”);
printf(“go – run program to completion \n”);
printf(“run n – execute program for n instructions\n”);
printf(“mdump low high – dump memory from low to high \n”);
printf(“rdump – dump the register & bus values \n”);
printf(“input reg_no reg_value – set GPR reg_no to reg_value \n”);
printf(“? – display this help menu \n”);
printf(“quit – exit the program \n\n”);
return 1;
}

/***************************************************************/
/* */
/* Procedure : cycle */
/* */
/* Purpose : Execute a cycle */
/* */
/***************************************************************/
void cycle() {
process_instruction();
CURRENT_STATE = NEXT_STATE;
INSTRUCTION_COUNT++;
}

/***************************************************************/
/* */
/* Procedure : run n */
/* */
/* Purpose : Simulate MIPS for n cycles */
/* */
/***************************************************************/
//void run(int num_cycles) {
int run(char **args) {
int num_cycles;
int i;

if (args[1] == NULL) {
printf (“Incorrect run cmd: missing # of instrucitons to run\n\n”);
return 1;
}

num_cycles = atoi(args[1]);
if (num_cycles <= 0) { printf("Incorrect run cmd: num_cycles should be positive!\n\n"); return 1; } if (RUN_BIT == FALSE) { printf("Can't simulate: Simulator is halted\n\n"); return 1; } printf("Simulating for %d cycles...\n\n", num_cycles); for (i = 0; i < num_cycles; i++) { if (RUN_BIT == FALSE) { printf("Simulator halted\n\n"); break; } cycle(); } return 1; } /***************************************************************/ /* */ /* Procedure : go */ /* */ /* Purpose : Simulate MIPS until HALTed */ /* */ /***************************************************************/ int go(char **args) { if (RUN_BIT == FALSE) { printf("Can't simulate, Simulator is halted\n\n"); return 1; } printf("Simulating...\n\n"); while (RUN_BIT) cycle(); printf("Simulator halted\n\n"); return 1; } /***************************************************************/ /* */ /* Procedure : mdump */ /* */ /* Purpose : Dump a word-aligned region of memory to the */ /* output file. */ /* */ /***************************************************************/ int mdump(char **args) { int address, start, stop; if (args[1] == NULL || args[2] == NULL) { printf ("incorrect mdump syntax: missing start and/or stop address\n\n"); return 1; } start = strtol(args[1], NULL, 16); stop = strtol(args[2], NULL, 16); printf("\nMemory content [0x%08x..0x%08x] :\n", start, stop); printf("-------------------------------------\n"); for (address = start; address <= stop; address += 4) printf(" 0x%08x (%d) : 0x%x\n", address, address, mem_read_32(address)); printf("\n"); /* dump the memory contents into the dumpsim file */ fprintf(dumpsim_file, "\nMemory content [0x%08x..0x%08x] :\n", start, stop); fprintf(dumpsim_file, "-------------------------------------\n"); for (address = start; address <= stop; address += 4) fprintf(dumpsim_file, " 0x%08x (%d) : 0x%x\n", address, address, mem_read_32(address)); fprintf(dumpsim_file, "\n"); return 1; } /***************************************************************/ /* */ /* Procedure : rdump */ /* */ /* Purpose : Dump current register and bus values to the */ /* output file. */ /* */ /***************************************************************/ //void rdump(FILE * dumpsim_file) { int rdump(char **args) { int k; printf("\nCurrent register/bus values :\n"); printf("-------------------------------------\n"); printf("Instruction Count : %u\n", INSTRUCTION_COUNT); printf("PC : 0x%" PRIx32 "\n", CURRENT_STATE.PC); printf("Registers:\n"); for (k = 0; k < MIPS_REGS; k++) printf("$%d: 0x%" PRIx32 "\n", k, CURRENT_STATE.REGS[k]); printf("FLAG_N: %d\n", CURRENT_STATE.FLAG_N); printf("FLAG_Z: %d\n", CURRENT_STATE.FLAG_Z); printf("FLAG_V: %d\n", CURRENT_STATE.FLAG_V); printf("FLAG_C: %d\n", CURRENT_STATE.FLAG_C); printf("\n"); /* dump the state information into the dumpsim file */ fprintf(dumpsim_file, "\nCurrent register/bus values :\n"); fprintf(dumpsim_file, "-------------------------------------\n"); fprintf(dumpsim_file, "Instruction Count : %u\n", INSTRUCTION_COUNT); fprintf(dumpsim_file, "PC : 0x%" PRIx32 "\n", CURRENT_STATE.PC); fprintf(dumpsim_file, "Registers:\n"); for (k = 0; k < MIPS_REGS; k++) fprintf(dumpsim_file, "X%d: 0x%" PRIx32 "\n", k, CURRENT_STATE.REGS[k]); fprintf(dumpsim_file, "FLAG_N: %d\n", CURRENT_STATE.FLAG_N); fprintf(dumpsim_file, "FLAG_Z: %d\n", CURRENT_STATE.FLAG_Z); fprintf(dumpsim_file, "FLAG_V: %d\n", CURRENT_STATE.FLAG_V); fprintf(dumpsim_file, "FLAG_C: %d\n", CURRENT_STATE.FLAG_C); fprintf(dumpsim_file, "\n"); return 1; } #if 0 /***************************************************************/ /* */ /* Procedure : get_command */ /* */ /* Purpose : Read a command from standard input. */ /* */ /***************************************************************/ void get_command(FILE * dumpsim_file) { char buffer[20]; int start, stop, cycles; int register_no; int32_t register_value; printf("MIPS-SIM> “);

if (scanf(“%s”, buffer) == EOF)
exit(0);

printf(“\n”);

switch(buffer[0]) {
case ‘G’:
case ‘g’:
go();
break;

case ‘M’:
case ‘m’:
if (scanf(“%i %i”, &start, &stop) != 2)
break;

mdump(dumpsim_file, start, stop);
break;

case ‘?’:
help();
break;

case ‘Q’:
case ‘q’:
printf(“Bye.\n”);
exit(0);

case ‘R’:
case ‘r’:
if (buffer[1] == ‘d’ || buffer[1] == ‘D’)
rdump(dumpsim_file);
else {
if (scanf(“%d”, &cycles) != 1) break;
run(cycles);
}
break;

case ‘I’:
case ‘i’:
if (scanf(“%i %” PRIx32, &register_no, &register_value) != 2)
break;
CURRENT_STATE.REGS[register_no] = register_value;
NEXT_STATE.REGS[register_no] = register_value;
break;

default:
printf(“Invalid Command\n”);
break;
}
}
#endif

/***************************************************************/
/* */
/* Procedure : init_memory */
/* */
/* Purpose : Allocate and zero memory */
/* */
/***************************************************************/
void init_memory() {
int i;
for (i = 0; i < MEM_NREGIONS; i++) { MEM_REGIONS[i].mem = malloc(MEM_REGIONS[i].size); memset(MEM_REGIONS[i].mem, 0, MEM_REGIONS[i].size); } } /**************************************************************/ /* */ /* Procedure : load_program */ /* */ /* Purpose : Load program and service routines into mem. */ /* */ /**************************************************************/ void load_program(char *program_filename) { FILE * prog; int ii, word; /* Open program file. */ prog = fopen(program_filename, "r"); if (prog == NULL) { printf("Error: Can't open program file %s\n", program_filename); exit(-1); } /* Read in the program. */ ii = 0; while (fscanf(prog, "%x\n", &word) != EOF) { mem_write_32(MEM_TEXT_START + ii, word); ii += 4; } CURRENT_STATE.PC = MEM_TEXT_START; printf("Read %d words from program into memory.\n\n", ii/4); } /************************************************************/ /* */ /* Procedure : initialize */ /* */ /* Purpose : Load machine language program */ /* and set up initial state of the machine. */ /* */ /************************************************************/ void initialize(char *program_filename, int num_prog_files) { int i; init_memory(); for ( i = 0; i < num_prog_files; i++ ) { load_program(program_filename); while(*program_filename++ != '\0'); } NEXT_STATE = CURRENT_STATE; RUN_BIT = TRUE; } int exit_shell(char **args) { printf("Bye.\n"); return 0; } int input_cmd(char **args) { int reg_no, reg_value; if (args[1] == NULL || args[2] == NULL) { printf ("Incorrect input syntax: missing reg_no and/or reg_value\n\n"); return 1; } reg_no = atoi(args[1]); reg_value = atoi(args[2]); if (reg_no < 0 || reg_no >= MIPS_REGS) {
printf (“Incorrect register number: should be 0, 1, …, 31\n\n”);
return 1;
}

CURRENT_STATE.REGS[reg_no] = reg_value;
NEXT_STATE.REGS[reg_no] = reg_value;

return 1;
}

/*
List of builtin commands, followed by their corresponding functions.
*/
char *builtin_str[] = {
“g”,
“G”,
“go”,
“r”,
“R”,
“run”,
“mdump”,
“?”,
“h”,
“help”,
“q”,
“Q”,
“quit”,
“rdump”,
“i”,
“I”,
“input”
};

int (*builtin_func[]) (char **) = {
&go,
&go,
&go,
&run,
&run,
&run,
&mdump,
&help,
&help,
&help,
&exit_shell,
&exit_shell,
&exit_shell,
&rdump,
&input_cmd,
&input_cmd,
&input_cmd
};

int num_builtins() {
return sizeof(builtin_str) / sizeof(char *);
}

/**
@brief Execute shell built-in or launch program.
@param args Null terminated list of arguments.
@return 1 if the shell should continue running, 0 if it should terminate
*/
int execute_cmd(char **args)
{
int i;

if (args[0] == NULL) {
// An empty command was entered.
return 1;
}

for (i = 0; i < num_builtins(); i++) { if (strcmp(args[0], builtin_str[i]) == 0) { return (*builtin_func[i])(args); } } printf("Invalid Command\n\n"); return 1; } #define RL_BUFSIZE 1024 /** @brief Read a line of input from stdin. @return The line from stdin. */ char *read_line(void) { int bufsize = RL_BUFSIZE; int position = 0; char *buffer = malloc(sizeof(char) * bufsize); int c; if (!buffer) { fprintf(stderr, "shell: allocation error\n"); exit(EXIT_FAILURE); } while (1) { // Read a character c = getchar(); if (c == EOF) { exit(EXIT_SUCCESS); } else if (c == '\n') { buffer[position] = '\0'; return buffer; } else { buffer[position] = c; } position++; // If we have exceeded the buffer, reallocate. if (position >= bufsize) {
bufsize += RL_BUFSIZE;
buffer = realloc(buffer, bufsize);
if (!buffer) {
fprintf(stderr, “shell: allocation error\n”);
exit(EXIT_FAILURE);
}
}
}
}

#define TOK_BUFSIZE 64
#define TOK_DELIM ” \t\r\n\a”
/**
@brief Split a line into tokens (very naively).
@param line The line.
@return Null-terminated array of tokens.
*/
char **split_line(char *line)
{
int bufsize = TOK_BUFSIZE, position = 0;
char **tokens = malloc(bufsize * sizeof(char*));
char *token, **tokens_backup;

if (!tokens) {
fprintf(stderr, “shell: allocation error\n”);
exit(EXIT_FAILURE);
}

token = strtok(line, TOK_DELIM);
while (token != NULL) {
tokens[position] = token;
position++;

if (position >= bufsize) {
bufsize += TOK_BUFSIZE;
tokens_backup = tokens;
tokens = realloc(tokens, bufsize * sizeof(char*));
if (!tokens) {
free(tokens_backup);
fprintf(stderr, “shell: allocation error\n”);
exit(EXIT_FAILURE);
}
}

token = strtok(NULL, TOK_DELIM);
}
tokens[position] = NULL;
return tokens;
}

/***************************************************************/
/* */
/* Procedure : main */
/* */
/***************************************************************/
int main(int argc, char *argv[]) {
int status;
char *line;
char **args;

/* Error Checking */
if (argc < 2) { printf("Error: usage: %s …\n”,
argv[0]);
exit(1);
}

printf(“MIP Simulator\n\n”);

initialize(argv[1], argc – 1);

if ( (dumpsim_file = fopen( “dumpsim”, “w” )) == NULL ) {
printf(“Error: Can’t open dumpsim file\n”);
exit(-1);
}

do {
printf(“MIPS-SIM> “);
line = read_line();
args = split_line(line);
status = execute_cmd(args);
} while (status);

}