basic reading functionality added, need to complete parsing implementation
This commit is contained in:
@@ -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
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user