moving to nested linked list structure for instructions and arguments. this should allow for better dynamism between instructions and clearer organizational logic.
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "util/registers.h"
|
#include "util/registers.h"
|
||||||
#include "util/functions.h"
|
#include "util/functions.c"
|
||||||
|
|
||||||
int help() {
|
int help() {
|
||||||
printf(
|
printf(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../util/formats.h"
|
#include "../util/formats.c"
|
||||||
|
|
||||||
int compareIntArray(int * x, int * y, int size) {
|
int compareIntArray(int * x, int * y, int size) {
|
||||||
for(int i = 0; i < size; i++)
|
for(int i = 0; i < size; i++)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../util/parse.h"
|
#include "../util/parse.c"
|
||||||
|
|
||||||
char * filepath;
|
char * filepath;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "formats.h"
|
||||||
|
|
||||||
|
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.
|
||||||
|
// 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
|
||||||
|
int * toBinary(int num, int size) {
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
if(num == 0) return bin;
|
||||||
|
|
||||||
|
// Since the binary values are calculated in reverse order, entering the values into the array
|
||||||
|
// in reverse order will negate this, and leave us with an array in the correct order.
|
||||||
|
int i = size - 1;
|
||||||
|
while(num > 0) {
|
||||||
|
bin[i] = num % 2;
|
||||||
|
num = num / 2;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int * iToBinary(i* 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 * immediate = toBinary(format->immediate, 16);
|
||||||
|
fillArray(bin, immediate, 16, size);
|
||||||
|
free(immediate);
|
||||||
|
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * rToHex(r* format) {
|
||||||
|
return binaryToHex(rToBinary(format));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to convert any given I instruction into hexadecimal.
|
||||||
|
char* iToHex(i* format) {
|
||||||
|
return binaryToHex(iToBinary(format));
|
||||||
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// Represents the R instruction format.
|
// Represents the R instruction format.
|
||||||
typedef struct r {
|
typedef struct r {
|
||||||
int opcode; // 6 bits
|
int opcode; // 6 bits
|
||||||
@@ -33,141 +28,3 @@ typedef struct j {
|
|||||||
int address; // 26 bits
|
int address; // 26 bits
|
||||||
} j;
|
} 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.
|
|
||||||
// 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
|
|
||||||
int* toBinary(int num, int size) {
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
if(num == 0) return bin;
|
|
||||||
|
|
||||||
// Since the binary values are calculated in reverse order, entering the values into the array
|
|
||||||
// in reverse order will negate this, and leave us with an array in the correct order.
|
|
||||||
int i = size - 1;
|
|
||||||
while(num > 0) {
|
|
||||||
bin[i] = num % 2;
|
|
||||||
num = num / 2;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 "";
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,20 @@
|
|||||||
#define FOREACH_FUNCTION(FUNCTION) \
|
#define FOREACH_FUNCTION(FUNCTION) \
|
||||||
FUNCTION(add) \
|
FUNCTION(add) \
|
||||||
|
FUNCTION(jr) \
|
||||||
|
FUNCTION(syscall) \
|
||||||
FUNCTION(li) \
|
FUNCTION(li) \
|
||||||
|
FUNCTION(addu) \
|
||||||
|
FUNCTION(and) \
|
||||||
|
FUNCTION(nor) \
|
||||||
|
FUNCTION(or) \
|
||||||
|
FUNCTION(slt) \
|
||||||
|
FUNCTION(sltu) \
|
||||||
|
FUNCTION(sll) \
|
||||||
|
FUNCTION(srl) \
|
||||||
|
FUNCTION(sub) \
|
||||||
|
FUNCTION(subu) \
|
||||||
|
FUNCTION(addi) \
|
||||||
|
FUNCTION(jal) \
|
||||||
|
|
||||||
#define GENERATE_ENUM(ENUM) ENUM,
|
#define GENERATE_ENUM(ENUM) ENUM,
|
||||||
#define GENERATE_STRING(STRING) #STRING,
|
#define GENERATE_STRING(STRING) #STRING,
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "formats.c"
|
||||||
|
|
||||||
|
r* rFormat;
|
||||||
|
i* iFormat;
|
||||||
|
|
||||||
|
void initFunctions() {
|
||||||
|
rFormat = (r*)malloc(sizeof(r));
|
||||||
|
iFormat = (i*)malloc(sizeof(i));
|
||||||
|
|
||||||
|
rFormat->opcode = 0;
|
||||||
|
iFormat->opcode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------- R FORMAT INSTRUCTIONS -------------------------- //
|
||||||
|
char * add(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 32;
|
||||||
|
|
||||||
|
// Unused in add instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * addu(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 33;
|
||||||
|
|
||||||
|
// Unused in addu instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * and(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 36;
|
||||||
|
|
||||||
|
// Unused in and instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * jr(int * args[]) {
|
||||||
|
rFormat->rs = *args[0];
|
||||||
|
rFormat->funct = 8;
|
||||||
|
|
||||||
|
// Unused in jr instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
rFormat->rd = 0;
|
||||||
|
rFormat->rt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * nor(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 39;
|
||||||
|
|
||||||
|
// Unused in nor instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * or(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 37;
|
||||||
|
|
||||||
|
// Unused in or instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * slt(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 42;
|
||||||
|
|
||||||
|
// Unused in slt instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * sltu(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 43;
|
||||||
|
|
||||||
|
// Unused in sltu instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * sll(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rt = *args[1];
|
||||||
|
rFormat->shamt = *args[2];
|
||||||
|
rFormat->funct = 0;
|
||||||
|
|
||||||
|
// Unused in sll instruction.
|
||||||
|
rFormat->rs = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * srl(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rt = *args[1];
|
||||||
|
rFormat->shamt = *args[2];
|
||||||
|
rFormat->funct = 2;
|
||||||
|
|
||||||
|
// Unused in sll instruction.
|
||||||
|
rFormat->rs = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * sub(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 34;
|
||||||
|
|
||||||
|
// Unused in sll instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * subu(int * args[]) {
|
||||||
|
rFormat->rd = *args[0];
|
||||||
|
rFormat->rs = *args[1];
|
||||||
|
rFormat->rt = *args[2];
|
||||||
|
rFormat->funct = 35;
|
||||||
|
|
||||||
|
// Unused in sll instruction.
|
||||||
|
rFormat->shamt = 0;
|
||||||
|
|
||||||
|
return rToHex(rFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------- I FORMAT INSTRUCTIONS -------------------------- //
|
||||||
|
char * addi(int * args[]) {
|
||||||
|
iFormat->opcode = 8;
|
||||||
|
iFormat->rt = *args[0];
|
||||||
|
iFormat->rs = *args[1];
|
||||||
|
iFormat->immediate = *args[2];
|
||||||
|
|
||||||
|
return iToHex(iFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * addiu(int * args[]) {
|
||||||
|
iFormat->opcode = 9;
|
||||||
|
iFormat->rt = *args[0];
|
||||||
|
iFormat->rs = *args[1];
|
||||||
|
iFormat->immediate = *args[2];
|
||||||
|
|
||||||
|
return iToHex(iFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * andi(int * args[]) {
|
||||||
|
iFormat->opcode = 12;
|
||||||
|
iFormat->rt = *args[0];
|
||||||
|
iFormat->rs = *args[1];
|
||||||
|
iFormat->immediate = *args[2];
|
||||||
|
|
||||||
|
return iToHex(iFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * beq(int * args[]) {
|
||||||
|
iFormat->opcode = 4;
|
||||||
|
iFormat->rt = *args[0];
|
||||||
|
iFormat->rs = *args[1];
|
||||||
|
iFormat->immediate = *args[2];
|
||||||
|
|
||||||
|
return iToHex(iFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------- J FORMAT INSTRUCTIONS -------------------------- //
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "formats.h"
|
|
||||||
|
|
||||||
r* rFormat;
|
|
||||||
i* iFormat;
|
|
||||||
|
|
||||||
void initFunctions() {
|
|
||||||
rFormat = (r*)malloc(sizeof(r));
|
|
||||||
iFormat = (i*)malloc(sizeof(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
char * add(int * args[]) {
|
|
||||||
rFormat->opcode = 0;
|
|
||||||
rFormat->rd = *args[0];
|
|
||||||
rFormat->rs = *args[1];
|
|
||||||
rFormat->rt = *args[2];
|
|
||||||
rFormat->shamt = *args[3];
|
|
||||||
rFormat->funct = 20;
|
|
||||||
|
|
||||||
return rToHex(rFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * sub(int * args[]) {
|
|
||||||
rFormat->opcode = 0;
|
|
||||||
rFormat->rd = *args[0];
|
|
||||||
rFormat->rs = *args[1];
|
|
||||||
rFormat->rt = *args[2];
|
|
||||||
rFormat->shamt = *args[3];
|
|
||||||
rFormat->funct = 22;
|
|
||||||
|
|
||||||
return rToHex(rFormat);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
typedef struct args {
|
||||||
|
int arg;
|
||||||
|
struct args *nextArg; // Allows dynamically sized lists of arguments. For eg. syscall will just be 1 element, but add has 4 elements.
|
||||||
|
} args;
|
||||||
|
|
||||||
|
typedef struct instruction {
|
||||||
|
int formatType; // 0 = R, 1 = I, 2 = J
|
||||||
|
struct instruction* nextInstruction;
|
||||||
|
struct args* a; // A linked list of each argument of the instruction.
|
||||||
|
|
||||||
|
} instruction;
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "instruction.h"
|
||||||
|
|
||||||
|
int traverse(struct instruction* current) {
|
||||||
|
while(current->nextInstruction != NULL) {
|
||||||
|
|
||||||
|
struct args* currentArgs = current->a;
|
||||||
|
|
||||||
|
while(currentArgs != NULL) {
|
||||||
|
printf("%d ", currentArgs->arg);
|
||||||
|
|
||||||
|
currentArgs = currentArgs->nextArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
current = current->nextInstruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test driver for nested linked list functionality.
|
||||||
|
int main() {
|
||||||
|
struct instruction* head = (instruction*) malloc(sizeof(instruction));
|
||||||
|
struct instruction* current = head;
|
||||||
|
|
||||||
|
for(int i = 0; i < 20; i++) {
|
||||||
|
|
||||||
|
// Get a pseudo random formatType between 0 and 2 inclusive
|
||||||
|
current->formatType = i % 3;
|
||||||
|
|
||||||
|
// Create the head and current pointers for the inner linked list.
|
||||||
|
struct args* argsHead = (args*) malloc(sizeof(args));
|
||||||
|
current->a = argsHead;
|
||||||
|
struct args* argsCurrent = argsHead;
|
||||||
|
|
||||||
|
for(int j = 0; j < (i % 4 + 1); j++) {
|
||||||
|
argsCurrent->arg = j;
|
||||||
|
|
||||||
|
argsCurrent->nextArg = (args*) malloc(sizeof(args));
|
||||||
|
argsCurrent = argsCurrent->nextArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next instruction.
|
||||||
|
current->nextInstruction = (instruction*) malloc(sizeof(instruction));
|
||||||
|
current = current->nextInstruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
traverse(head);
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "formats.h"
|
#include "formats.c"
|
||||||
#include "registers.h"
|
#include "registers.h"
|
||||||
#include "functionAssigner.h"
|
#include "functionAssigner.h"
|
||||||
|
|
||||||
@@ -12,8 +12,8 @@ FILE * file;
|
|||||||
|
|
||||||
// Determines if the parser should keep a space, based upon if the space is surrounded by two non-space characters.
|
// Determines if the parser should keep a space, based upon if the space is surrounded by two non-space characters.
|
||||||
int determineKeepSpace(char prior, char after) {
|
int determineKeepSpace(char prior, char after) {
|
||||||
if(prior != NULL && !isspace(prior))
|
if(&prior != (char *) NULL && !isspace(prior))
|
||||||
if(after != NULL && !isspace(after))
|
if(&after != (char *) NULL && !isspace(after))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -57,37 +57,38 @@ char * removeCommentsAndWhiteSpace(char * line) {
|
|||||||
|
|
||||||
// Parse a line of assembly into numerical representations for the function (eg. add = 0), registers, offset, etc.
|
// Parse a line of assembly into numerical representations for the function (eg. add = 0), registers, offset, etc.
|
||||||
int * parseIntoNotation(char * bareLine) {
|
int * parseIntoNotation(char * bareLine) {
|
||||||
int numFunctions = 2; // TODO: Need to obtain dynamically.
|
int numFunctions = 20; // TODO: Need to obtain dynamically.
|
||||||
int * notation = (int *)calloc(4, sizeof(int));
|
|
||||||
//char * tokens = strtok(bareLine, " ");
|
//char * tokens = strtok(bareLine, " ");
|
||||||
|
|
||||||
char * token = strtok(bareLine, " ");
|
char * token = strtok(bareLine, " ");
|
||||||
|
|
||||||
int counter = 0;
|
int cmd;
|
||||||
|
for(int i = 0; i < numFunctions; i++)
|
||||||
|
if(strcmp(token, FUNCTION_STRING[i]) == 0) cmd = i;
|
||||||
|
|
||||||
|
int * notation = (int *)calloc(4, sizeof(int));
|
||||||
|
int counter = 1;
|
||||||
while (token != NULL)
|
while (token != NULL)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < numFunctions; i++) {
|
// Compare only the first token to all available functions.
|
||||||
if(strcmp(token, FUNCTION_STRING[i]) == 0) {
|
if(counter == 0) {
|
||||||
printf("found a match between %s and %s, value is %d\n", token, FUNCTION_STRING[i], i);
|
|
||||||
notation[counter] = i;
|
|
||||||
counter++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(counter == 0) break;
|
if(counter == 0) break;
|
||||||
|
|
||||||
|
// Compare subsequent tokens to available registers.
|
||||||
for(int i = 0; i < 32; i++) {
|
for(int i = 0; i < 32; i++) {
|
||||||
if(strcmp(token, REGISTER_STRING[i]) == 0) {
|
if(strcmp(token, REGISTER_STRING[i]) == 0) {
|
||||||
printf("found a match between %s and %s, value is %d\n", token, REGISTER_STRING[i], i);
|
|
||||||
notation[counter] = i;
|
notation[counter] = i;
|
||||||
counter++;
|
counter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("%s ", token);
|
||||||
token = strtok(NULL, " ");
|
token = strtok(NULL, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return notation;
|
return notation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ int initParse(char * filepath) {
|
|||||||
file = fopen(filepath, "r");
|
file = fopen(filepath, "r");
|
||||||
|
|
||||||
// Maximum number of characters in a line is 1024.
|
// Maximum number of characters in a line is 1024.
|
||||||
char lines[1024];
|
char lines[256];
|
||||||
|
|
||||||
// Catch if the file does not exist/cannot be opened.
|
// Catch if the file does not exist/cannot be opened.
|
||||||
if(file == NULL) {
|
if(file == NULL) {
|
||||||
@@ -104,13 +105,11 @@ int initParse(char * filepath) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get each line of the file, remove comments and whitespace, and attempt to parse
|
// Get each line of the file, remove comments and whitespace, and attempt to parse
|
||||||
while(fgets(lines, sizeof(lines), file)) {
|
while(fgets(lines, sizeof(lines), file)) {
|
||||||
char * line = removeCommentsAndWhiteSpace(lines);
|
char * line = removeCommentsAndWhiteSpace(lines);
|
||||||
int * notation = parseIntoNotation(line);
|
int * notation = parseIntoNotation(line);
|
||||||
|
|
||||||
printf("notation: %d %d %d %d\n", notation[0], notation[1], notation[2], notation[3]);
|
|
||||||
free(notation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
Reference in New Issue
Block a user