basic reading functionality added, need to complete parsing implementation

This commit is contained in:
Josh Ashton
2023-10-09 19:40:47 -06:00
parent 6a1fbca018
commit a5136d917b
6 changed files with 369 additions and 76 deletions
+53
View File
@@ -0,0 +1,53 @@
.data
welcomeMessage: .asciiz "Welcome to a MIPS assembly Fibonacci Sequence calculator!\nThis will calculate the nth term of the Fibonacci Sequence.\n"
prompt: .asciiz "Enter a number (n, input n > 2) to find the nth term:"
foundTerm: .asciiz "The nth term is: "
.text
main:
li $v0, 4 # syscall 4 is to print a string
la $a0, welcomeMessage # store the ascii string in register a0
syscall # print
jal getInput # get the user input
jal fibonacci # calculate the nth fibonacci term
move $a0, $v0 # move the returned term to register a0
li $v0, 1 # syscall 1 is to print an int
syscall # print
ori $v0, $0, 10 # system call code 10 for exit
syscall # exit the program
getInput:
li $v0, 4 # syscall 4 is to print a string
la $a0, prompt # store the ascii string in register a0
syscall # print
li $v0, 5 # syscall 5 is for reading an int
syscall # read an int from the user
move $a0, $v0 # load input into register a0
jr $ra # return to caller
fibonacci:
move $s1, $a0 # Copy the nth term
li $t0, 2 # Counter
li $t1, 0 # Prev value
li $t2, 1 # Current value
li $t3, 0 # Next value
while:
bge $t0, $s1, done # While the counter is less than n
add $t3, $t1, $t2 # Sum the previous and current values and save in register t3
move $t1, $t2 # Shift current value to previous value
move $t2, $t3 # Shift next value to current value
addi $t0, $t0, 1 # Increment counter
b while # Jump back to start of while loop
done:
move $v0, $t2 # Move current value to register v0
jr $ra # Return to caller
+96 -28
View File
@@ -1,9 +1,16 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../util/formats.h"
int compareIntArray(int * x, int * y, int size) {
for(int i = 0; i < size; i++)
if(x[i] != y[i]) return 0;
return 1;
}
int test_binaryToHex() {
return 1; // TODO
}
@@ -14,10 +21,7 @@ int test_toBinary_0_size5() {
int * binary = toBinary(0, size);
int expectedOutput[] = { 0, 0, 0, 0, 0 };
int cmp = 1;
for(int i = 0; i < size; i++)
if(binary[i] != expectedOutput[i]) cmp = 0;
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -28,10 +32,7 @@ int test_toBinary_0_size6() {
int * binary = toBinary(0, size);
int expectedOutput[] = { 0, 0, 0, 0, 0, 0 };
int cmp = 1;
for(int i = 0; i < size; i++)
if(binary[i] != expectedOutput[i]) cmp = 0;
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -42,10 +43,7 @@ int test_toBinary_10_size6() {
int * binary = toBinary(10, size);
int expectedOutput[] = { 0, 0, 1, 0, 1, 0 };
int cmp = 1;
for(int i = 0; i < size; i++)
if(binary[i] != expectedOutput[i]) cmp = 0;
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -56,10 +54,7 @@ int test_toBinary_20_size6() {
int * binary = toBinary(20, size);
int expectedOutput[] = { 0, 1, 0, 1, 0, 0 };
int cmp = 1;
for(int i = 0; i < size; i++)
if(binary[i] != expectedOutput[i]) cmp = 0;
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
@@ -70,17 +65,81 @@ int test_toBinary_17_size16() {
int * binary = toBinary(17, size);
int expectedOutput[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1};
int cmp = 1;
for(int i = 0; i < size; i++)
if(binary[i] != expectedOutput[i]) cmp = 0;
int cmp = compareIntArray(binary, expectedOutput, size);
free(binary);
return cmp;
}
int test_rToBinary() {
int test_rToBinary_sll() {
r* rFormat = malloc(sizeof(r));
return 1; // TODO
rFormat->opcode = 0; // Opcode for sll instruction
rFormat->rs = 0; // Register 17.
rFormat->rt = 16; // Register 18.
rFormat->rd = 14; // Register 13.
rFormat->shamt = 2; // Shift amount
rFormat->funct = 0; // Hexadecimal 00, or 0000 0000.
int * binary = rToBinary(rFormat);
int expectedOutput[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, 32);
free(binary);
return cmp;
}
int test_rToBinary_add() {
r* rFormat = malloc(sizeof(r));
rFormat->opcode = 0; // Opcode for add instruction
rFormat->rs = 17; // Register 17.
rFormat->rt = 18; // Register 18.
rFormat->rd = 13; // Register 13.
rFormat->shamt = 0; // Shift amount is 0
rFormat->funct = 32; // Hexadecimal 20, or 0010 0000.
int * binary = rToBinary(rFormat);
int expectedOutput[] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };
int cmp = compareIntArray(binary, expectedOutput, 32);
free(binary);
return cmp;
}
int test_rToHex_add() {
r* rFormat = malloc(sizeof(r));
rFormat->opcode = 0; // Opcode for add instruction
rFormat->rs = 17; // Register 17.
rFormat->rt = 18; // Register 18.
rFormat->rd = 13; // Register 13.
rFormat->shamt = 0; // Shift amount is 0
rFormat->funct = 32; // Hexadecimal 20, or 0010 0000.
char * hex = rToHex(rFormat);
char * expectedHex = "02326820";
int cmp = strcmp(hex, expectedHex);
free(hex);
if(cmp < 0 || cmp > 0) return 0;
else return 1;
}
int test_rToHex_sll() {
r* rFormat = malloc(sizeof(r));
rFormat->opcode = 0; // Opcode for sll instruction
rFormat->rs = 0; // Register 17.
rFormat->rt = 16; // Register 18.
rFormat->rd = 14; // Register 13.
rFormat->shamt = 2; // Shift amount
rFormat->funct = 0; // Hexadecimal 00, or 0000 0000.
char * hex = rToHex(rFormat);
char * expectedHex = "00107080";
int cmp = strcmp(hex, expectedHex);
free(hex);
if(cmp < 0 || cmp > 0) return 0;
else return 1;
}
int test_iToHex() {
@@ -89,11 +148,20 @@ int test_iToHex() {
}
int main() {
printf("\nTesting formats.h functionality.\n");
printf("\nTesting formats.h functionality. 1 = pass, 0 = fail\n");
printf("\ntoBinary_0_size5: %d\n", test_toBinary_0_size5());
printf("\ntoBinary_0_size6: %d\n", test_toBinary_0_size6());
printf("\ntoBinary_10_size6: %d\n", test_toBinary_10_size6());
printf("\ntoBinary_20_size6: %d\n", test_toBinary_20_size6());
printf("\ntoBinary_17_size16: %d\n", test_toBinary_17_size16());
printf("\nTesting number to binary (with formatted size):\n");
printf("toBinary_0_size5: %d\n", test_toBinary_0_size5());
printf("toBinary_0_size6: %d\n", test_toBinary_0_size6());
printf("toBinary_10_size6: %d\n", test_toBinary_10_size6());
printf("toBinary_20_size6: %d\n", test_toBinary_20_size6());
printf("toBinary_17_size16: %d\n", test_toBinary_17_size16());
printf("\nTesting R Format to Binary:\n");
printf("rToBinary_add: %d\n", test_rToBinary_add());
printf("rToBinary_sll: %d\n", test_rToBinary_sll());
printf("\nTesting R Format to Hex:\n");
printf("rToHex_add: %d\n", test_rToHex_add());
printf("rToHex_sll: %d\n", test_rToHex_sll());
}
+20
View File
@@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../util/parse.h"
char * filepath;
int test_readFile() {
initParse(filepath);
return 1;
}
int main() {
// filepath may be a relative or an absolute filepath
//filepath = "/home/jashton/dev/mipsToHex/src/test/Fibonacci.asm";
filepath = "Fibonacci.asm";
return test_readFile();
}
+137 -35
View File
@@ -1,9 +1,93 @@
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Represents the R instruction format.
typedef struct r {
int opcode; // 6 bits
int opcode_size;
int rs; // 5 bits
int rs_size;
int rt; // 5 bits
int rt_size;
int rd; // 5 bits
int rd_size;
int shamt; // 5 bits
int shamt_size;
int funct; // 6 bits
int functHex_size;
} r;
// Represents the I instruction format.
typedef struct i {
int opcode; // 6 bits
int rs; // 4 bits
int rt; // 4 bits
int immediate; // 16 bits
} i;
// Represents the J instruction format.
typedef struct j {
int opcode; // 6 bits
int address; // 26 bits
} j;
char subBinaryToHex(int * bin) {
int sum = 0;
for(int i = 0; i < 4; i++) {
switch (i) {
case 0:
if(bin[i] == 1) sum += 8;
break;
case 1:
if(bin[i] == 1) sum += 4;
break;
case 2:
if(bin[i] == 1) sum += 2;
break;
case 3:
if(bin[i] == 1) sum += 1;
break;
};
}
if(sum < 10) return sum + '0';
else {
switch (sum) {
case 10:
return 'A';
case 11:
return 'B';
case 12:
return 'C';
case 13:
return 'D';
case 14:
return 'E';
case 15:
return 'F';
default:
return 'G';
};
}
}
// Utility function to convert any given binary instruction into hexadecimal.
char* binaryToHex(char* bin) {
return "0x00000000";
// Expected input is an int array containing 32 bits.
char* binaryToHex(int * bin) {
char * hex = (char *)calloc(8, sizeof(char));
int j = 0;
for(int i = 0; i < 8; i++) {
int * tmp[4];
int c = j + 4;
for(; j < c; j++) tmp[j % 4] = &bin[j];
hex[i] = subBinaryToHex(* tmp);
}
return hex;
}
// Utility function to convert a number to binary
@@ -29,43 +113,61 @@ int* toBinary(int num, int size) {
return bin;
}
// Represents the R instruction format.
typedef struct r {
int opcode; // 6 bits
int opcode_size;
int rs; // 5 bits
int rs_size;
int rt; // 5 bits
int rt_size;
int rd; // 5 bits
int rd_size;
int shamt; // 5 bits
int shamt_size;
char* functHex; // 6 bits
int functHex_size;
} r;
char* rToBinary(r* format) {
char binary[32];
return binary;
// Utility function to copy an existing array into a destination array, starting at a specified index of the existing array.
// This allows for multiple existing arrays to be added in sequence to a destination array.
void fillArray(int * destArray, int * arrayToAdd, int startIndex, int destArraySize) {
int j = 0;
for(int i = startIndex; i < destArraySize; i++) {
destArray[i] = arrayToAdd[j];
j++;
}
}
// Represents the I instruction format.
typedef struct i {
int opcode; // 6 bits
int rs; // 4 bits
int rt; // 4 bits
int immediate; // 16 bits
} i;
int * rToBinary(r* format) {
int size = 32; // R-Format instructions when decoded into their bit strings are 32 bits.
// Dynamically allows for different sized arrays. Need to manually release from memory.
int * bin = (int*)calloc(size, sizeof(int));
// Fill up the array with default values.
for(int i = 0; i < size; i++)
bin[i] = 0;
// Create the binary form of the field, fill the instruction array with those values, and once complete, free from memory the original array.
int * opcode = toBinary(format->opcode, 6);
fillArray(bin, opcode, 0, size);
free(opcode);
int * rs = toBinary(format->rs, 5);
fillArray(bin, rs, 6, size);
free(rs);
int * rt = toBinary(format->rt, 5);
fillArray(bin, rt, 11, size);
free(rt);
int * rd = toBinary(format->rd, 5);
fillArray(bin, rd, 16, size);
free(rd);
int * shamt = toBinary(format->shamt, 5);
fillArray(bin, shamt, 21, size);
free(shamt);
int * funct = toBinary(format->funct, 6);
fillArray(bin, funct, 26, size);
free(funct);
return bin;
}
char * rToHex(r* format) {
int * bin = rToBinary(format);
return binaryToHex(bin);
}
// Utility function to convert any given I instruction into hexadecimal.
char* iToHex(i* format) {
return "";
}
// Represents the J instruction format.
typedef struct j {
int opcode; // 6 bits
int address; // 26 bits
} j;
+4 -13
View File
@@ -10,33 +10,24 @@ void initFunctions() {
iFormat = (i*)malloc(sizeof(i));
}
char* add(int * args[]) {
int * add(int * args[]) {
rFormat->opcode = 0;
rFormat->rd = *args[0];
rFormat->rs = *args[1];
rFormat->rt = *args[2];
rFormat->shamt = *args[4];
rFormat->functHex = "0x20";
rFormat->funct = 20;
return rToBinary(rFormat);
}
char* addi(int * args[]) {
rFormat->opcode = 0;
rFormat->rs = *args[0];
rFormat->rt = *args[1];
rFormat->functHex = "0x8";
return rToBinary(rFormat);
}
char* sub(int * args[]) {
int * sub(int * args[]) {
rFormat->opcode = 0;
rFormat->rd = *args[0];
rFormat->rs = *args[1];
rFormat->rt = *args[2];
rFormat->shamt = *args[4];
rFormat->functHex = "0x22";
rFormat->funct = 22;
return rToBinary(rFormat);
}
+59
View File
@@ -0,0 +1,59 @@
#include <bits/types/FILE.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE * file;
char * removeCommentsAndWhiteSpace(char * line) {
int j = 0;
char * newLine;
for(int i = 0; i < strlen(line); i++) {
// If we've reached a comment, we can break to return what we have
if(line[i] == '#') break;
// Remove commas and spaces.
if((line[i] != ',') && (isspace(line[i]) == 0)) {
newLine[j] = line[i];
j++;
}
}
// Remove any excess that is stored from a prior line.
for(; j < strlen(line); j++)
newLine[j] = (char)NULL;
return newLine;
}
char * parse(char * bareLine) {
char * function;
for(int i = 0; i < strlen(bareLine); i++) {
}
return function;
}
int initParse(char * filepath) {
// Open and read a file.
file = fopen(filepath, "r");
// Maximum number of characters in a line is 1024.
char lines[1024];
// Catch if the file does not exist/cannot be opened.
if(file == NULL) {
printf("%s cannot be opened.\n", filepath);
return 0;
}
// Get each line of the file.
while(fgets(lines, sizeof(lines), file))
printf("%s\n", parse(removeCommentsAndWhiteSpace(lines)));
fclose(file);
return 1;
}