diff --git a/pa1/.DS_Store b/pa1/.DS_Store new file mode 100644 index 0000000..0dce177 Binary files /dev/null and b/pa1/.DS_Store differ diff --git a/pa1/Makefile b/pa1/Makefile new file mode 100755 index 0000000..e13264b --- /dev/null +++ b/pa1/Makefile @@ -0,0 +1,14 @@ +HEADERS = simulator.h + +default: simulator + +simulator.o: simulator.c $(HEADERS) + gcc -c simulator.c -o simulator.o -ggdb -std=c99 + +simulator: simulator.o + gcc simulator.o -o simulator -ggdb -std=c99 + +clean: + -rm -f simulator.o + -rm -f simulator + -rm -f pipe_trace.txt *.out mdump.txt diff --git a/pa1/README.md b/pa1/README.md new file mode 100644 index 0000000..5e8ea55 --- /dev/null +++ b/pa1/README.md @@ -0,0 +1,13 @@ +MIPS Simulator +============== + +A simulator for the MIPS like Instruction Set, that translates machine code created from the assembler, and then executes the machine instructions. Each instruction goes through a Fetch, Decode, Execute, Memory and Writeback stage of processing. + +# Build + $ make + +# RUN add.out assembler output file + $ ./simulator add.out + + + diff --git a/pa1/mipsInstructionMap.h b/pa1/mipsInstructionMap.h new file mode 100644 index 0000000..f55f5bb --- /dev/null +++ b/pa1/mipsInstructionMap.h @@ -0,0 +1,35 @@ +/* + * + * mipsInstructionMap.h + * + * Defines instructions as a hex value for comparison + * + * Modified by Omer Khan + * + */ + +// R-Type Instructions +#define RTYPEOP 0x0 +#define ADD 0x20 +#define SUB 0x21 +#define AND 0x24 +#define OR 0x25 +#define SLL 0x0 +#define SLT 0x2A +#define SRL 0x2 +#define JR 0x8 + +// I-Type Instructions +#define LW 0x23 +#define SW 0x2B +#define ANDI 0xC +#define ORI 0xD +#define LUI 0xF +#define BEQ 0x4 +#define BNE 0x5 +#define SLTI 0xA +#define ADDI 0x8 + +// J-Type Instructions +#define J 0x2 +#define JAL 0x3 diff --git a/pa1/simulator.c b/pa1/simulator.c new file mode 100644 index 0000000..9b2c48d --- /dev/null +++ b/pa1/simulator.c @@ -0,0 +1,415 @@ +/* + * riscy-uconn simulator.c --- Non pipelined simulator + */ + +#include +#include +#include +#include "simulator.h" +#include "mipsInstructionMap.h" + +int debug = 0; +int pipe_trace = 1; + +static FILE *fptr_pt; + +int main(int argc, char *argv[]) { + + if (argc != 2) { + printf("Incorrect number of arguments\n"); + exit(1); + } + else { + // Open Input file + FILE *fp; + fp = fopen(argv[1], "r"); + + fptr_pt = fopen("pipe_trace.txt","w"); + + // Call initialize function for registers and instruction/data memory + initialize(fp); + + // Process one instruction at a time + process_instructions(); + + printf("\n Printing Output Registers \n"); + + // Output registers + rdump(); + + // Output Memory + mdump(); + + // Dealloc .data + free(memory); + memory = NULL; + + // Close File + fclose (fp); + return 0; + } +} + +void process_instructions() { + + int terminate = 0; + int instruction_counter = 0; //committed instruction count + + while(terminate != 1) + { + //Fetch Instruction + unsigned int instruction_fetch; + instruction_fetch = 0xffffffff; // initial state + instruction_fetch = fetch(instruction_fetch); + cycle++; + + if (pipe_trace == 1) { + fprintf(fptr_pt, "\ncycle %d, PC %d: ", cycle, pc); + inst_dump ("Fetch", instruction_fetch); + } + + // Decode Instruction + struct Registers decode_out; + decode_out = decode(instruction_fetch); + cycle++; + + if (pipe_trace == 1) { + fprintf(fptr_pt, "\ncycle %d, PC %d: ", cycle, pc); + inst_dump ("Decode", decode_out.inst); + } + + // Execute Instruction + struct Registers alu_out; + alu_out = execute(decode_out); + cycle++; + + if (pipe_trace == 1) { + fprintf(fptr_pt, "\ncycle %d, PC %d: ", cycle, pc); + inst_dump ("Execute", alu_out.inst); + } + + // Memory Stage + struct Registers mem_out; + mem_out = memory_stage(alu_out); + cycle++; + + if (pipe_trace == 1) { + fprintf(fptr_pt, "\ncycle %d, PC %d: ", cycle, pc); + inst_dump ("Memory", mem_out.inst); + } + + // Write Back Stage + unsigned int committed_inst; + committed_inst = write_back_stage(mem_out); + cycle++; + + if (pipe_trace == 1) { + fprintf(fptr_pt, "\ncycle %d, PC %d: ", cycle, pc); + inst_dump ("Writeback", committed_inst); + rdump_pt(); + } + + if(debug==1) + printf("\n cycle: %d IMEM ADDR:%d instruction 0x%08x", cycle, pc/4, instruction_fetch); + + if ( (committed_inst != 0xffffffff) & (committed_inst != 0x00000000) ) { + instruction_counter++; + } + + if (registers[0] != 0) + terminate = 1; // set terminate flag when $zero is updated + + }//while pc loop + + printf("\n TOTAL %d INSTRUCTIONS EXECUTEDIN %d CYCLES", instruction_counter, cycle); + +} //process_instruction + +// Advance PC +void advance_pc(int step) { + pc += step; +} + +unsigned int fetch(unsigned int instruction_fetch) { + unsigned int inst = 0; + return inst = memory[pc/4]; +} + +struct Registers decode(unsigned int instruction_fetch) { + struct Registers reg_temp; + + // your code for decode phase goes here. + + return reg_temp; +} + + +struct Registers execute(struct Registers decode_out) +{ + + // your code for execute phase goes here. + + return decode_out; +} + + +struct Registers memory_stage(struct Registers alu_out) +{ + + // your code for memory phase goes here. + + return alu_out; +} + +unsigned int write_back_stage(struct Registers mem_out) +{ + + // your code for write back phase goes here. + return mem_out.inst; +} + + +// Output reigsters +void rdump() +{ + printf("$0 $zero 0x%08x\n", registers[0]); + printf("$1 $at 0x%08x\n", registers[1]); + printf("$2 $v0 0x%08x\n", registers[2]); + printf("$3 $v1 0x%08x\n", registers[3]); + printf("$4 $a0 0x%08x\n", registers[4]); + printf("$5 $a1 0x%08x\n", registers[5]); + printf("$6 $a2 0x%08x\n", registers[6]); + printf("$7 $a3 0x%08x\n", registers[7]); + printf("$8 $t0 0x%08x\n", registers[8]); + printf("$9 $t1 0x%08x\n", registers[9]); + printf("$10 $t2 0x%08x\n", registers[10]); + printf("$11 $t3 0x%08x\n", registers[11]); + printf("$12 $t4 0x%08x\n", registers[12]); + printf("$13 $t5 0x%08x\n", registers[13]); + printf("$14 $t6 0x%08x\n", registers[14]); + printf("$15 $t7 0x%08x\n", registers[15]); + printf("$16 $s0 0x%08x\n", registers[16]); + printf("$17 $s1 0x%08x\n", registers[17]); + printf("$18 $s2 0x%08x\n", registers[18]); + printf("$19 $s3 0x%08x\n", registers[19]); + printf("$20 $s4 0x%08x\n", registers[20]); + printf("$21 $s5 0x%08x\n", registers[21]); + printf("$22 $s6 0x%08x\n", registers[22]); + printf("$23 $s7 0x%08x\n", registers[23]); + printf("$24 $t8 0x%08x\n", registers[24]); + printf("$25 $t9 0x%08x\n", registers[25]); + printf("$26 $k0 0x%08x\n", registers[26]); + printf("$27 $k1 0x%08x\n", registers[27]); + printf("$28 $gp 0x%08x\n", registers[28]); + printf("$29 $sp 0x%08x\n", registers[29]); + printf("$30 $fp 0x%08x\n", registers[30]); + printf("$31 $ra 0x%08x\n", registers[31]); + + printf(" --> pc 0x%08x\n", pc); +} + +void rdump_pt() { + fprintf(fptr_pt, "\n$0 $zero: %d $8 $t0: %d $16 $s0: %d $24 $t8: %d", registers[0], registers[8], registers[16], registers[24]); + fprintf(fptr_pt, "\n$1 $at: %d $9 $t1: %d $17 $s1: %d $25 $t9: %d", registers[1], registers[9], registers[17], registers[25]); + fprintf(fptr_pt, "\n$2 $v0: %d $10 $t2: %d $18 $s2: %d $26 $k0: %d", registers[2], registers[10], registers[18], registers[26]); + fprintf(fptr_pt, "\n$3 $v1: %d $11 $t3: %d $19 $s3: %d $27 $k1: %d", registers[3], registers[11], registers[19], registers[27]); + fprintf(fptr_pt, "\n$4 $a0: %d $12 $t4: %d $20 $s4: %d $28 $gp: %d", registers[4], registers[12], registers[20], registers[28]); + fprintf(fptr_pt, "\n$5 $a1: %d $13 $t5: %d $21 $s5: %d $29 $sp: %d", registers[5], registers[13], registers[21], registers[29]); + fprintf(fptr_pt, "\n$6 $a2: %d $14 $t6: %d $22 $s6: %d $30 $fp: %d", registers[6], registers[14], registers[22], registers[30]); + fprintf(fptr_pt, "\n$7 $a3: %d $15 $t7: %d $23 $s7: %d $31 $ra: %d\n", registers[7], registers[15], registers[23], registers[31]); +} + +// Output Memory +void mdump() { + FILE *fptr; + fptr = fopen("mdump.txt","w"); + int i = 0; + for(i=0;i<16384;i++) + { + fprintf(fptr,"\n Memory[%d] = %d",i,memory[i]); + } +} + +void inst_dump(char stage[], unsigned int inst) { + + int opcode = inst >> 26; + + unsigned int func = inst << 26; + func = func >> 26; + + int rs = (inst >> 21) & 0x1F; + int rt = (inst >> 16) & 0x1F; + int rd = (inst >> 11) & 0x1F; + int sa = (inst >> 6) & 0x1F; + int imm = inst & 0xFFFF; + short shortImm = (short)imm; + int target = inst & 0x03ffffff; + + if (inst == 0xffffffff) + fprintf(fptr_pt, "\n %s instr: ", stage); + + if (opcode == RTYPEOP) { + if (func == ADD) + fprintf(fptr_pt, "\n %s instr: add $%d, $%d, $%d", stage, rd, rs, rt); + if (func == SUB) + fprintf(fptr_pt, "\n %s instr: sub $%d, $%d, $%d", stage, rd, rs, rt); + if (func == AND) + fprintf(fptr_pt, "\n %s instr: and $%d, $%d, $%d", stage, rd, rs, rt); + if (func == OR) + fprintf(fptr_pt, "\n %s instr: or $%d, $%d, $%d", stage, rd, rs, rt); + if (func == SLL) + fprintf(fptr_pt, "\n %s instr: sll $%d, $%d, %d", stage, rd, rt, sa); + if (func == SRL) + fprintf(fptr_pt, "\n %s instr: srl $%d, $%d, %d", stage, rd, rt, sa); + if (func == SLT) + fprintf(fptr_pt, "\n %s instr: slt $%d, $%d, $%d", stage, rd, rs, rt); + if (func == JR) + fprintf(fptr_pt, "\n %s instr: jr $%d", stage, rs); + } + + if (opcode == LW) + fprintf(fptr_pt, "\n %s instr: lw $%d %d($%d)", stage, rt, imm, rs); + if (opcode == SW) + fprintf(fptr_pt, "\n %s instr: sw $%d %d($%d)", stage, rt, imm, rs); + if (opcode == ANDI) + fprintf(fptr_pt, "\n %s instr: andi $%d, $%d, %d", stage, rt, rs, imm); + if (opcode == ADDI) + fprintf(fptr_pt, "\n %s instr: addi $%d, $%d, %d", stage, rt, rs, imm); + if (opcode == ORI) + fprintf(fptr_pt, "\n %s instr: ori $%d, $%d, %d", stage, rt, rs, imm); + if (opcode == SLTI) + fprintf(fptr_pt, "\n %s instr: slti $%d, $%d, %d", stage, rt, rs, imm); + if (opcode == LUI) + fprintf(fptr_pt, "\n %s instr: lui $%d, %d", stage, rt, imm); + if (opcode == BEQ) + fprintf(fptr_pt, "\n %s instr: beq $%d, $%d, %d", stage, rs, rt, shortImm); + if (opcode == BNE) + fprintf(fptr_pt, "\n %s instr: bne $%d, $%d, %d", stage, rs, rt, shortImm); + + if (opcode == J) + fprintf(fptr_pt, "\n %s instr: j %d", stage, target); + if (opcode == JAL) + fprintf(fptr_pt, "\n %s instr: jal %d", stage, target); +} + +void initialize(FILE *fp) +{ + if (fp == NULL) + { + printf("Error opening input file.\n"); + exit(1); + } + + // Initialize registers values' to 0x0 + for (int i = 0; i < 32; i++) + registers[i] = 0x0; + + printf("\n Initialized Registers \n"); + + // Malloc memory + memory = (int *)malloc(16384 * sizeof(int)); + if (memory == NULL) + { + printf("Not enough memory. Aborting..\n"); + exit(1); + } + + // Initialize 'memory' array to -1 + for (int i = 0; i < 16384; i++) + { + memory[i] = -1; + } + + printf("\n Initialized Memory \n"); + + // Initialize variables for parsing + char line[MAX_LENGTH+2]; + char *p; + int i = 0, line_num = 0; + //int line_num = 0, i = 0, data_line = 0; + + // Copy .text section to memory, breaks at nop + while (fgets(line, MAX_LENGTH+2, fp) != NULL) + { + line_num++; + + // Remove '\n' from 'line' + p = strchr(line, '\n'); + if (p != NULL) + *p = '\0'; + + memory[i] = getDec(line); + //printf("\n %d",memory[i]); + + // If 'nop' found, move to 0x8000 / 2048 in memory and break + //if (strcmp(line, "00000000000000000000000000000000") == 0) + if (strcmp(line, "11111111111111111111111111111111") == 0) + { + memory[i] = 0; + i = 0x800; + break; + } + else + i++; + } + + int j = 2048; //Data Memory Starts at 2048 + for(j=i;j<16384;j++) + { + memory[j] = 2; + //printf("\n %d",memory[i]); + } + + printf("\n Instructions Read, Memory Offset: %d\n", line_num); + + // Seek fp to first instruction in .data + char data[MAX_LENGTH+2]; + int bytes = 33 * line_num; + fseek(fp, bytes, SEEK_SET); + + // Copy .data section to memory + while (fgets(line, MAX_LENGTH+2, fp) != NULL) + { + // Remove '\n' from 'line' + p = strchr(line, '\n'); + if (p != NULL) + *p = '\0'; + + memory[i] = getDec(line); + printf("\n Data: %d %d",i,memory[i]); + i++; + } + + printf("\n Data put in Memory \n"); +} + +// Convert a binary string to a decimal value +int getDec(char *bin) +{ + int b, k, m, n; + int len, sum = 0; + + // Length - 1 to accomodate for null terminator + len = strlen(bin) - 1; + + // Iterate the string + for(k = 0; k <= len; k++) + { + // Convert char to numeric value + n = (bin[k] - '0'); + + // Check the character is binary + if ((n > 1) || (n < 0)) + { + return 0; + } + + for(b = 1, m = len; m > k; m--) + b *= 2; + + // sum it up + sum = sum + n * b; + } + return sum; +} + diff --git a/pa1/simulator.h b/pa1/simulator.h new file mode 100644 index 0000000..2864e26 --- /dev/null +++ b/pa1/simulator.h @@ -0,0 +1,70 @@ +/* + + * simulator.h + * + * Simulator header file declaring variables and methods + * + */ + +#ifndef SIMULATOR_H_ +#define SIMULATOR_H_ + +// Define MAX_LENGTH for number of registers & instruction length +#define MAX_LENGTH 32 + +// Array of size MAX_LENGTH to hold registers +int registers[MAX_LENGTH]; + +// PC Register +unsigned int pc = 0; +unsigned int pc_n = 0; + +// Memory Allocated +//unsigned int *memory; +int *memory; + +// CLOCK CYCLE +int cycle = 0; + +struct Registers +{ + unsigned int inst; + int x; + unsigned int y; + int reg; + int rs; + int rt; + int rd; + int sa; + unsigned short imm; + + int memory_flag; + int addr_mem; + int branch_flag; + int jmp_out_31; + + //ALU Inputs/Outputs + int A; + int B; + int C; + int D; + +}; + +void initialize(FILE *fp); +void process_instructions(); +int getDec(char *bin); +void isZero(int reg); +void advance_pc(int step); +void rdump(); +void rdump_pt(); +void mdump(); +void inst_dump(char [], unsigned int inst); + +unsigned int fetch(unsigned int instuction_fetch); +struct Registers decode(unsigned int instuction_fetch); +struct Registers execute(struct Registers decode_out); +struct Registers memory_stage(struct Registers alu_out); +unsigned int write_back_stage(struct Registers memory_out); + +#endif /* SIMULATOR_H_ */ diff --git a/pa1/unittests/beq_test1.asm b/pa1/unittests/beq_test1.asm new file mode 100644 index 0000000..758bdc7 --- /dev/null +++ b/pa1/unittests/beq_test1.asm @@ -0,0 +1,27 @@ +.text +add $a0, $zero, $zero # set $a0=0 : 0 --> i +addi $a1, $zero, 1 # set $a1=1 + +loop: +addi $t0, $zero, 2048 # set $t0 to 2048 +#ori $t0, $zero, 2048 # set $t0 to 2048 +sll $t1, $a0, 2 # $t1 <-- $a0 << 2 : $t1 <-- i*4 +add $t0, $t0, $t1 # form address of array[i] in $t0 +sw $zero, 0($t0) # store 32-bits of zero from $zero into array[i] +addi $a0, $a0, 1 # i++ +slti $t0, $a0, 10 # set $t0=1 if $a0 < 10 otherwise $t0=0 +beq $t0, $a1, loop # if $t0=0, branch to end label + +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 10 +2049: .word 32 +2050: .word 2 +2051: .word 2 +2052: .word 5 +2053: .word 5 +2054: .word 5 +2055: .word 5 +2056: .word 5 + diff --git a/pa1/unittests/beq_test2.asm b/pa1/unittests/beq_test2.asm new file mode 100644 index 0000000..30dbdb0 --- /dev/null +++ b/pa1/unittests/beq_test2.asm @@ -0,0 +1,27 @@ +.text +add $a0, $zero, $zero # set $a0=0 : 0 --> i + +loop: +slti $t0, $a0, 10 # set $t0=1 if $a0 < 10 otherwise $t0=0 +beq $t0, $zero, end # if $t0=0, branch to end label +addi $t0, $zero, 2048 +sll $t1, $a0, 2 # $t1 <-- $a0 << 2 : $t1 <-- i*4 +add $t0, $t0, $t1 # form address of array[i] in $t0 +sw $zero, 0($t0) # store 32-bits of zero from $zero into array[i] +addi $a0, $a0, 1 # i++ +beq $zero, $zero, loop # branch to label loop -- always branches + +end: +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 10 +2049: .word 32 +2050: .word 2 +2051: .word 2 +2052: .word 5 +2053: .word 5 +2054: .word 5 +2055: .word 5 +2056: .word 5 + diff --git a/pa1/unittests/bne_test1.asm b/pa1/unittests/bne_test1.asm new file mode 100644 index 0000000..fb354d8 --- /dev/null +++ b/pa1/unittests/bne_test1.asm @@ -0,0 +1,28 @@ +.text +add $a0, $zero, $zero # set $a0=0 : 0 --> i + +loop: +#addi $t0, $zero, 2048 # set $t0 to 2048 +ori $t0, $zero, 2048 # set $t0 to 2048 +#lui $t0, 0 # $t0 <-- 0x00000000 +#ori $t0, $t0, 0 # $t0 <-- $t0 | 0x0800 : $t0 = 0x00000800 +sll $t1, $a0, 2 # $t1 <-- $a0 << 2 : $t1 <-- i*4 +add $t0, $t0, $t1 # form address of array[i] in $t0 +sw $zero, 0($t0) # store 32-bits of zero from $zero into array[i] +addi $a0, $a0, 1 # i++ +slti $t0, $a0, 10 # set $t0=1 if $a0 < 10 otherwise $t0=0 +bne $t0, $zero, loop # if $t0=0, branch to end label + +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 10 +2049: .word 32 +2050: .word 2 +2051: .word 2 +2052: .word 5 +2053: .word 5 +2054: .word 5 +2055: .word 5 +2056: .word 5 + diff --git a/pa1/unittests/fibonacci.asm b/pa1/unittests/fibonacci.asm new file mode 100644 index 0000000..5a8c137 --- /dev/null +++ b/pa1/unittests/fibonacci.asm @@ -0,0 +1,50 @@ +.text +addi $t9, $zero, 10 +addi $t1, $zero, 0 +addi $t2, $zero, 1 +j fibonacci + +fibonacci: +add $t3, $t2, $t1 +addq $t1, $zero, $t2 +add $t2, $zero, $t3 +addi $t5, $t5, 1 +bne $t5, $t9, fibonacci +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 10 +2049: .word 10 +2050: .word 20 +2051: .word 30 +2052: .word 40 +2053: .word 50 +2054: .word 60 +2055: .word 70 +2056: .word 80 +2057: .word 90 +2058: .word 100 +2059: .word 3 +2060: .word 3 +2061: .word 3 +2062: .word 3 +2063: .word +2064: .word 11 +2065: .word 10 +2066: .word 20 +2067: .word 30 +2068: .word 40 +2069: .word 50 +2070: .word 60 +2071: .word 70 +2072: .word 80 +2073: .word 90 +2074: .word 100 +2075: .word 3 +2076: .word 3 +2077: .word 3 +2078: .word 3 +2079: .word 3 +2080: .word 5 + + diff --git a/pa1/unittests/j_test1.asm b/pa1/unittests/j_test1.asm new file mode 100644 index 0000000..550fcb0 --- /dev/null +++ b/pa1/unittests/j_test1.asm @@ -0,0 +1,27 @@ +.text +add $t0, $zero, $zero # iterator i = 0 +add $t2, $zero, $zero # initialize a memory pointer to zero +add $t3, $zero, $zero # initialize temporary register to zero +add $t4, $zero, $zero # initialize temporary register to zero +j jump_test1 # Jump to procedure "jump_test1" + +jump_test2: +lw $a1, 2048($t2) # Load a1 = 2, Mem[2048] = 2, 2 in simulator +addi $t2, $t2, 1 # Add 1 to the pointer to access Mem[2049] +lw $a2, 2048($t2) # Load a2 = 10, Mem[2049] = 10, 10 in simulator +j end # Jump to procedure "end" + +jump_test1: +add $t5, $zero, $zero # initialize temporary register to zero +add $t6, $zero, $zero # initialize temporary register to zero +j jump_test2 # Jump to procedure "jump_test2" + +end: +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +# --- Start of the Memory Layout --- + +.data +2048: .word 2 +2049: .word 10 + diff --git a/pa1/unittests/jal_test1.asm b/pa1/unittests/jal_test1.asm new file mode 100644 index 0000000..091d4a1 --- /dev/null +++ b/pa1/unittests/jal_test1.asm @@ -0,0 +1,20 @@ +.text +addi $a0, $zero, 2 # argument 0 = 2 +addi $a1, $zero, 3 # argument 1 = 3 +addi $a2, $zero, 4 # argument 2 = 4 +addi $a3, $zero, 5 # argument 3 = 5 +add $t4, $zero, $zero +jal diffofsums # call procedure +add $s0, $v0, $zero # y = returned value +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +diffofsums: +add $t0, $a0, $a1 # $t0 = f + g +add $t1, $a2, $a3 # $t1 = h + i +sub $s0, $t0, $t1 # result = (f+g)-(h+i) +add $v0, $s0, $zero # put return value in $v0 +jr $ra # return to caller + +.data +2048: .word 10 +2049: .word 10 diff --git a/pa1/unittests/jr_test1.asm b/pa1/unittests/jr_test1.asm new file mode 100644 index 0000000..f465759 --- /dev/null +++ b/pa1/unittests/jr_test1.asm @@ -0,0 +1,24 @@ +.text +addi $a0, $zero, 2 # argument 0 = 2 +addi $a1, $zero, 3 # argument 1 = 3 +addi $a2, $zero, 4 # argument 2 = 4 +addi $a3, $zero, 5 # argument 3 = 5 +add $t4, $zero, $zero +addi $t4, $t4, 44 +jr $t4 # call procedure +add $s0, $v0, $zero # y = returned value +add $t5, $zero, $zero +addi $t5, $t5, 72 +jr $t5 +add $t0, $a0, $a1 # $t0 = f + g +add $t1, $a2, $a3 # $t1 = h + i +sub $s0, $t0, $t1 # result = (f+g)-(h+i) +add $v0, $s0, $zero # put return value in $v0 +add $t6, $zero, $zero +addi $t6, $t6, 28 +jr $t6 # return to caller +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 10 +2049: .word 10 diff --git a/pa1/unittests/jr_test2.asm b/pa1/unittests/jr_test2.asm new file mode 100644 index 0000000..f9b504c --- /dev/null +++ b/pa1/unittests/jr_test2.asm @@ -0,0 +1,21 @@ +.text +addi $a0, $zero, 2 # argument 0 = 2 +addi $a1, $zero, 3 # argument 1 = 3 +addi $a2, $zero, 4 # argument 2 = 4 +addi $a3, $zero, 5 # argument 3 = 5 +add $t4, $zero, $zero +addi $t4, $t4, 36 +jr $t4 # call procedure +add $s0, $v0, $zero # y = returned value +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator +add $t0, $a0, $a1 # $t0 = f + g +add $t1, $a2, $a3 # $t1 = h + i +sub $s0, $t0, $t1 # result = (f+g)-(h+i) +add $v0, $s0, $zero # put return value in $v0 +add $t6, $zero, $zero +addi $t6, $t6, 28 +jr $t6 # return to caller + +.data +2048: .word 10 +2049: .word 10 diff --git a/pa1/unittests/lw_sw_test1.asm b/pa1/unittests/lw_sw_test1.asm new file mode 100644 index 0000000..dcb79f0 --- /dev/null +++ b/pa1/unittests/lw_sw_test1.asm @@ -0,0 +1,59 @@ +.text +add $t0, $zero, $zero # i = 0 +add $t1, $zero, $zero # initialize the sum to zero +add $t2, $zero, $zero # for second loop compare 2 +add $t3, $zero, $zero +add $t5, $zero, $zero # initialize temporary register to zero +add $t6, $zero, $zero # for sw later +add $t7, $zero, $zero + +lw $t1, 2048($t0) # $t1=20 +lw $t2, 2048($t1) # $t2=4 +add $t4, $t1, $t2 # $t4=24 +lw $t3, 2048($t4) # $t3=8 +add $t4, $t4, $t3 # $t4=32 +sw $t4, 2048($t0) # mem[2048]=32 +lw $t1, 2048($t0) # $t1=32 <-- observation of stored value 32 as $t1=0x00000020 +lw $t2, 2048($t1) # $t2=5 +add $t4, $t1, $t2 # $t4=37 +sw $t4, 2048($t1) # mem[2080]=37 +lw $t5, 2048($t1) # $t5=37 <--- observation of stored value 37 as $t5=0x00000025 + +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 20 +2049: .word 32 +2050: .word 2 +2051: .word 2 +2052: .word 3 +2053: .word 3 +2054: .word 3 +2055: .word 3 +2056: .word 3 +2057: .word 3 +2058: .word 3 +2059: .word 3 +2060: .word 3 +2061: .word 3 +2062: .word 3 +2063: .word 3 +2064: .word 3 +2065: .word 3 +2066: .word 3 +2067: .word 3 +2068: .word 4 +2069: .word 3 +2070: .word 3 +2071: .word 3 +2072: .word 8 +2073: .word 3 +2074: .word 3 +2075: .word 3 +2076: .word 3 +2077: .word 3 +2078: .word 3 +2079: .word 3 +2080: .word 5 + + diff --git a/pa1/unittests/rand_test1.asm b/pa1/unittests/rand_test1.asm new file mode 100644 index 0000000..4f63409 --- /dev/null +++ b/pa1/unittests/rand_test1.asm @@ -0,0 +1,38 @@ +.text +add $t0, $zero, $zero +add $t1, $zero, $zero +add $t2, $zero, $zero +add $t3, $zero, $zero +add $t5, $zero, $zero +add $t6, $zero, $zero +add $t7, $zero, $zero + + +lw $t1, 2048($t0) # $t1=5119 or 0x000013ff +andi $t2, $t1, 255 # mask 0x000000ff, so $t2=255 or 0x000000ff +sll $t3, $t2, 1 # times 2, so $t3=510 or 0x000001fe +andi $t4, $t3, 63 # mask 0x0000003f, so $t4=62 or 0x0000003e +#lui $t5, 65535 # $t5=-65536 or 0xffff0000 + +srl $t5, $t4, 1 # div 2, so $t5=31 or 0x0000001f +srl $t6, $t4, 2 # div 4, so $t6=15 or 0x0000000f +srl $t7, $t4, 3 # div 8, so $t7=7 or 0x00000007 + +sub $a0, $t5, $t6 # $a0=16 or 0x00000010 +and $a1, $t5, $t6 # $a1=15 or 0x0000000f +or $a2, $t5, $t6 # $a2=31 or 0x0000001f + + +ori $a3, $a0, 3 # $a3=19 or 0x00000013 + +slti $t0, $a0, 17 # $t0=1 +addi $t0, $t0, 2 # $t0=3 or 0x00000003 + +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + + +.data +2048: .word 5119 +2049: .word 32 + + diff --git a/pa1/unittests/rand_test2.asm b/pa1/unittests/rand_test2.asm new file mode 100644 index 0000000..d3f8f7b --- /dev/null +++ b/pa1/unittests/rand_test2.asm @@ -0,0 +1,23 @@ +.text +add $t0, $zero, $zero +add $t1, $zero, $zero +add $t2, $zero, $zero +add $t3, $zero, $zero +add $t5, $zero, $zero +add $t6, $zero, $zero +add $t7, $zero, $zero + + +lw $t1, 2048($t0) # $t1=5119 or 0x000013ff +andi $t2, $t1, 255 # mask 0x000000ff, so $t2=255 or 0x000000ff +sll $t3, $t2, 1 # times 2, so $t3=510 or 0x000001fe +andi $t4, $t3, 63 # mask 0x0000003f, so $t4=62 or 0x0000003e +lui $t5, 65535 # $t5=-65536 or 0xffff0000 + +addi $zero $zero, 1 # $zero register should never be updated, so detect this change and quit simulator + +.data +2048: .word 5119 +2049: .word 32 + +