From c1803336d1f1db722f76856d8395beef6b2688b0 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Sat, 10 Oct 2015 14:02:49 +0200 Subject: [PATCH 01/15] edited AUTHORS --- AUTHORS | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index f8c27e6..b024818 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,2 @@ -Martin Aigner -Christian Barthel -Christoph Kirsch -Michael Lippautz -Simone Oblasser \ No newline at end of file +Tobias Seiler +Johannes Vollmer \ No newline at end of file From 626aa192e7a861b9a47e9d56f55435b7726275c5 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Thu, 15 Oct 2015 19:31:49 +0200 Subject: [PATCH 02/15] fulfilled assignment0: added a linked list --- selfie.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/selfie.c b/selfie.c index c2b5d87..e9e0d56 100755 --- a/selfie.c +++ b/selfie.c @@ -4104,6 +4104,207 @@ int* copyC2CStarArguments(int argc, int *argv) { return cstar_argv; } +///////////////////////////////////////////////////////////////////// +//////------Assignment 0: Implementation of a Linked List------////// +///////////////////////////////////////////////////////////////////// + +// Initialization of the linked list (Creating the header with data -1) +// The header cannot be deleted!! +int* initializeList(int *list) { + int *header; + int data = -1; // no data inserted + + header = malloc(4*2); + *header = 0; + *(header+1) = data; + return header; +} + +// Add a node to the linked list at the bottom +int* addToList(int *list, int data) { + + int *newNode; + newNode = malloc(4*2); + *newNode = list; + *(newNode+1) = data; + return newNode; +} + +// Iterate through the linked list and get the nth node of the list +int* getNodeFromList(int* list, int nthNode) { + + while(nthNode > 0) { + list = *list; + nthNode = nthNode - 1; + } + + return list; +} + +// Iterate through the linked list and get the data of the nth node of the list +int getDataFromList(int* list, int nthNode) { + + while(nthNode > 0) { + list = *list; + nthNode = nthNode - 1; + } + + return *(list+1); +} + +// Iterate through the linked list and set the data of the nth node of the list +int alterDataInList(int* list, int nthNode, int newValue) { + + while(nthNode > 0) { + list = *list; + nthNode = nthNode - 1; + } + + *(list+1) = newValue; + + return *(list+1); +} + + +// Get the size of the linked list +int sizeOfList(int* list) { + + int *count; + count = malloc(4); + *count = 0; + + while(*list != 0) { + list = *list; + *count = *count + 1; + } + return *count; +} + +// Delete a node from the linked list from the top +int* deleteFirstNodeFromList(int* list) { + + int *prev; + int *next; + prev = malloc(2*4); + next = malloc(2*4); + *prev = 0; + *next = 0; + int size = sizeOfList(list); + + prev = getNodeFromList(list, size-2); + next = getNodeFromList(list, size); + *prev = next; + + return list; +} + +// Sort the list with Bubble Sort +int* sortList(int* list) { + + int size = sizeOfList(list); + while(size > 1){ + int i = 0; + while(i= 0) { + int number = getDataFromList(list, *counter); + int *Buffer = (int*)malloc(4*10); + print(itoa( number, Buffer, 10, 0)); + putchar(CHAR_LF); + *counter = *counter - 1; + } + +} + +int testList() { + + int *list; + // Create new linked list (FIFO Linked List): + // top -> [9,7,8,2,4,1,5,3] -> bottom + printString('I','n','s','e','r','t',' ','i','n','t','o',' ','l','i','s','t',CHAR_LF,0,0,0); + list = initializeList(list); + list = addToList(list, 9); + list = addToList(list, 7); + list = addToList(list, 8); + list = addToList(list, 2); + list = addToList(list, 4); + list = addToList(list, 1); + list = addToList(list, 5); + list = addToList(list, 3); + printList(list); + + // Delete the first node (FIFO Linked List): + // top -> [2,4,1,5,3] -> bottom + printString('D','e','l','e','t','e',' ','f','i','r','s','t',' ','n','o','d','e',CHAR_LF,0,0); + list = deleteFirstNodeFromList(list); + list = deleteFirstNodeFromList(list); + list = deleteFirstNodeFromList(list); + printList(list); + + // Sorting the list + // top -> [5,4,3,2,1] -> bottom + printString('S','o','r','t','i','n','g',' ','t','h','e',' ','l','i','s','t',CHAR_LF,0,0,0); + list = sortList(list); + printList(list); + + exit(0); +} + +int main(int argc, int *argv) { + int *cstar_argv; + int *firstParameter; + + initLibrary(); + + initRegister(); + initDecoder(); + initSyscalls(); + + cstar_argv = copyC2CStarArguments(argc, argv); + + if (argc > 1) { + firstParameter = (int*) (*(cstar_argv+1)); + + if (*firstParameter == '-') { + if (*(firstParameter+1) == 'c') + main_compiler(); + else if (*(firstParameter+1) == 'm') { + if (argc > 3) + main_emulator(argc, argv, cstar_argv); + else + exit(-1); + } + else { + exit(-1); + } + } else { + exit(-1); + } + } else + // default: compiler + //main_compiler(); + testList(); +} + int main(int argc, int *argv) { int *cstar_argv; int *firstParameter; From d19bb1d8524620fd8fea960dc4add6301debd5b6 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Mon, 19 Oct 2015 13:55:48 +0200 Subject: [PATCH 03/15] - added description for assignment01 --- selfie.c | 66 ++++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/selfie.c b/selfie.c index e9e0d56..f289b1e 100755 --- a/selfie.c +++ b/selfie.c @@ -4105,9 +4105,21 @@ int* copyC2CStarArguments(int argc, int *argv) { } ///////////////////////////////////////////////////////////////////// -//////------Assignment 0: Implementation of a Linked List------////// +//////-----------Assignment 0: Basic data structures-----------////// ///////////////////////////////////////////////////////////////////// +//Review linked lists and implement a simple program using a singly linked list in C*. The minimal requirements are as follows: +// +//must be implemented in C* +//must compile with selfie +//must run on selfie +//the list must be dynamically allocated +//every node must be dynamically allocated +//inserting nodes to the list and removing nodes from the list +//list iteration +//Bonus: sort the list. Any way you like +//Deadline: Oct 15, end of day + // Initialization of the linked list (Creating the header with data -1) // The header cannot be deleted!! int* initializeList(int *list) { @@ -4269,41 +4281,24 @@ int testList() { exit(0); } -int main(int argc, int *argv) { - int *cstar_argv; - int *firstParameter; - - initLibrary(); - - initRegister(); - initDecoder(); - initSyscalls(); +///////////////////////////////////////////////////////////////////// +//////-Assignment 1: Loading, scheduling, switching, execution-////// +///////////////////////////////////////////////////////////////////// - cstar_argv = copyC2CStarArguments(argc, argv); +//Implement basic concurrent execution of n processes in mipster. n >= 2 +// +//understand how mipster interprets and executes binary instructions. Tipp: add your own comments to the code +//mipster maintains a local state for a process (running executable), e.g., pc, registers, memory +//understand the purpose of each variable and data structure +//duplicate the process state n times +//running mipster like: ./selfie -m 32 yourbinary should generate n instances of yourbinary in a single instance of mipster +//implement preemptive multitasking, i.e., switching between the n instances of yourbinary is determined by mipster +//switch processes every m instructions. 1 <= m <= number of instructions in yourbinary +//implement round-robin scheduling +//add some output in yourbinary to demonstrate context switching +//Deadline: Oct 22, end of day - if (argc > 1) { - firstParameter = (int*) (*(cstar_argv+1)); - if (*firstParameter == '-') { - if (*(firstParameter+1) == 'c') - main_compiler(); - else if (*(firstParameter+1) == 'm') { - if (argc > 3) - main_emulator(argc, argv, cstar_argv); - else - exit(-1); - } - else { - exit(-1); - } - } else { - exit(-1); - } - } else - // default: compiler - //main_compiler(); - testList(); -} int main(int argc, int *argv) { int *cstar_argv; @@ -4337,5 +4332,6 @@ int main(int argc, int *argv) { } } else // default: compiler - main_compiler(); -} + //main_compiler(); + testList(); +} \ No newline at end of file From 267106c11187f023702ee5914b81eebcf2d6bf3b Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Mon, 19 Oct 2015 13:57:37 +0200 Subject: [PATCH 04/15] - fixed AUTHORS --- AUTHORS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AUTHORS b/AUTHORS index b024818..7d19ede 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,7 @@ +Martin Aigner +Christian Barthel +Christoph Kirsch +Michael Lippautz +Simone Oblasser Tobias Seiler Johannes Vollmer \ No newline at end of file From 487fd6bc43e6f8962656cd256e5e3bd7430c665a Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Tue, 20 Oct 2015 13:46:55 +0200 Subject: [PATCH 05/15] - added flag to start linked list --- selfie.c | 41 ++++++----------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/selfie.c b/selfie.c index f289b1e..8c5fe2e 100755 --- a/selfie.c +++ b/selfie.c @@ -4105,21 +4105,9 @@ int* copyC2CStarArguments(int argc, int *argv) { } ///////////////////////////////////////////////////////////////////// -//////-----------Assignment 0: Basic data structures-----------////// +//////------Assignment 0: Implementation of a Linked List------////// ///////////////////////////////////////////////////////////////////// -//Review linked lists and implement a simple program using a singly linked list in C*. The minimal requirements are as follows: -// -//must be implemented in C* -//must compile with selfie -//must run on selfie -//the list must be dynamically allocated -//every node must be dynamically allocated -//inserting nodes to the list and removing nodes from the list -//list iteration -//Bonus: sort the list. Any way you like -//Deadline: Oct 15, end of day - // Initialization of the linked list (Creating the header with data -1) // The header cannot be deleted!! int* initializeList(int *list) { @@ -4281,25 +4269,6 @@ int testList() { exit(0); } -///////////////////////////////////////////////////////////////////// -//////-Assignment 1: Loading, scheduling, switching, execution-////// -///////////////////////////////////////////////////////////////////// - -//Implement basic concurrent execution of n processes in mipster. n >= 2 -// -//understand how mipster interprets and executes binary instructions. Tipp: add your own comments to the code -//mipster maintains a local state for a process (running executable), e.g., pc, registers, memory -//understand the purpose of each variable and data structure -//duplicate the process state n times -//running mipster like: ./selfie -m 32 yourbinary should generate n instances of yourbinary in a single instance of mipster -//implement preemptive multitasking, i.e., switching between the n instances of yourbinary is determined by mipster -//switch processes every m instructions. 1 <= m <= number of instructions in yourbinary -//implement round-robin scheduling -//add some output in yourbinary to demonstrate context switching -//Deadline: Oct 22, end of day - - - int main(int argc, int *argv) { int *cstar_argv; int *firstParameter; @@ -4324,6 +4293,9 @@ int main(int argc, int *argv) { else exit(-1); } + else if (*(firstParameter+1) == 'l') { + testList(); + } else { exit(-1); } @@ -4332,6 +4304,5 @@ int main(int argc, int *argv) { } } else // default: compiler - //main_compiler(); - testList(); -} \ No newline at end of file + main_compiler(); +} From 6915a691bb99fa068e62a1f72cb748c983eb13a7 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Tue, 20 Oct 2015 13:56:30 +0200 Subject: [PATCH 06/15] - fixed allocation of "count" --- selfie.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/selfie.c b/selfie.c index 8c5fe2e..8691b2c 100755 --- a/selfie.c +++ b/selfie.c @@ -4169,15 +4169,14 @@ int alterDataInList(int* list, int nthNode, int newValue) { // Get the size of the linked list int sizeOfList(int* list) { - int *count; - count = malloc(4); - *count = 0; + int count; + count = 0; while(*list != 0) { list = *list; - *count = *count + 1; + count = count + 1; } - return *count; + return count; } // Delete a node from the linked list from the top @@ -4294,7 +4293,7 @@ int main(int argc, int *argv) { exit(-1); } else if (*(firstParameter+1) == 'l') { - testList(); + testList(); } else { exit(-1); From 8f1af44fde9495d4b84cd7abcd1cc43a69c1a426 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Tue, 20 Oct 2015 14:22:43 +0200 Subject: [PATCH 07/15] - fixed duplicate of getNodeFromList and getDataFromList --- selfie.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/selfie.c b/selfie.c index 8691b2c..1b4410b 100755 --- a/selfie.c +++ b/selfie.c @@ -4131,7 +4131,7 @@ int* addToList(int *list, int data) { } // Iterate through the linked list and get the nth node of the list -int* getNodeFromList(int* list, int nthNode) { +int getNodeFromList(int *list, int nthNode) { while(nthNode > 0) { list = *list; @@ -4141,19 +4141,8 @@ int* getNodeFromList(int* list, int nthNode) { return list; } -// Iterate through the linked list and get the data of the nth node of the list -int getDataFromList(int* list, int nthNode) { - - while(nthNode > 0) { - list = *list; - nthNode = nthNode - 1; - } - - return *(list+1); -} - // Iterate through the linked list and set the data of the nth node of the list -int alterDataInList(int* list, int nthNode, int newValue) { +int alterDataInList(int *list, int nthNode, int newValue) { while(nthNode > 0) { list = *list; @@ -4167,7 +4156,7 @@ int alterDataInList(int* list, int nthNode, int newValue) { // Get the size of the linked list -int sizeOfList(int* list) { +int sizeOfList(int *list) { int count; count = 0; @@ -4180,7 +4169,7 @@ int sizeOfList(int* list) { } // Delete a node from the linked list from the top -int* deleteFirstNodeFromList(int* list) { +int* deleteFirstNodeFromList(int *list) { int *prev; int *next; @@ -4198,15 +4187,18 @@ int* deleteFirstNodeFromList(int* list) { } // Sort the list with Bubble Sort -int* sortList(int* list) { +int* sortList(int *list) { int size = sizeOfList(list); while(size > 1){ int i = 0; - while(i= 0) { - int number = getDataFromList(list, *counter); + int *nodeNumber = getNodeFromList(list, *counter); + int number = *(nodeNumber+1); int *Buffer = (int*)malloc(4*10); print(itoa( number, Buffer, 10, 0)); putchar(CHAR_LF); From 2dce0f09b56f63ec3c8feab72f4c1c319ea96ba5 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Tue, 20 Oct 2015 14:37:47 +0200 Subject: [PATCH 08/15] - added comments --- selfie.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/selfie.c b/selfie.c index 1b4410b..76a0530 100755 --- a/selfie.c +++ b/selfie.c @@ -4104,9 +4104,18 @@ int* copyC2CStarArguments(int argc, int *argv) { return cstar_argv; } -///////////////////////////////////////////////////////////////////// -//////------Assignment 0: Implementation of a Linked List------////// -///////////////////////////////////////////////////////////////////// +//// Assignment 0: Basic data structures //// +//Review linked lists and implement a simple program using a singly linked list in C*. The minimal requirements are as follows: +// +//must be implemented in C* +//must compile with selfie +//must run on selfie +//the list must be dynamically allocated +//every node must be dynamically allocated +//inserting nodes to the list and removing nodes from the list +//list iteration +//Bonus: sort the list. Any way you like +//Deadline: Oct 15, end of day // Initialization of the linked list (Creating the header with data -1) // The header cannot be deleted!! @@ -4141,20 +4150,6 @@ int getNodeFromList(int *list, int nthNode) { return list; } -// Iterate through the linked list and set the data of the nth node of the list -int alterDataInList(int *list, int nthNode, int newValue) { - - while(nthNode > 0) { - list = *list; - nthNode = nthNode - 1; - } - - *(list+1) = newValue; - - return *(list+1); -} - - // Get the size of the linked list int sizeOfList(int *list) { @@ -4199,8 +4194,8 @@ int* sortList(int *list) { int y = *(listitemY+1); if(x < y) { - alterDataInList(list, i, y); - alterDataInList(list, i+1, x); + *(listitemX + 1) = y; + *(listitemY + 1) = x; } i = i + 1; } @@ -4261,6 +4256,19 @@ int testList() { exit(0); } +//// Assignment 1: Loading, scheduling, switching, execution //// +//Implement basic concurrent execution of n processes in mipster. n >= 2 +//understand how mipster interprets and executes binary instructions. Tipp: add your own comments to the code +//mipster maintains a local state for a process (running executable), e.g., pc, registers, memory +//understand the purpose of each variable and data structure +//duplicate the process state n times +//running mipster like: ./selfie -m 32 yourbinary should generate n instances of yourbinary in a single instance of mipster +//implement preemptive multitasking, i.e., switching between the n instances of yourbinary is determined by mipster +//switch processes every m instructions. 1 <= m <= number of instructions in yourbinary +//implement round-robin scheduling +//add some output in yourbinary to demonstrate context switching +//Deadline: Oct 22, end of day + int main(int argc, int *argv) { int *cstar_argv; int *firstParameter; From 959287a5cfa4f9c246dc29607bf3629ef357c866 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Thu, 22 Oct 2015 20:23:02 +0200 Subject: [PATCH 09/15] - added assignment01 --- selfie.c | 444 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 351 insertions(+), 93 deletions(-) diff --git a/selfie.c b/selfie.c index 76a0530..3e1ff5b 100755 --- a/selfie.c +++ b/selfie.c @@ -3463,6 +3463,20 @@ void emitPutchar() { // ------------------------- INSTRUCTIONS -------------------------- // ----------------------------------------------------------------- +// ------------------------ GLOBAL VARIABLES ----------------------------------- +// ready queue +int* ready_queue; +// number of instructions for one process in one run +int numb_of_instr; +// getting maximal memory size +int MAX_MEM; +// Address of the actual running thread +int* running_process; + +void printList(int *list); +void printListPC(int *list); +void schedule_and_switch(); + void fct_syscall() { if (debug_disassemble) { print((int*)(*(fct_strings+function))); @@ -3931,6 +3945,12 @@ void execute() { } void run() { + int instr; + int* nextprocess; + int *Buffer; + Buffer = (int*)malloc(4*10); + + instr = 0; while (1) { fetch(); @@ -3938,6 +3958,16 @@ void run() { pre_debug(); execute(); post_debug(); + + instr = instr + 1; + *(running_process+1) = *(running_process+1) + 1; + + if(instr == numb_of_instr){ + //round robin scheduling and switching the running process + schedule_and_switch(); + instr = 0; + } + } } @@ -3955,6 +3985,8 @@ int* parse_args(int argc, int *argv, int *cstar_argv) { memorySize = atoi((int*)*(cstar_argv+2)) * 1024 * 1024 / 4; + MAX_MEM = memorySize; + allocateMachineMemory(memorySize*4); // initialize stack pointer @@ -4044,66 +4076,6 @@ void up_copyArguments(int argc, int *argv) { } } -int main_emulator(int argc, int *argv, int *cstar_argv) { - initInterpreter(); - - *(registers+REG_GP) = loadBinary(parse_args(argc, argv, cstar_argv)); - - *(registers+REG_K1) = *(registers+REG_GP); - - up_copyArguments(argc-3, argv+3); - - run(); - - exit(0); -} - -// ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ -// ----------------------------------------------------------------- - -int* copyC2CStarString(int* s) { - int l; - int *r; - int i; - - l = CStringLength(s); - - r = malloc((l + 1) * 4); - - i = 0; - - while (i <= l) { - *(r+i) = rightShift(leftShift(*s, 24 - (i % 4) * 8), 24); - - i = i + 1; - - if (i % 4 == 0) - s = s + 1; - } - - return r; -} - -int* copyC2CStarArguments(int argc, int *argv) { - int *cstar_argv; - int *cursor; - - cstar_argv = malloc(argc * 4); - - cursor = cstar_argv; - - while (argc > 0) { - *cursor = (int)copyC2CStarString((int*)*argv); - - argv = argv + 1; - cursor = cursor + 1; - argc = argc - 1; - } - - return cstar_argv; -} - //// Assignment 0: Basic data structures //// //Review linked lists and implement a simple program using a singly linked list in C*. The minimal requirements are as follows: // @@ -4121,11 +4093,10 @@ int* copyC2CStarArguments(int argc, int *argv) { // The header cannot be deleted!! int* initializeList(int *list) { int *header; - int data = -1; // no data inserted + int data; header = malloc(4*2); *header = 0; - *(header+1) = data; return header; } @@ -4134,7 +4105,7 @@ int* addToList(int *list, int data) { int *newNode; newNode = malloc(4*2); - *newNode = list; + *newNode = (int) list; *(newNode+1) = data; return newNode; } @@ -4143,11 +4114,11 @@ int* addToList(int *list, int data) { int getNodeFromList(int *list, int nthNode) { while(nthNode > 0) { - list = *list; + list = (int*) *list; nthNode = nthNode - 1; } - return list; + return (int) list; } // Get the size of the linked list @@ -4157,7 +4128,7 @@ int sizeOfList(int *list) { count = 0; while(*list != 0) { - list = *list; + list = (int*) *list; count = count + 1; } return count; @@ -4168,15 +4139,16 @@ int* deleteFirstNodeFromList(int *list) { int *prev; int *next; + int size; prev = malloc(2*4); next = malloc(2*4); *prev = 0; *next = 0; - int size = sizeOfList(list); + size = sizeOfList(list); - prev = getNodeFromList(list, size-2); - next = getNodeFromList(list, size); - *prev = next; + prev = (int*) getNodeFromList(list, size-2); + next = (int*) getNodeFromList(list, size); + *prev = (int) next; return list; } @@ -4184,18 +4156,26 @@ int* deleteFirstNodeFromList(int *list) { // Sort the list with Bubble Sort int* sortList(int *list) { - int size = sizeOfList(list); + int size; + int i; + int *listitemX; + int *listitemY; + int x; + int y; + + size = sizeOfList(list); + while(size > 1){ - int i = 0; + i = 0; while(i < size-1) { - int *listitemX = getNodeFromList(list, i); - int *listitemY = getNodeFromList(list, i+1); - int x = *(listitemX+1); - int y = *(listitemY+1); + listitemX = (int*) getNodeFromList(list, i); + listitemY = (int*) getNodeFromList(list, i+1); + x = *(listitemX+1); + y = *(listitemY+1); if(x < y) { - *(listitemX + 1) = y; - *(listitemY + 1) = x; + *(listitemX + 1) = y; + *(listitemY + 1) = x; } i = i + 1; } @@ -4207,22 +4187,25 @@ int* sortList(int *list) { // Print the linked list void printList(int *list) { - int *counter; - counter = malloc(4); - *counter = sizeOfList(list); - - while(*counter >= 0) { - int *nodeNumber = getNodeFromList(list, *counter); - int number = *(nodeNumber+1); - int *Buffer = (int*)malloc(4*10); - print(itoa( number, Buffer, 10, 0)); + int counter; + int *nodeNumber; + int number; + int *Buffer; + + counter = sizeOfList(list)-1; + + while(counter >= 0) { + nodeNumber = (int*) getNodeFromList(list, counter); + number = *(nodeNumber+1); + Buffer = (int*)malloc(4*10); + print(itoa(number, Buffer, 10, 0)); putchar(CHAR_LF); - *counter = *counter - 1; + counter = counter - 1; } - } -int testList() { +//Testing for Assignment 00 +int test00() { int *list; // Create new linked list (FIFO Linked List): @@ -4269,6 +4252,278 @@ int testList() { //add some output in yourbinary to demonstrate context switching //Deadline: Oct 22, end of day +// ------------------------ DATA STRUCTURE FOR A PROCESS ----------------------- +// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), +// Address to the Register (new_reg), Address to the Memory (new_mem), +// hi register for multiplication/division (new_reg_hi) and +// lo register for multiplication/division (new_reg_lo) and +int* create_process(int new_pid, int* new_reg, int* new_mem, int new_reg_hi, int new_reg_lo){ + //initialization of the process + int* process; + //memory allocation + process = malloc (6 * 4); + + //initalization of the argments of the process + *process = new_pid; + *(process+1) = 0; + *(process+2) = (int) new_reg; + *(process+3) = (int) new_mem; + *(process+4) = new_reg_hi; + *(process+5) = new_reg_lo; + + return process; +} + +// ------------------------ READY QUEUE ---------------------------------------- +// Creating a Ready queue with n processes and with m as number of instructions +void create_ready_queue(int n, int m){ + + int *new_process; + int pid; + int *new_reg; + int *new_mem; + + numb_of_instr = m; + pid = 0; + ready_queue = initializeList(ready_queue); + + while(pid < n){ + new_reg = malloc(4*32); + new_mem = malloc(4*MAX_MEM); + if(pid ==0){ + running_process = create_process(pid, new_reg, new_mem, reg_hi, reg_lo); + } + else{ + new_process = create_process(pid, new_reg, new_mem, reg_hi, reg_lo); + ready_queue = addToList(ready_queue, new_process); + } + pid = pid + 1; + } +} + +void printListPID(int *list) { + int counter; + int number; + int *Buffer; + int *node; + int *process; + + counter = sizeOfList(list)-1; + + while(counter >= 0) { + node = (int*) getNodeFromList(list, counter); + process = *(node+1); + number = *(process); + Buffer = (int*)malloc(4*10); + print(itoa(number, Buffer, 10, 0)); + putchar(CHAR_LF); + counter = counter - 1; + } + +} + +// Print the value of the Program counters +void printListPC(int *list) { + + int counter; + int number; + int *Buffer; + int *node; + int *process; + + counter = sizeOfList(list)-1; + + while(counter >= 0) { + node = (int*) getNodeFromList(list, counter); + process = *(node+1); + number = *(process+1); + Buffer = (int*)malloc(4*10); + print(itoa(number, Buffer, 10, 0)); + putchar(CHAR_LF); + counter = counter - 1; + } + +} + +void schedule_and_switch(){ + int size; + int *node; + size = sizeOfList(ready_queue); + //if the ready queue is empty, the running process can continue + if(size == 0){ + printString('e','m','p','t','y','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + return; + } + //else the processes have to be switched so that the next process from the ready queue is allowed to run + else{ + // 1. Saving the states of the running process in the ready queue + ready_queue = addToList(ready_queue, running_process); + // 2. Switching the running process and get the first of the ready queue + node = getNodeFromList(ready_queue, size-1); + running_process = *(node+1); + + // 3. Delete the first Process from ready queue because it is the running process + ready_queue = deleteFirstNodeFromList(ready_queue); + } +} + +void runtest() { + int* nextprocess; + int instr; + int *Buffer; + + instr = 0; + Buffer = (int*)malloc(4*10); + + while (1) { + instr = instr + 1; + *(running_process+1) = *(running_process+1) + 1; + + if(instr == numb_of_instr){ + //round robin scheduling and switching the running process + + //Printing the Ready queue and the running process + printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + putchar(CHAR_LF); + printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + putchar(CHAR_LF); + printString('R','e','a','d','y','Q','u','e','u','e',' ','a','f','t','e','r',' ','R','u','n'); + printString('n','i','n','g',' ', 'P','r','o','c','e','s','s',CHAR_LF,0,0,0,0,0,0,0); + printString('P','I','D','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printListPID(ready_queue); + printString('P','C','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printListPC(ready_queue); + printString('N','e','w',' ','R','u','n','n','i','n','g',' ','P','r','o','c','e','s','s',CHAR_LF); + printString('P','I','D',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print(itoa(*(running_process), Buffer, 10, 0)); + putchar(CHAR_LF); + printString('P','C',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print(itoa(*(running_process+1), Buffer, 10, 0)); + putchar(CHAR_LF); + schedule_and_switch(); + instr = 0; + + //Printing the Ready queue and the running process + printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + putchar(CHAR_LF); + printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + putchar(CHAR_LF); + printString('R','e','a','d','y','Q','u','e','u','e',' ','a','f','t','e','r',' ','S','w','i'); + printString('t','c','h','i','n','g',' ', 'P','r','o','c','e','s','s',CHAR_LF,0,0,0,0,0); + printString('P','I','D','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printListPID(ready_queue); + printString('P','C','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printListPC(ready_queue); + printString('N','e','w',' ','R','u','n','n','i','n','g',' ','P','r','o','c','e','s','s',CHAR_LF); + printString('P','I','D',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print(itoa(*(running_process), Buffer, 10, 0)); + putchar(CHAR_LF); + printString('P','C',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print(itoa(*(running_process+1), Buffer, 10, 0)); + putchar(CHAR_LF); + } + } +} + +//Testing for Assignment 01 +int test01() { + + int *Buffer; + + create_ready_queue(5,100000000); + + Buffer = (int*)malloc(4*10); + + printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + putchar(CHAR_LF); + printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + putchar(CHAR_LF); + //Printing the Ready Queue after the creation (PID's and PC's) + printString('R','e','a','d','y','Q','u','e','u','e',' ','a','f','t','e','r',' ','C','r','e'); + printString('a','t','i','o','n',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printString('P','I','D','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printListPID(ready_queue); + printString('P','C','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + printListPC(ready_queue); + + //Printing the PID and the PC of the running Process + printString('R','u','n','n','i','n','g',' ','P','r','o','c','e','s','s',CHAR_LF,0,0,0,0); + printString('P','I','D',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print(itoa(*(running_process), Buffer, 10, 0)); + putchar(CHAR_LF); + printString('P','C',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print(itoa(*(running_process+1), Buffer, 10, 0)); + putchar(CHAR_LF); + + //Testversion of run of the Emulator + runtest(); + + exit(0); +} + +int main_emulator(int argc, int *argv, int *cstar_argv) { + initInterpreter(); + + *(registers+REG_GP) = loadBinary(parse_args(argc, argv, cstar_argv)); + + *(registers+REG_K1) = *(registers+REG_GP); + + up_copyArguments(argc-3, argv+3); + + //create a ready queue and 5 processes + create_ready_queue(5,10); + + run(); + + exit(0); +} + +// ----------------------------------------------------------------- +// ----------------------------- MAIN ------------------------------ +// ----------------------------------------------------------------- + +int* copyC2CStarString(int* s) { + int l; + int *r; + int i; + + l = CStringLength(s); + + r = malloc((l + 1) * 4); + + i = 0; + + while (i <= l) { + *(r+i) = rightShift(leftShift(*s, 24 - (i % 4) * 8), 24); + + i = i + 1; + + if (i % 4 == 0) + s = s + 1; + } + + return r; +} + +int* copyC2CStarArguments(int argc, int *argv) { + int *cstar_argv; + int *cursor; + + cstar_argv = malloc(argc * 4); + + cursor = cstar_argv; + + while (argc > 0) { + *cursor = (int)copyC2CStarString((int*)*argv); + + argv = argv + 1; + cursor = cursor + 1; + argc = argc - 1; + } + + return cstar_argv; +} + int main(int argc, int *argv) { int *cstar_argv; int *firstParameter; @@ -4293,8 +4548,11 @@ int main(int argc, int *argv) { else exit(-1); } - else if (*(firstParameter+1) == 'l') { - testList(); + else if (*(firstParameter+1) == '0') { + test00(); + } + else if (*(firstParameter+1) == '1') { + test01(); } else { exit(-1); @@ -4305,4 +4563,4 @@ int main(int argc, int *argv) { } else // default: compiler main_compiler(); -} +} \ No newline at end of file From 95419696f554aaa20bc700e1768a61db362df18b Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Tue, 27 Oct 2015 13:52:26 +0100 Subject: [PATCH 10/15] - fixed a problem which caused starting the second process in queue instead of the first one --- selfie.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/selfie.c b/selfie.c index 3e1ff5b..f251ee3 100755 --- a/selfie.c +++ b/selfie.c @@ -4295,7 +4295,7 @@ void create_ready_queue(int n, int m){ } else{ new_process = create_process(pid, new_reg, new_mem, reg_hi, reg_lo); - ready_queue = addToList(ready_queue, new_process); + ready_queue = addToList(ready_queue, (int) new_process); } pid = pid + 1; } @@ -4312,7 +4312,7 @@ void printListPID(int *list) { while(counter >= 0) { node = (int*) getNodeFromList(list, counter); - process = *(node+1); + process = (int*) *(node+1); number = *(process); Buffer = (int*)malloc(4*10); print(itoa(number, Buffer, 10, 0)); @@ -4335,7 +4335,7 @@ void printListPC(int *list) { while(counter >= 0) { node = (int*) getNodeFromList(list, counter); - process = *(node+1); + process = (int*) *(node+1); number = *(process+1); Buffer = (int*)malloc(4*10); print(itoa(number, Buffer, 10, 0)); @@ -4357,10 +4357,10 @@ void schedule_and_switch(){ //else the processes have to be switched so that the next process from the ready queue is allowed to run else{ // 1. Saving the states of the running process in the ready queue - ready_queue = addToList(ready_queue, running_process); + ready_queue = addToList(ready_queue, (int) running_process); // 2. Switching the running process and get the first of the ready queue - node = getNodeFromList(ready_queue, size-1); - running_process = *(node+1); + node = (int*) getNodeFromList(ready_queue, size); + running_process = (int*) *(node+1); // 3. Delete the first Process from ready queue because it is the running process ready_queue = deleteFirstNodeFromList(ready_queue); @@ -4563,4 +4563,4 @@ int main(int argc, int *argv) { } else // default: compiler main_compiler(); -} \ No newline at end of file +} From 05ca09933d9ba260ca8dfbecf382024cedaf7294 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Thu, 29 Oct 2015 20:10:59 +0100 Subject: [PATCH 11/15] - added assignment2 --- selfie.c | 4049 +++++++++++++++++++++++++++++------------------------- 1 file changed, 2211 insertions(+), 1838 deletions(-) diff --git a/selfie.c b/selfie.c index f251ee3..ec32477 100755 --- a/selfie.c +++ b/selfie.c @@ -80,39 +80,53 @@ int leftShift(int n, int b); int rightShift(int n, int b); int stringLength(int *s); -void reverseString(int *s); +void stringReverse(int *s); int stringCompare(int *s, int *t); + int atoi(int *s); int* itoa(int n, int *s, int b, int a); + void print(int *s); -void assignString(int *s, int c0, int c1, int c2, int c3, int c4, - int c5, int c6, int c7, int c8, int c9, - int c10, int c11, int c12, int c13, int c14, - int c15, int c16, int c17, int c18, int c19); -int* createString(int c0, int c1, int c2, int c3, int c4, - int c5, int c6, int c7, int c8, int c9, - int c10, int c11, int c12, int c13, int c14, - int c15, int c16, int c17, int c18, int c19); -void printString(int c0, int c1, int c2, int c3, int c4, - int c5, int c6, int c7, int c8, int c9, - int c10, int c11, int c12, int c13, int c14, - int c15, int c16, int c17, int c18, int c19); -void memset(int *a, int size, int v); +void println(); + +void printCharacter(int character); +void printString(int *s); void exit(int code); int* malloc(int size); // ------------------------ GLOBAL CONSTANTS ----------------------- +int CHAR_EOF = -1; // end of file +int CHAR_TAB = 9; // ASCII code 9 = tabulator +int CHAR_LF = 10; // ASCII code 10 = line feed +int CHAR_CR = 13; // ASCII code 13 = carriage return +int CHAR_SPACE = ' '; +int CHAR_SEMICOLON = ';'; +int CHAR_PLUS = '+'; +int CHAR_DASH = '-'; +int CHAR_ASTERISK = '*'; +int CHAR_HASH = '#'; +int CHAR_SLASH = '/'; +int CHAR_UNDERSCORE = '_'; +int CHAR_EQUAL = '='; +int CHAR_LPARENTHESIS = '('; +int CHAR_RPARENTHESIS = ')'; +int CHAR_LBRACE = '{'; +int CHAR_RBRACE = '}'; +int CHAR_COMMA = ','; +int CHAR_LT = '<'; +int CHAR_GT = '>'; +int CHAR_EXCLAMATION = '!'; +int CHAR_PERCENTAGE = '%'; +int CHAR_SINGLEQUOTE = 39; // ASCII code 39 = ' +int CHAR_DOUBLEQUOTE = '"'; + int *power_of_two_table; int INT_MAX; // maximum numerical value of an integer int INT_MIN; // minimum numerical value of an integer -int CHAR_TAB; -int CHAR_LF; -int CHAR_CR; - int *string_buffer; // ------------------------- INITIALIZATION ------------------------ @@ -136,11 +150,8 @@ void initLibrary() { INT_MAX = (twoToThePowerOf(30) - 1) * 2 + 1; INT_MIN = -INT_MAX - 1; - CHAR_TAB = 9; // ASCII code 9 = tabulator - CHAR_LF = 10; // ASCII code 10 = linefeed - CHAR_CR = 13; // ASCII code 13 = carriage return - - string_buffer = malloc(33*4); + // accommodate 32-bit numbers for itoa + string_buffer = malloc(33); } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -155,342 +166,161 @@ void initLibrary() { void initScanner(); -int findNextCharacter(); +void printSymbol(int symbol); +void printLineNumber(int* message); + +void syntaxErrorMessage(int *message); +void syntaxErrorCharacter(int character); + int isCharacterWhitespace(); -int isCharacterLetterOrDigitOrUnderscore(); -int isCharacterDigit(); +int findNextCharacter(); int isCharacterLetter(); +int isCharacterDigit(); +int isCharacterLetterOrDigitOrUnderscore(); +int isNotDoubleQuoteOrEOF(); int identifierStringMatch(int stringIndex); int identifierOrKeyword(); int getSymbol(); -void syntaxWarn(int errCode); -void syntaxError(int errCode); - // ------------------------ GLOBAL CONSTANTS ----------------------- -int SYM_EOF; // end of file -int SYM_IDENTIFIER; // identifier -int SYM_INTEGER; // a number -int SYM_VOID; // VOID -int SYM_INT; // INT -int SYM_SEMICOLON; // ; -int SYM_IF; // IF -int SYM_ELSE; // ELSE -int SYM_PLUS; // + -int SYM_MINUS; // - -int SYM_ASTERISK; // * -int SYM_DIV; // / -int SYM_EQUAL; // == -int SYM_ASSIGN; // = -int SYM_LPARENTHESIS; // ( -int SYM_RPARENTHESIS; // ) -int SYM_LBRACE; // { -int SYM_RBRACE; // } -int SYM_WHILE; // WHILE -int SYM_RETURN; // RETURN -int SYM_COMMA; // , -int SYM_LT; // < -int SYM_LEQ; // <= -int SYM_GT; // > -int SYM_GEQ; // >= -int SYM_NOTEQ; // != -int SYM_MOD; // % -int SYM_CHARACTER; // char value - -int maxIdentifierLength; // maximum number of characters in an identifier -int maxIntegerLength; // maximum number of characters in an integer - -// Error-Token declaration -int ERR_EOF; -int ERR_UNKNOWN; -int ERR_EXPRESSION; -int ERR_TYPE; -int ERR_IDENTIFIER_OR_LPARENTHESIS; -int ERR_IDENTIFIER; -int ERR_ASSIGN; -int ERR_IDENTIFIER_OR_ASSIGN; -int ERR_IDENT_OR_CONST_OR_EXP; -int ERR_LBRACE_OR_SEMICOLON; -int ERR_PROCEDURE_OR_VARIABLE; -int ERR_UNDECLARED_VARIABLE; -int ERR_TYPE_MISMATCH; -int ERR_WRONG_RETURNTYPE; -int ERR_MAXCODELENGTH; -int ERR_MAXIDENTIFIERLENGTH; -int ERR_WRAPAROUND; -int ERR_STATEMENT; -int ERR_FILE_NOT_FOUND; -int ERR_ILLEGAL_DEREF; -int ERR_IDENTIFIER_OR_INTEGER; - -// strings for better error messages -int *error; -int *warning; -int *errNewline; -int *errLine; -int *errSymbol; -int *stringArray; +int SYM_EOF = -1; // end of file +int SYM_IDENTIFIER = 0; // identifier +int SYM_INTEGER = 1; // integer +int SYM_VOID = 2; // VOID +int SYM_INT = 3; // INT +int SYM_SEMICOLON = 4; // ; +int SYM_IF = 5; // IF +int SYM_ELSE = 6; // ELSE +int SYM_PLUS = 7; // + +int SYM_MINUS = 8; // - +int SYM_ASTERISK = 9; // * +int SYM_DIV = 10; // / +int SYM_EQUALITY = 11; // == +int SYM_ASSIGN = 12; // = +int SYM_LPARENTHESIS = 13; // ( +int SYM_RPARENTHESIS = 14; // ) +int SYM_LBRACE = 15; // { +int SYM_RBRACE = 16; // } +int SYM_WHILE = 17; // WHILE +int SYM_RETURN = 18; // RETURN +int SYM_COMMA = 19; // , +int SYM_LT = 20; // < +int SYM_LEQ = 21; // <= +int SYM_GT = 22; // > +int SYM_GEQ = 23; // >= +int SYM_NOTEQ = 24; // != +int SYM_MOD = 25; // % +int SYM_CHARACTER = 26; // character +int SYM_STRING = 27; // string + +int *SYMBOLS; // array of strings representing symbols + +int maxIdentifierLength = 64; // maximum number of characters in an identifier +int maxIntegerLength = 10; // maximum number of characters in an integer +int maxStringLength = 64; // maximum number of characters in a string // ------------------------ GLOBAL VARIABLES ----------------------- -int lineNumber; // Current Line Number for error reporting -int character; // most recently read character -int symbol; // most recently recognized symbol - -int *identifier; // stores scanned identifier -int *integer; // stores scanned integer as string - -int ivalue; // stores numerical value of scanned integer string - -int mayBeINTMINConstant; // support INT_MIN constant - -// ------------------------- INITIALIZATION ------------------------ - -void initScanner () { - SYM_EOF = -1; // end of file - SYM_IDENTIFIER = 0; // identifier - SYM_INTEGER = 1; // a number - SYM_VOID = 2; // VOID - SYM_INT = 3; // INT - SYM_SEMICOLON = 4; // ; - SYM_IF = 5; // IF - SYM_ELSE = 6; // ELSE - SYM_PLUS = 7; // + - SYM_MINUS = 8; // - - SYM_ASTERISK = 9; // * - SYM_DIV = 10; // / - SYM_EQUAL = 11; // == - SYM_ASSIGN = 12; // = - SYM_LPARENTHESIS = 13; // ( - SYM_RPARENTHESIS = 14; // ) - SYM_LBRACE = 15; // { - SYM_RBRACE = 16; // } - SYM_WHILE = 17; // WHILE - SYM_RETURN = 18; // RETURN - SYM_COMMA = 19; // , - SYM_LT = 20; // < - SYM_LEQ = 21; // <= - SYM_GT = 22; // > - SYM_GEQ = 23; // >= - SYM_NOTEQ = 24; // != - SYM_MOD = 25; // % - SYM_CHARACTER = 26; // character value - - maxIdentifierLength = 64; - maxIntegerLength = 10; - - ERR_EOF = 40; //keep this b/c -1 is no valid array index - ERR_UNKNOWN = 41; - ERR_EXPRESSION = 42; - ERR_TYPE = 43; - ERR_IDENTIFIER_OR_LPARENTHESIS = 44; - ERR_IDENTIFIER = 45; - ERR_ASSIGN = 46; - ERR_IDENTIFIER_OR_ASSIGN = 47; - ERR_IDENT_OR_CONST_OR_EXP = 48; - ERR_LBRACE_OR_SEMICOLON = 49; - ERR_PROCEDURE_OR_VARIABLE = 50; - ERR_UNDECLARED_VARIABLE = 51; - ERR_TYPE_MISMATCH = 52; - ERR_WRONG_RETURNTYPE = 53; - ERR_MAXCODELENGTH = 54; - ERR_MAXIDENTIFIERLENGTH = 55; - ERR_WRAPAROUND = 56; - ERR_STATEMENT = 57; - ERR_FILE_NOT_FOUND = 58; - ERR_ILLEGAL_DEREF = 59; - ERR_IDENTIFIER_OR_INTEGER = 60; - - // ------------ "ERROR: " ------------ - error = createString('E','R','R','O','R',':',' ',0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "WARNING: " ------------ - warning = createString('W','A','R','N','I','N','G',':',' ',0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "/n" ------------ - errNewline = createString(10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ ", line " ------------ - errLine = createString(',',' ','l','i','n','e',' ',0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ ", current symbol: " ------------ - errSymbol = createString(',',' ','c','u','r','r','e','n','t',' ','s','y','m','b','o','l',':',' ',0,0); - - // -------------------- ERROR TOKENS -------------------- - - stringArray = (int*)malloc(4*70); - - // ------------ "unknown" ------------ - *(stringArray + ERR_UNKNOWN) = (int)createString('u','n','k','n','o','w','n',0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "expression" ------------ - *(stringArray + ERR_EXPRESSION) = (int)createString('e','x','p','r','e','s','s','i','o','n',0,0,0,0,0,0,0,0,0,0); - - // ------------ "while" ------------ - *(stringArray + SYM_WHILE) = (int)createString('w','h','i','l','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "if" ------------ - *(stringArray + SYM_IF) = (int)createString('i','f',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "return" ------------ - *(stringArray + SYM_RETURN) = (int)createString('r','e','t','u','r','n',0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "type" ------------ - *(stringArray + ERR_TYPE) = (int)createString('t','y','p','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "(" ------------ - *(stringArray + SYM_LPARENTHESIS) = (int)createString('(',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ ")" ------------ - *(stringArray + SYM_RPARENTHESIS) = (int)createString(')',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "{" ------------ - *(stringArray + SYM_LBRACE) = (int)createString('{',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "}" ------------ - *(stringArray + SYM_RBRACE) = (int)createString('}',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ ";" ------------ - *(stringArray + SYM_SEMICOLON) = (int)createString(';',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "ident or (" ------------ - *(stringArray + ERR_IDENTIFIER_OR_LPARENTHESIS) = (int)createString('i','d','e','n','t',' ','o','r',' ','(',0,0,0,0,0,0,0,0,0,0); - - // ------------ "identifier" ------------ - *(stringArray + ERR_IDENTIFIER) = (int)createString('i','d','e','n','t','i','f','i','e','r',0,0,0,0,0,0,0,0,0,0); - - // ------------ "assign" ------------ - *(stringArray + ERR_ASSIGN) = (int)createString('a','s','s','i','g','n',0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "ident or assign" ------------ - *(stringArray + ERR_IDENTIFIER_OR_ASSIGN) = (int)createString('i','d','e','n','t',' ','o','r',' ','a','s','s','i','g','n',0,0,0,0,0); - - // ------------ "ident, const or exp" ------------ - *(stringArray + ERR_IDENT_OR_CONST_OR_EXP) = (int)createString('i','d','e','n','t',',',' ','c','o','n','s','t',' ','o','r',' ','e','x','p',0); - - // ------------ "( or ;" ------------ - *(stringArray + ERR_LBRACE_OR_SEMICOLON) = (int)createString('(',' ','o','r',' ',';',0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "procedure or var"------------ - *(stringArray + ERR_PROCEDURE_OR_VARIABLE) = (int)createString('p','r','o','c','e','d','u','r','e',' ','o','r',' ','v','a','r',0,0,0,0); - - // ------------ "eof" ------------ - *(stringArray + ERR_EOF) = (int)createString('e','o','f',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); +int lineNumber = 1; // current Line Number for error reporting - // ------------ "undeclared var"------------ - *(stringArray + ERR_UNDECLARED_VARIABLE) = (int)createString('u','n','d','e','c','l','a','r','e','d',' ','v','a','r',0,0,0,0,0,0); +int *identifier = (int*) 0; // stores scanned identifier as string +int *integer = (int*) 0; // stores scanned integer as string +int *string = (int*) 0; // stores scanned string - // ------------ "type mismatch" ------------ - *(stringArray + ERR_TYPE_MISMATCH) = (int)createString('t','y','p','e',' ','m','i','s','m','a','t','c','h',0,0,0,0,0,0,0); +int constant = 0; // stores numerical value of scanned integer or character - // ------------ "wrong return type" ------------ - *(stringArray + ERR_WRONG_RETURNTYPE) = (int)createString('w','r','o','n','g',' ','r','e','t','u','r','n',' ','t','y','p','e',0,0,0); +int initialValue = 0; // stores initial value of variable definitions - // ------------ "statement" ------------ - *(stringArray + ERR_STATEMENT) = (int)createString('s','t','a','t','e','m','e','n','t',0,0,0,0,0,0,0,0,0,0,0); +int mayBeINTMINConstant = 0; // support INT_MIN constant +int isINTMINConstant = 0; - // ------------ "wraparound" ------------ - *(stringArray + ERR_WRAPAROUND) = (int)createString('w','r','a','p','a','r','o','u','n','d',0,0,0,0,0,0,0,0,0,0); +int character; // most recently read character +int symbol; // most recently recognized symbol +int testvar; - // ------------ "maxcodelength" ------------ - *(stringArray + ERR_MAXCODELENGTH) = (int)createString('m','a','x','c','o','d','e','l','e','n','g','t','h',0,0,0,0,0,0,0); - - // ------------ "maxidentlength" ------------ - *(stringArray + ERR_MAXIDENTIFIERLENGTH) = (int)createString('m','a','x','i','d','e','n','t','l','e','n','g','t','h',0,0,0,0,0,0); - - // ------------ "file not found" ------------ - *(stringArray + ERR_FILE_NOT_FOUND) = (int)createString('f','i','l','e',' ','n','o','t',' ','f','o','u','n','d',0,0,0,0,0,0); - - // ------------ "else" ------------ - *(stringArray + SYM_ELSE) = (int)createString('e','l','s','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - // ------------ "void" ------------ - *(stringArray + SYM_VOID) = (int)createString('v','o','i','d',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); +// ------------------------- INITIALIZATION ------------------------ - // ------------ "int" ------------ - *(stringArray + SYM_INT) = (int)createString('i','n','t',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); +void initScanner () { + SYMBOLS = malloc(28*4); + + *(SYMBOLS + SYM_IDENTIFIER) = (int) "identifier"; + *(SYMBOLS + SYM_INTEGER) = (int) "integer"; + *(SYMBOLS + SYM_VOID) = (int) "void"; + *(SYMBOLS + SYM_INT) = (int) "int"; + *(SYMBOLS + SYM_SEMICOLON) = (int) ";"; + *(SYMBOLS + SYM_IF) = (int) "if"; + *(SYMBOLS + SYM_ELSE) = (int) "else"; + *(SYMBOLS + SYM_PLUS) = (int) "+"; + *(SYMBOLS + SYM_MINUS) = (int) "-"; + *(SYMBOLS + SYM_ASTERISK) = (int) "*"; + *(SYMBOLS + SYM_DIV) = (int) "/"; + *(SYMBOLS + SYM_EQUALITY) = (int) "=="; + *(SYMBOLS + SYM_ASSIGN) = (int) "="; + *(SYMBOLS + SYM_LPARENTHESIS) = (int) "("; + *(SYMBOLS + SYM_RPARENTHESIS) = (int) ")"; + *(SYMBOLS + SYM_LBRACE) = (int) "{"; + *(SYMBOLS + SYM_RBRACE) = (int) "}"; + *(SYMBOLS + SYM_WHILE) = (int) "while"; + *(SYMBOLS + SYM_RETURN) = (int) "return"; + *(SYMBOLS + SYM_COMMA) = (int) ","; + *(SYMBOLS + SYM_LT) = (int) "<"; + *(SYMBOLS + SYM_LEQ) = (int) "<="; + *(SYMBOLS + SYM_GT) = (int) ">"; + *(SYMBOLS + SYM_GEQ) = (int) ">="; + *(SYMBOLS + SYM_NOTEQ) = (int) "!="; + *(SYMBOLS + SYM_MOD) = (int) "%"; + *(SYMBOLS + SYM_CHARACTER) = (int) "character"; + *(SYMBOLS + SYM_STRING) = (int) "string"; - lineNumber = 1; character = getchar(); - symbol = -1; - - identifier = 0; - integer = 0; - - ivalue = 0; - - mayBeINTMINConstant = 0; + symbol = SYM_EOF; } // ----------------------------------------------------------------- // ------------------------- SYMBOL TABLE -------------------------- // ----------------------------------------------------------------- -void initSymbolTable(); - -void createSymbolTableEntry(int which_symbol_table, int *ident, int data, int class, int type); -int *getSymbolTableEntry(int *ident, int *symbol_table); +void createSymbolTableEntry(int which, int *string, int data, int class, int type, int value); +int* getSymbolTableEntry(int *string, int class, int *symbol_table); -int *getNext(int *entry); -int *getIdentifier(int *entry); +int* getNext(int *entry); +int* getString(int *entry); int getData(int *entry); int getClass(int *entry); int getType(int *entry); +int getValue(int *entry); int getRegister(int *entry); void setNext(int *entry, int *next); -void setIdentifier(int *entry, int *identifier); +void setString(int *entry, int *identifier); void setData(int *entry, int data); void setClass(int *entry, int class); void setType(int *entry, int type); +void setValue(int *entry, int value); void setRegister(int *entry, int reg); // ------------------------ GLOBAL CONSTANTS ----------------------- // classes -int UNKNOWN; // 0 -int CONSTANT; // 1 -int VARIABLE; // 2 -int FUNCTION; // 3 +int VARIABLE = 1; +int FUNCTION = 2; +int STRING = 3; // types -int INT_T; // 1 -int INTSTAR_T; // 2 -int VOID_T; // 3 +int INT_T = 1; +int INTSTAR_T = 2; +int VOID_T = 3; // symbol tables -int GLOBAL_TABLE; -int LOCAL_TABLE; +int GLOBAL_TABLE = 1; +int LOCAL_TABLE = 2; // ------------------------ GLOBAL VARIABLES ----------------------- -// table pointer -int *global_symbol_table; -int *local_symbol_table; - -// ------------------------- INITIALIZATION ------------------------ - -void initSymbolTable() { - // classes - UNKNOWN = 0; - CONSTANT = 1; - VARIABLE = 2; - FUNCTION = 3; - - // types - INT_T = 1; - INTSTAR_T = 2; - VOID_T = 3; - - // symbol tables - GLOBAL_TABLE = 1; - LOCAL_TABLE = 2; - - // table pointer - global_symbol_table = 0; - local_symbol_table = 0; -} +// table pointers +int *global_symbol_table = (int*) 0; +int *local_symbol_table = (int*) 0; // ----------------------------------------------------------------- // ---------------------------- PARSER ----------------------------- @@ -499,25 +329,31 @@ void initSymbolTable() { void initParser(); int isNotRbraceOrEOF(); -int isVariableOrProcedure(); int isExpression(); -int isPlusOrMinus(); int isStarOrDivOrModulo(); +int isPlusOrMinus(); +int isComparison(); + +int lookForFactor(); +int lookForStatement(); +int lookForType(); -int waitForStatement(); -int waitForVariable(); -int waitForFactor(); +void save_temporaries(); +void restore_temporaries(int numberOfTemporaries); -void save_registers(); -void restore_registers(int numberOfRegisters); +void syntaxErrorSymbol(int expected); +void syntaxErrorUnexpected(); +int* putType(int type); +void typeWarning(int expected, int found); int* getVariable(int *variable); int load_variable(int *variable); void load_integer(); +void load_string(); int help_call_codegen(int *entry, int *procedure); void help_procedure_prologue(int localVariables); -void help_procedure_epilogue(int parameters, int functionStart, int functionType); +void help_procedure_epilogue(int parameters); int gr_call(int *procedure); int gr_factor(); @@ -528,36 +364,33 @@ void gr_while(); void gr_if(); void gr_return(int returnType); void gr_statement(); -int gr_variable(); +int gr_type(); +void gr_variable(int offset); +void gr_initialization(int *name, int offset, int type); void gr_procedure(int *procedure, int returnType); void gr_cstar(); // ------------------------ GLOBAL CONSTANTS ----------------------- -int maxCodeLength; +int maxBinaryLength; // ------------------------ GLOBAL VARIABLES ----------------------- -int allocatedRegisters; // number of allocated registers -int allocatedGlobalVariables; // number of global variables +int allocatedTemporaries = 0; // number of allocated temporaries -int codeLength; -int returnBranches; -int *currentFuncName; // holds the name of currently parsed function +int allocatedMemory = 0; // number of bytes for global variables and strings + +int mainJumpAddress = 0; // address of main function +int returnBranches = 0; // fixup chain for return statements + +int *currentProcedureName = (int*) 0; // name of currently parsed procedure // ------------------------- INITIALIZATION ------------------------ void initParser() { - // set maximum code length for emitting code - maxCodeLength = 32000; - - allocatedRegisters = 0; - allocatedGlobalVariables = 0; - - codeLength = 0; - returnBranches = 0; - currentFuncName = 0; + // set maximum code length in bytes for emitting code + maxBinaryLength = twoToThePowerOf(17); } // ----------------------------------------------------------------- @@ -577,36 +410,84 @@ void emitMainEntry(); // ---------------------------- REGISTER --------------------------- // ----------------------------------------------------------------- +void initRegister(); + +void printRegister(int reg); + // ------------------------ GLOBAL CONSTANTS ----------------------- -int REG_ZR; -int REG_V0; -int REG_A0; -int REG_A1; -int REG_A2; -int REG_A3; -int REG_RR; -int REG_K1; -int REG_GP; -int REG_SP; -int REG_FP; -int REG_LINK; +int REG_ZR = 0; +int REG_AT = 1; +int REG_V0 = 2; +int REG_V1 = 3; +int REG_A0 = 4; +int REG_A1 = 5; +int REG_A2 = 6; +int REG_A3 = 7; +int REG_T0 = 8; +int REG_T1 = 9; +int REG_T2 = 10; +int REG_T3 = 11; +int REG_T4 = 12; +int REG_T5 = 13; +int REG_T6 = 14; +int REG_T7 = 15; +int REG_S0 = 16; +int REG_S1 = 17; +int REG_S2 = 18; +int REG_S3 = 19; +int REG_S4 = 20; +int REG_S5 = 21; +int REG_S6 = 22; +int REG_S7 = 23; +int REG_T8 = 24; +int REG_T9 = 25; +int REG_K0 = 26; +int REG_K1 = 27; +int REG_GP = 28; +int REG_SP = 29; +int REG_FP = 30; +int REG_RA = 31; + +int *REGISTERS; // array of strings representing registers // ------------------------- INITIALIZATION ------------------------ void initRegister() { - REG_ZR = 0; - REG_V0 = 2; - REG_A0 = 4; - REG_A1 = 5; - REG_A2 = 6; - REG_A3 = 7; - REG_RR = 26; - REG_K1 = 27; - REG_GP = 28; - REG_SP = 29; - REG_FP = 30; - REG_LINK = 31; + REGISTERS = malloc(32*4); + + *(REGISTERS + REG_ZR) = (int) "$zero"; + *(REGISTERS + REG_AT) = (int) "$at"; + *(REGISTERS + REG_V0) = (int) "$v0"; + *(REGISTERS + REG_V1) = (int) "$v1"; + *(REGISTERS + REG_A0) = (int) "$a0"; + *(REGISTERS + REG_A1) = (int) "$a1"; + *(REGISTERS + REG_A2) = (int) "$a2"; + *(REGISTERS + REG_A3) = (int) "$a3"; + *(REGISTERS + REG_T0) = (int) "$t0"; + *(REGISTERS + REG_T1) = (int) "$t1"; + *(REGISTERS + REG_T2) = (int) "$t2"; + *(REGISTERS + REG_T3) = (int) "$t3"; + *(REGISTERS + REG_T4) = (int) "$t4"; + *(REGISTERS + REG_T5) = (int) "$t5"; + *(REGISTERS + REG_T6) = (int) "$t6"; + *(REGISTERS + REG_T7) = (int) "$t7"; + *(REGISTERS + REG_S0) = (int) "$s0"; + *(REGISTERS + REG_S1) = (int) "$s1"; + *(REGISTERS + REG_S2) = (int) "$s2"; + *(REGISTERS + REG_S3) = (int) "$s3"; + *(REGISTERS + REG_S4) = (int) "$s4"; + *(REGISTERS + REG_S5) = (int) "$s5"; + *(REGISTERS + REG_S6) = (int) "$s6"; + *(REGISTERS + REG_S7) = (int) "$s7"; + *(REGISTERS + REG_T8) = (int) "$t8"; + *(REGISTERS + REG_T9) = (int) "$t9"; + *(REGISTERS + REG_K0) = (int) "$k0"; + *(REGISTERS + REG_K1) = (int) "$k1"; + *(REGISTERS + REG_GP) = (int) "$gp"; + *(REGISTERS + REG_SP) = (int) "$sp"; + *(REGISTERS + REG_FP) = (int) "$fp"; + *(REGISTERS + REG_RA) = (int) "$ra"; } // ----------------------------------------------------------------- @@ -632,6 +513,9 @@ int signExtend(int immediate); void initDecoder(); +void printOpcode(int opcode); +void printFunction(int function); + void decode(); void decodeRFormat(); void decodeIFormat(); @@ -639,77 +523,98 @@ void decodeJFormat(); // ------------------------ GLOBAL CONSTANTS ----------------------- -int OP_SPECIAL; -int FCT_SYSCALL; -int FCT_MFHI; -int FCT_MFLO; -int FCT_MULTU; -int FCT_DIVU; -int OP_ADDIU; -int FCT_ADDU; -int FCT_SUBU; -int OP_LW; -int OP_SW; -int OP_BEQ; -int OP_BNE; -int FCT_SLT; -int FCT_NOP; -int FCT_JR; -int OP_JAL; -int OP_J; -int FCT_TEQ; +int OP_SPECIAL = 0; +int OP_J = 2; +int OP_JAL = 3; +int OP_BEQ = 4; +int OP_BNE = 5; +int OP_ADDIU = 9; +int OP_LW = 35; +int OP_SW = 43; + +int *OPCODES; // array of strings representing MIPS opcodes + +int FCT_NOP = 0; +int FCT_JR = 8; +int FCT_SYSCALL = 12; +int FCT_MFHI = 16; +int FCT_MFLO = 18; +int FCT_MULTU = 25; +int FCT_DIVU = 27; +int FCT_ADDU = 33; +int FCT_SUBU = 35; +int FCT_SLT = 42; +int FCT_TEQ = 52; + +int *FUNCTIONS; // array of strings representing MIPS functions // ------------------------ GLOBAL VARIABLES ----------------------- -int opcode; -int rs; -int rt; -int rd; -int immediate; -int function; -int instr_index; +int opcode = 0; +int rs = 0; +int rt = 0; +int rd = 0; +int immediate = 0; +int function = 0; +int instr_index = 0; // ------------------------- INITIALIZATION ------------------------ void initDecoder() { - OP_SPECIAL = 0; - FCT_NOP = 0; - OP_JAL = 3; - OP_J = 2; - OP_BEQ = 4; - OP_BNE = 5; - OP_ADDIU = 9; - FCT_JR = 8; - FCT_SYSCALL = 12; - FCT_MFHI = 16; - FCT_MFLO = 18; - FCT_MULTU = 25; - FCT_DIVU = 27; - FCT_ADDU = 33; - FCT_SUBU = 35; - OP_LW = 35; - FCT_SLT = 42; - OP_SW = 43; - FCT_TEQ = 52; - - opcode = 0; - rs = 0; - rt = 0; - rd = 0; - immediate = 0; - function = 0; - instr_index = 0; + OPCODES = malloc(44*4); + + *(OPCODES + OP_SPECIAL) = (int) "nop"; + *(OPCODES + OP_J) = (int) "j"; + *(OPCODES + OP_JAL) = (int) "jal"; + *(OPCODES + OP_BEQ) = (int) "beq"; + *(OPCODES + OP_BNE) = (int) "bne"; + *(OPCODES + OP_ADDIU) = (int) "addiu"; + *(OPCODES + OP_LW) = (int) "lw"; + *(OPCODES + OP_SW) = (int) "sw"; + + FUNCTIONS = malloc(53*4); + + *(FUNCTIONS + FCT_NOP) = (int) "nop"; + *(FUNCTIONS + FCT_JR) = (int) "jr"; + *(FUNCTIONS + FCT_SYSCALL) = (int) "syscall"; + *(FUNCTIONS + FCT_MFHI) = (int) "mfhi"; + *(FUNCTIONS + FCT_MFLO) = (int) "mflo"; + *(FUNCTIONS + FCT_MULTU) = (int) "multu"; + *(FUNCTIONS + FCT_DIVU) = (int) "divu"; + *(FUNCTIONS + FCT_ADDU) = (int) "addu"; + *(FUNCTIONS + FCT_SUBU) = (int) "subu"; + *(FUNCTIONS + FCT_SLT) = (int) "slt"; + *(FUNCTIONS + FCT_TEQ) = (int) "teq"; } // ----------------------------------------------------------------- // ---------------------------- MEMORY ----------------------------- // ----------------------------------------------------------------- -void allocateMachineMemory(int size); +void initMemory(int size, int* name); + +int tlb(int vaddr); + +int loadMemory(int vaddr); +void storeMemory(int vaddr, int data); // ------------------------ GLOBAL VARIABLES ----------------------- -int *memory; // machine memory +int *memory; +int memorySize; + +int *binaryName; +int binaryLength; + +// ------------------------- INITIALIZATION ------------------------ + +void initMemory(int size, int *name) { + memory = malloc(size); + memorySize = size; + + binaryName = name; + binaryLength = 0; +} // ----------------------------------------------------------------- // ---------------------------- BINARY ----------------------------- @@ -724,15 +629,15 @@ void fixup_relative(int fromAddress); void fixup_absolute(int fromAddress, int toAddress); void fixlink_absolute(int fromAddress, int toAddress); +int copyStringToMemory(int *s, int a); + void emitBinary(); -int loadBinary(int *filename); +void loadBinary(); // ----------------------------------------------------------------- // --------------------------- SYSCALLS ---------------------------- // ----------------------------------------------------------------- -void initSyscalls(); - void emitExit(); void syscall_exit(); @@ -753,25 +658,18 @@ void syscall_getchar(); void emitPutchar(); -// ------------------------ GLOBAL CONSTANTS ----------------------- - -int SYSCALL_EXIT; -int SYSCALL_READ; -int SYSCALL_WRITE; -int SYSCALL_OPEN; -int SYSCALL_MALLOC; -int SYSCALL_GETCHAR; +void emitYield(); +void syscall_yield(); -// ------------------------- INITIALIZATION ------------------------ +// ------------------------ GLOBAL CONSTANTS ----------------------- -void initSyscalls() { - SYSCALL_EXIT = 4001; - SYSCALL_READ = 4003; - SYSCALL_WRITE = 4004; - SYSCALL_OPEN = 4005; - SYSCALL_MALLOC = 5001; - SYSCALL_GETCHAR = 5002; -} +int SYSCALL_EXIT = 4001; +int SYSCALL_READ = 4003; +int SYSCALL_WRITE = 4004; +int SYSCALL_OPEN = 4005; +int SYSCALL_MALLOC = 5001; +int SYSCALL_GETCHAR = 5002; +int SYSCALL_YIELD = 5003; // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- @@ -809,9 +707,9 @@ void op_teq(); void initInterpreter(); -void exception_handler(int enumber); +void printException(int enumber); -int addressTranslation(int vaddr); +void exception_handler(int enumber); void pre_debug(); void post_debug(); @@ -820,124 +718,60 @@ void fetch(); void execute(); void run(); -void debug_boot(int memorySize); -int* parse_args(int argc, int *argv, int *cstar_argv); +void parse_args(int argc, int *argv); + void up_push(int value); int up_malloc(int size); -int up_copyCString(int *s); void up_copyArguments(int argc, int *argv); -int main_emulator(int argc, int *argv, int *cstar_argv); +int main_emulator(int argc, int *argv); // ------------------------ GLOBAL CONSTANTS ----------------------- -int *register_strings; // static strings for register names -int *op_strings; // static strings for debug_disassemble -int *fct_strings; +int debug_load = 0; + +int debug_read = 0; +int debug_write = 0; +int debug_open = 0; +int debug_malloc = 0; +int debug_getchar = 0; +int debug_yield = 1; -int debug_registers; -int debug_syscalls; -int debug_load; -int debug_disassemble; +int debug_registers = 0; +int debug_disassemble = 0; -int EXCEPTION_SIGNAL; -int EXCEPTION_ADDRESSERROR; -int EXCEPTION_UNKNOWNINSTRUCTION; -int EXCEPTION_HEAPOVERFLOW; -int EXCEPTION_UNKNOWNSYSCALL; -int EXCEPTION_UNKNOWNFUNCTION; +int EXCEPTION_SIGNAL = 1; +int EXCEPTION_ADDRESSERROR = 2; +int EXCEPTION_UNKNOWNINSTRUCTION = 3; +int EXCEPTION_HEAPOVERFLOW = 4; +int EXCEPTION_UNKNOWNSYSCALL = 5; +int EXCEPTION_UNKNOWNFUNCTION = 6; + +int *EXCEPTIONS; // array of strings representing exceptions // ------------------------ GLOBAL VARIABLES ----------------------- int *registers; // general purpose registers -int pc; // program counter -int ir; // instruction record +int pc = 0; // program counter +int ir = 0; // instruction record -int reg_hi; // hi register for multiplication/division -int reg_lo; // lo register for multiplication/division +int reg_hi = 0; // hi register for multiplication/division +int reg_lo = 0; // lo register for multiplication/division // ------------------------- INITIALIZATION ------------------------ void initInterpreter() { - register_strings = (int*)malloc(4*32); - op_strings = (int*)malloc(4*64); - fct_strings = (int*)malloc(4*64); - - *(register_strings + 0) = (int)createString('z','e','r','o',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 1) = (int)createString('a','t',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 2) = (int)createString('v','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 3) = (int)createString('v','1',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 4) = (int)createString('a','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 5) = (int)createString('a','1',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 6) = (int)createString('a','2',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 7) = (int)createString('a','3',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 8) = (int)createString('t','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 9) = (int)createString('t','1',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 10) = (int)createString('t','2',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 11) = (int)createString('t','3',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 12) = (int)createString('t','4',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 13) = (int)createString('t','5',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 14) = (int)createString('t','6',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 15) = (int)createString('t','7',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 16) = (int)createString('s','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 17) = (int)createString('s','1',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 18) = (int)createString('s','2',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 19) = (int)createString('s','3',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 20) = (int)createString('s','4',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 21) = (int)createString('s','5',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 22) = (int)createString('s','6',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 23) = (int)createString('s','7',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 24) = (int)createString('t','8',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 25) = (int)createString('t','9',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 26) = (int)createString('k','0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 27) = (int)createString('k','1',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 28) = (int)createString('g','p',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 29) = (int)createString('s','p',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 30) = (int)createString('f','p',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(register_strings + 31) = (int)createString('r','a',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - *(fct_strings + 0) = (int)createString('n','o','p',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 8) = (int)createString('j','r',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 12) = (int)createString('s','y','s','c','a','l','l',0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 16) = (int)createString('m','f','h','i',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 18) = (int)createString('m','f','l','o',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 25) = (int)createString('m','u','l','t','u',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 27) = (int)createString('d','i','v','u',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 33) = (int)createString('a','d','d','u',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 35) = (int)createString('s','u','b','u',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 42) = (int)createString('s','l','t',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(fct_strings + 52) = (int)createString('t','e','q',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - *(op_strings + 0) = (int)createString('n','o','p',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 3) = (int)createString('j','a','l',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 2) = (int)createString('j',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 4) = (int)createString('b','e','q',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 5) = (int)createString('b','n','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 9) = (int)createString('a','d','d','i','u',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 15) = (int)createString('l','u','i',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 35) = (int)createString('l','w',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - *(op_strings + 43) = (int)createString('s','w',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - debug_registers = 0; - debug_syscalls = 0; - debug_load = 0; - debug_disassemble = 0; - - EXCEPTION_SIGNAL = 1; - EXCEPTION_ADDRESSERROR = 2; - EXCEPTION_UNKNOWNINSTRUCTION = 3; - EXCEPTION_HEAPOVERFLOW = 4; - EXCEPTION_UNKNOWNSYSCALL = 5; - EXCEPTION_UNKNOWNFUNCTION = 6; - - registers = (int*)malloc(32*4); - - pc = 0; - ir = 0; - - reg_hi = 0; - reg_lo = 0; + EXCEPTIONS = malloc(7*4); + + *(EXCEPTIONS + EXCEPTION_SIGNAL) = (int) "signal"; + *(EXCEPTIONS + EXCEPTION_ADDRESSERROR) = (int) "address error"; + *(EXCEPTIONS + EXCEPTION_UNKNOWNINSTRUCTION) = (int) "unknown instruction"; + *(EXCEPTIONS + EXCEPTION_HEAPOVERFLOW) = (int) "heap overflow"; + *(EXCEPTIONS + EXCEPTION_UNKNOWNSYSCALL) = (int) "unknown syscall"; + *(EXCEPTIONS + EXCEPTION_UNKNOWNFUNCTION) = (int) "unknown function"; + + registers = malloc(32*4); } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -977,56 +811,85 @@ int rightShift(int n, int b) { (INT_MAX / twoToThePowerOf(b) + 1); } +int getCharacter(int *s, int i) { + // assert: i >= 0 + int a; + + a = i / 4; + + return rightShift(leftShift(*(s + a), 24 - (i % 4) * 8), 24); +} + +int* putCharacter(int *s, int i, int c) { + // assert: i >= 0, all characters are 7-bit + int a; + + a = i / 4; + + *(s + a) = (*(s + a) - leftShift(getCharacter(s, i), (i % 4) * 8)) + leftShift(c, (i % 4) * 8); + + return s; +} + int stringLength(int *s) { int i; i = 0; - while (*(s+i) != 0) + while (getCharacter(s, i) != 0) i = i + 1; return i; } -void reverseString(int *s) { - int tmp; +void stringReverse(int *s) { int i; int j; + int tmp; i = 0; j = stringLength(s) - 1; while (i < j) { - tmp = *(s+i); - *(s+i) = *(s+j); - *(s+j) = tmp; + tmp = getCharacter(s, i); + + putCharacter(s, i, getCharacter(s, j)); + putCharacter(s, j, tmp); + i = i + 1; j = j - 1; } } -int stringCompare(int* s, int* t) { +int stringCompare(int *s, int *t) { + int i; + + i = 0; + while (1) - if (*s == 0) - if (*t == 0) + if (getCharacter(s, i) == 0) + if (getCharacter(t, i) == 0) return 1; else return 0; - else if (*s == *t) { - s = s + 1; - t = t + 1; - } else + else if (getCharacter(s, i) == getCharacter(t, i)) + i = i + 1; + else return 0; } -int atoi(int* s) { +int atoi(int *s) { + int i; int n; + i = 0; + n = 0; - while (*s != 0) { - n = n * 10 + *s - '0'; - s = s + 1; + while (getCharacter(s, i) != 0) { + n = n * 10 + getCharacter(s, i) - '0'; + + i = i + 1; } return n; @@ -1043,7 +906,7 @@ int* itoa(int n, int *s, int b, int a) { sign = 0; if (n == 0) { - *s = '0'; + putCharacter(s, 0, '0'); i = 1; } else if (n < 0) { @@ -1051,7 +914,8 @@ int* itoa(int n, int *s, int b, int a) { if (b == 10) { if (n == INT_MIN) { - *s = '8'; // rightmost decimal digit of 32-bit INT_MIN + // rightmost decimal digit of 32-bit INT_MIN + putCharacter(s, 0, '8'); n = -(n / 10); i = i + 1; @@ -1059,7 +923,8 @@ int* itoa(int n, int *s, int b, int a) { n = -n; } else { if (n == INT_MIN) { - *s = '0'; // rightmost non-decimal digit of INT_MIN + // rightmost non-decimal digit of INT_MIN + putCharacter(s, 0, '0'); n = (rightShift(INT_MIN, 1) / b) * 2; i = i + 1; @@ -1069,12 +934,10 @@ int* itoa(int n, int *s, int b, int a) { } while (n != 0) { - *(s+i) = n % b; - - if (*(s+i) > 9) - *(s+i) = *(s+i) - 10 + 'A'; + if (n % b > 9) + putCharacter(s, i, n % b - 10 + 'A'); else - *(s+i) = *(s+i) + '0'; + putCharacter(s, i, n % b + '0'); n = n / b; i = i + 1; @@ -1089,70 +952,69 @@ int* itoa(int n, int *s, int b, int a) { if (b != 10) { while (i < a) { - *(s+i) = '0'; // align with zeros + putCharacter(s, i, '0'); // align with zeros i = i + 1; } + + if (b == 16) { + putCharacter(s, i, 'x'); + putCharacter(s, i + 1, '0'); + + i = i + 2; + } } else if (sign) { - *(s+i) = '-'; + putCharacter(s, i, '-'); i = i + 1; } - *(s+i) = 0; // null terminated string + putCharacter(s, i, 0); // null terminated string - reverseString(s); + stringReverse(s); return s; } void print(int *s) { - while (*s != 0) { - putchar(*s); - s = s + 1; - } -} + int i; -void assignString(int *s, int c0, int c1, int c2, int c3, int c4, - int c5, int c6, int c7, int c8, int c9, - int c10, int c11, int c12, int c13, int c14, - int c15, int c16, int c17, int c18, int c19) { + i = 0; - *(s+0) = c0; *(s+1) = c1; *(s+2) = c2; *(s+3) = c3; *(s+4) = c4; - *(s+5) = c5; *(s+6) = c6; *(s+7) = c7; *(s+8) = c8; *(s+9) = c9; - *(s+10) = c10; *(s+11) = c11; *(s+12) = c12; *(s+13) = c13; *(s+14) = c14; - *(s+15) = c15; *(s+16) = c16; *(s+17) = c17; *(s+18) = c18; *(s+19) = c19; - *(s+20) = 0; -} + while (getCharacter(s, i) != 0) { + putchar(getCharacter(s, i)); -int* createString(int c0, int c1, int c2, int c3, int c4, - int c5, int c6, int c7, int c8, int c9, - int c10, int c11, int c12, int c13, int c14, - int c15, int c16, int c17, int c18, int c19) { - int* s; + i = i + 1; + } +} - s = (int*)malloc(21*4); - assignString(s, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - c10, c11, c12, c13, c14, c15, c16, c17, c18, c19); - return s; +void println() { + putchar(CHAR_LF); } -void printString(int c0, int c1, int c2, int c3, int c4, - int c5, int c6, int c7, int c8, int c9, - int c10, int c11, int c12, int c13, int c14, - int c15, int c16, int c17, int c18, int c19) { +void printCharacter(int character) { + putchar(CHAR_SINGLEQUOTE); - assignString(string_buffer, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - c10, c11, c12, c13, c14, c15, c16, c17, c18, c19); + if (character == CHAR_EOF) + print((int*) "end of file"); + else if (character == CHAR_TAB) + print((int*) "tabulator"); + else if (character == CHAR_LF) + print((int*) "line feed"); + else if (character == CHAR_CR) + print((int*) "carriage return"); + else + putchar(character); - print(string_buffer); + putchar(CHAR_SINGLEQUOTE); } -void memset(int *a, int size, int v) { - while (size > 0) { - size = size - 1; - *(a+size) = v; - } +void printString(int *s) { + putchar(CHAR_DOUBLEQUOTE); + + print(s); + + putchar(CHAR_DOUBLEQUOTE); } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -1165,6 +1027,58 @@ void memset(int *a, int size, int v) { // ---------------------------- SCANNER ---------------------------- // ----------------------------------------------------------------- +void printSymbol(int symbol) { + putchar(CHAR_DOUBLEQUOTE); + + if (symbol == SYM_EOF) + print((int*) "end of file"); + else + print((int*) *(SYMBOLS + symbol)); + + putchar(CHAR_DOUBLEQUOTE); +} + +void printLineNumber(int* message) { + print((int*) "cstarc: "); + print(message); + print((int*) " in line "); + print(itoa(lineNumber, string_buffer, 10, 0)); + print((int*) ": "); +} + +void syntaxErrorMessage(int *message) { + printLineNumber((int*) "error"); + + print(message); + + println(); +} + +void syntaxErrorCharacter(int expected) { + printLineNumber((int*) "error"); + + printCharacter(expected); + print((int*) " expected but "); + + printCharacter(character); + print((int*) " found"); + + println(); +} + +int isCharacterWhitespace() { + if (character == CHAR_SPACE) + return 1; + else if (character == CHAR_TAB) + return 1; + else if (character == CHAR_LF) + return 1; + else if (character == CHAR_CR) + return 1; + else + return 0; +} + int findNextCharacter() { int inComment; @@ -1178,7 +1092,7 @@ int findNextCharacter() { inComment = 0; else if (character == CHAR_CR) inComment = 0; - else if (character == SYM_EOF) + else if (character == CHAR_EOF) return character; } else if (isCharacterWhitespace()) { @@ -1189,13 +1103,13 @@ int findNextCharacter() { character = getchar(); - } else if (character == '#') { + } else if (character == CHAR_HASH) { character = getchar(); inComment = 1; - } else if (character == '/') { + } else if (character == CHAR_SLASH) { character = getchar(); - if (character == '/') + if (character == CHAR_SLASH) inComment = 1; else { symbol = SYM_DIV; @@ -1207,26 +1121,17 @@ int findNextCharacter() { } } -int isCharacterWhitespace() { - if (character == ' ') - return 1; - else if (character == CHAR_TAB) - return 1; - else if (character == CHAR_LF) - return 1; - else if (character == CHAR_CR) - return 1; - else - return 0; -} - -int isCharacterLetterOrDigitOrUnderscore() { - if (isCharacterLetter()) - return 1; - else if(isCharacterDigit()) - return 1; - else if(character == '_') - return 1; +int isCharacterLetter() { + if (character >= 'a') + if (character <= 'z') + return 1; + else + return 0; + else if (character >= 'A') + if (character <= 'Z') + return 1; + else + return 0; else return 0; } @@ -1241,23 +1146,28 @@ int isCharacterDigit() { return 0; } -int isCharacterLetter() { - if (character >= 'a') - if (character <= 'z') - return 1; - else - return 0; - else if (character >= 'A') - if (character <= 'Z') - return 1; - else - return 0; +int isCharacterLetterOrDigitOrUnderscore() { + if (isCharacterLetter()) + return 1; + else if (isCharacterDigit()) + return 1; + else if (character == CHAR_UNDERSCORE) + return 1; else return 0; } -int identifierStringMatch(int stringIndex) { - return stringCompare(identifier, (int*)(*(stringArray + stringIndex))); +int isNotDoubleQuoteOrEOF() { + if (character == CHAR_DOUBLEQUOTE) + return 0; + else if (character == CHAR_EOF) + return 0; + else + return 1; +} + +int identifierStringMatch(int keyword) { + return stringCompare(identifier, (int*) *(SYMBOLS + keyword)); } int identifierOrKeyword() { @@ -1282,216 +1192,243 @@ int getSymbol() { symbol = SYM_EOF; - if (findNextCharacter() == SYM_EOF) + if (findNextCharacter() == CHAR_EOF) return SYM_EOF; else if (symbol == SYM_DIV) // check here because / was recognized instead of // return SYM_DIV; if (isCharacterLetter()) { - identifier = (int*)malloc((maxIdentifierLength+1) * 4); + identifier = malloc(maxIdentifierLength + 1); + i = 0; while (isCharacterLetterOrDigitOrUnderscore()) { - if (i+1 > maxIdentifierLength) { - syntaxError(ERR_MAXIDENTIFIERLENGTH); // identifier too long + if (i >= maxIdentifierLength) { + syntaxErrorMessage((int*) "identifier too long"); exit(-1); } - *(identifier+i) = character; + + putCharacter(identifier, i, character); + i = i + 1; + character = getchar(); } - *(identifier+i) = 0; // null terminated string + putCharacter(identifier, i, 0); // null terminated string + symbol = identifierOrKeyword(); } else if (isCharacterDigit()) { - integer = (int*)malloc((maxIntegerLength+1) * 4); + integer = malloc(maxIntegerLength + 1); + i = 0; while (isCharacterDigit()) { - if (i+1 > maxIntegerLength) { - syntaxError(ERR_WRAPAROUND); // integer too long + if (i >= maxIntegerLength) { + syntaxErrorMessage((int*) "integer out of bound"); exit(-1); } - *(integer+i) = character; + + putCharacter(integer, i, character); + i = i + 1; + character = getchar(); } - *(integer+i) = 0; // null terminated string - ivalue = atoi(integer); + putCharacter(integer, i, 0); // null terminated string - if (ivalue < 0) { - if (ivalue == INT_MIN) { - if (mayBeINTMINConstant == 0) { - syntaxError(ERR_WRAPAROUND); + constant = atoi(integer); + + if (constant < 0) { + if (constant == INT_MIN) { + if (mayBeINTMINConstant) + isINTMINConstant = 1; + else { + syntaxErrorMessage((int*) "integer out of bound"); exit(-1); } } else { - syntaxError(ERR_WRAPAROUND); + syntaxErrorMessage((int*) "integer out of bound"); exit(-1); } } symbol = SYM_INTEGER; - } else if (character == ';') { + } else if (character == CHAR_SINGLEQUOTE) { character = getchar(); - symbol = SYM_SEMICOLON; - } else if (character == '+') { - character = getchar(); - symbol = SYM_PLUS; + constant = 0; - } else if (character == '-') { - character = getchar(); - symbol = SYM_MINUS; + if (character == CHAR_EOF) { + syntaxErrorMessage((int*) "reached end of file looking for a character constant"); - } else if (character == '*') { - character = getchar(); - symbol = SYM_ASTERISK; + exit(-1); + } else + constant = character; - } else if (character == '=') { character = getchar(); - if (character == '=') { + + if (character == CHAR_SINGLEQUOTE) character = getchar(); - symbol = SYM_EQUAL; + else if (character == CHAR_EOF) { + syntaxErrorCharacter(CHAR_SINGLEQUOTE); + + exit(-1); } else - symbol = SYM_ASSIGN; + syntaxErrorCharacter(CHAR_SINGLEQUOTE); - } else if (character == '(') { - character = getchar(); - symbol = SYM_LPARENTHESIS; + symbol = SYM_CHARACTER; - } else if (character == ')') { + } else if (character == CHAR_DOUBLEQUOTE) { character = getchar(); - symbol = SYM_RPARENTHESIS; - } else if (character == '{') { - character = getchar(); - symbol = SYM_LBRACE; + string = malloc(maxStringLength + 1); - } else if (character == '}') { - character = getchar(); - symbol = SYM_RBRACE; + i = 0; - } else if (character == ',') { - character = getchar(); - symbol = SYM_COMMA; + while (isNotDoubleQuoteOrEOF()) { + if (i >= maxStringLength) { + syntaxErrorMessage((int*) "string too long"); + exit(-1); + } + + putCharacter(string, i, character); + + i = i + 1; - } else if (character == '<') { - character = getchar(); - if (character == '=') { character = getchar(); - symbol = SYM_LEQ; - } else - symbol = SYM_LT; + } - } else if (character == '>') { - character = getchar(); - if (character == '=') { + if (character == CHAR_DOUBLEQUOTE) character = getchar(); - symbol = SYM_GEQ; - } else - symbol = SYM_GT; + else { + syntaxErrorCharacter(CHAR_DOUBLEQUOTE); + + exit(-1); + } - } else if (character == '!') { + putCharacter(string, i, 0); // null terminated string + + symbol = SYM_STRING; + + } else if (character == CHAR_SEMICOLON) { character = getchar(); - if (character == '=') { - character = getchar(); - symbol = SYM_NOTEQ; - } else - syntaxError(ERR_UNKNOWN); + symbol = SYM_SEMICOLON; - } else if (character == '%') { + } else if (character == CHAR_PLUS) { character = getchar(); - symbol = SYM_MOD; + symbol = SYM_PLUS; - } else if (character == 39) { // ' + } else if (character == CHAR_DASH) { character = getchar(); - ivalue = character; // any ascii character + symbol = SYM_MINUS; + + } else if (character == CHAR_ASTERISK) { character = getchar(); - if (character == 39) { // ' + symbol = SYM_ASTERISK; + + } else if (character == CHAR_EQUAL) { + character = getchar(); + if (character == CHAR_EQUAL) { character = getchar(); - symbol = SYM_CHARACTER; + symbol = SYM_EQUALITY; } else - syntaxError(ERR_UNKNOWN); - } else { - syntaxError(ERR_UNKNOWN); - exit(-1); // unknown character - } - - return symbol; -} - -void syntaxWarn(int errCode) { - int *numberBuffer; + symbol = SYM_ASSIGN; - numberBuffer = (int*)malloc(4*10); + } else if (character == CHAR_LPARENTHESIS) { + character = getchar(); + symbol = SYM_LPARENTHESIS; - print(warning); + } else if (character == CHAR_RPARENTHESIS) { + character = getchar(); + symbol = SYM_RPARENTHESIS; - print((int*)(*(stringArray+errCode))); + } else if (character == CHAR_LBRACE) { + character = getchar(); + symbol = SYM_LBRACE; - print(errLine); - print(itoa(lineNumber, numberBuffer, 10, 0)); + } else if (character == CHAR_RBRACE) { + character = getchar(); + symbol = SYM_RBRACE; - print(errSymbol); - print(itoa(symbol, numberBuffer, 10, 0)); + } else if (character == CHAR_COMMA) { + character = getchar(); + symbol = SYM_COMMA; - print(errNewline); -} + } else if (character == CHAR_LT) { + character = getchar(); + if (character == CHAR_EQUAL) { + character = getchar(); + symbol = SYM_LEQ; + } else + symbol = SYM_LT; -void syntaxError(int errCode) { - int *numberBuffer; + } else if (character == CHAR_GT) { + character = getchar(); + if (character == CHAR_EQUAL) { + character = getchar(); + symbol = SYM_GEQ; + } else + symbol = SYM_GT; - numberBuffer = (int*)malloc(4*10); + } else if (character == CHAR_EXCLAMATION) { + character = getchar(); + if (character == CHAR_EQUAL) + character = getchar(); + else + syntaxErrorCharacter(CHAR_EQUAL); - print(error); + symbol = SYM_NOTEQ; - print((int*)(*(stringArray+errCode))); + } else if (character == CHAR_PERCENTAGE) { + character = getchar(); + symbol = SYM_MOD; - print(errLine); - print(itoa(lineNumber, numberBuffer, 10, 0)); + } else { + printLineNumber((int*) "error"); + print((int*) "found unknown character "); + printCharacter(character); - print(errSymbol); - print(itoa(symbol, numberBuffer, 10, 0)); + println(); - print(errNewline); + exit(-1); + } - getSymbol(); + return symbol; } // ----------------------------------------------------------------- // ------------------------- SYMBOL TABLE -------------------------- // ----------------------------------------------------------------- -void createSymbolTableEntry(int which_symbol_table, int *ident, int data, int class, int type) { - int* newEntry; +void createSymbolTableEntry(int whichTable, int *string, int data, int class, int type, int value) { + int *newEntry; - // symbolTable: - // +----+------------+ - // | 0 | ptr to next| - // | 1 | identifier | - // | 2 | data | VARIABLE: offset/FUNCTION: code address - // | 3 | class | - // | 4 | type | - // | 5 | register | - // +----+------------+ + // symbol table entry: + // +----+----------+ + // | 0 | next | pointer to next entry + // | 1 | string | identifier string, string constant + // | 2 | data | VARIABLE: offset, FUNCTION: address, STRING: offset + // | 3 | class | VARIABLE, FUNCTION, STRING + // | 4 | type | INT_T, INTSTAR_T, VOID_T + // | 5 | value | VARIABLE: constant value + // | 6 | register | REG_GP, REG_FP + // +----+----------+ - newEntry = (int*)malloc(6 * 4); + newEntry = malloc(7 * 4); - // store pointer to identifier - // cast only works if size of int and int* is equivalent - setIdentifier(newEntry, ident); + setString(newEntry, string); setData(newEntry, data); setClass(newEntry, class); setType(newEntry, type); + setValue(newEntry, value); // create entry at head of symbol table - // cast only works if size of int and int* is equivalent - if (which_symbol_table == GLOBAL_TABLE) { + if (whichTable == GLOBAL_TABLE) { setRegister(newEntry, REG_GP); setNext(newEntry, global_symbol_table); global_symbol_table = newEntry; @@ -1502,24 +1439,26 @@ void createSymbolTableEntry(int which_symbol_table, int *ident, int data, int cl } } -int* getSymbolTableEntry(int *ident, int *symbol_table) { - while ((int)symbol_table != 0) { - if (stringCompare(ident, getIdentifier(symbol_table))) - return symbol_table; - else - // keep looking - // cast only works if size of int and int* is equivalent - symbol_table = getNext(symbol_table); +int* getSymbolTableEntry(int *string, int class, int *symbol_table) { + while ((int) symbol_table != 0) { + if (stringCompare(string, getString(symbol_table))) + if (class == getClass(symbol_table)) + return symbol_table; + + // keep looking + symbol_table = getNext(symbol_table); } - return 0; + return (int*) 0; } int* getNext(int *entry) { + // cast only works if size of int and int* is equivalent return (int*) *entry; } -int* getIdentifier(int *entry) { +int* getString(int *entry) { + // cast only works if size of int and int* is equivalent return (int*) *(entry + 1); } @@ -1535,15 +1474,21 @@ int getType(int *entry) { return *(entry + 4); } -int getRegister(int *entry) { +int getValue(int *entry) { return *(entry + 5); } +int getRegister(int *entry) { + return *(entry + 6); +} + void setNext(int *entry, int *next) { + // cast only works if size of int and int* is equivalent *entry = (int) next; } -void setIdentifier(int *entry, int *identifier) { +void setString(int *entry, int *identifier) { + // cast only works if size of int and int* is equivalent *(entry + 1) = (int) identifier; } @@ -1559,8 +1504,12 @@ void setType(int *entry, int type) { *(entry + 4) = type; } +void setValue(int *entry, int value) { + *(entry + 5) = value; +} + void setRegister(int *entry, int reg) { - *(entry + 5) = reg; + *(entry + 6) = reg; } // ----------------------------------------------------------------- @@ -1568,23 +1517,14 @@ void setRegister(int *entry, int reg) { // ----------------------------------------------------------------- int isNotRbraceOrEOF() { - if (symbol == SYM_EOF) + if (symbol == SYM_RBRACE) return 0; - else if(symbol == SYM_RBRACE) + else if(symbol == SYM_EOF) return 0; else return 1; } -int isVariableOrProcedure() { - if (symbol == SYM_INT) - return 1; - else if (symbol == SYM_VOID) - return 1; - else - return 0; -} - int isExpression() { if (symbol == SYM_MINUS) return 1; @@ -1596,16 +1536,18 @@ int isExpression() { return 1; else if (symbol == SYM_ASTERISK) return 1; + else if (symbol == SYM_STRING) + return 1; else if (symbol == SYM_CHARACTER) return 1; else return 0; } -int isPlusOrMinus() { - if (symbol == SYM_MINUS) +int isConstant() { + if (symbol == SYM_INTEGER) return 1; - else if (symbol == SYM_PLUS) + else if (symbol == SYM_CHARACTER) return 1; else return 0; @@ -1622,16 +1564,44 @@ int isStarOrDivOrModulo() { return 0; } -int waitForStatement() { - if (symbol == SYM_ASTERISK) +int isPlusOrMinus() { + if (symbol == SYM_MINUS) + return 1; + else if (symbol == SYM_PLUS) + return 1; + else + return 0; +} + +int isComparison() { + if (symbol == SYM_EQUALITY) + return 1; + else if (symbol == SYM_NOTEQ) + return 1; + else if (symbol == SYM_LT) + return 1; + else if (symbol == SYM_GT) + return 1; + else if (symbol == SYM_LEQ) + return 1; + else if (symbol == SYM_GEQ) + return 1; + else + return 0; +} + +int lookForFactor() { + if (symbol == SYM_LPARENTHESIS) + return 0; + else if (symbol == SYM_ASTERISK) return 0; else if (symbol == SYM_IDENTIFIER) return 0; - else if (symbol == SYM_WHILE) + else if (symbol == SYM_INTEGER) return 0; - else if (symbol == SYM_IF) + else if (symbol == SYM_CHARACTER) return 0; - else if (symbol == SYM_RETURN) + else if (symbol == SYM_STRING) return 0; else if (symbol == SYM_EOF) return 0; @@ -1639,8 +1609,16 @@ int waitForStatement() { return 1; } -int waitForVariable() { - if (symbol == SYM_INT) +int lookForStatement() { + if (symbol == SYM_ASTERISK) + return 0; + else if (symbol == SYM_IDENTIFIER) + return 0; + else if (symbol == SYM_WHILE) + return 0; + else if (symbol == SYM_IF) + return 0; + else if (symbol == SYM_RETURN) return 0; else if (symbol == SYM_EOF) return 0; @@ -1648,16 +1626,10 @@ int waitForVariable() { return 1; } -int waitForFactor() { - if (symbol == SYM_LPARENTHESIS) - return 0; - else if (symbol == SYM_ASTERISK) - return 0; - else if (symbol == SYM_IDENTIFIER) - return 0; - else if (symbol == SYM_INTEGER) +int lookForType() { + if (symbol == SYM_INT) return 0; - else if (symbol == SYM_CHARACTER) + else if (symbol == SYM_VOID) return 0; else if (symbol == SYM_EOF) return 0; @@ -1665,35 +1637,142 @@ int waitForFactor() { return 1; } -void save_registers() { - while (allocatedRegisters > 0) { - emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); - emitIFormat(OP_SW, REG_SP, allocatedRegisters, 0); +void talloc() { + // we use registers REG_T0-REG_T9 and REG_S0-REG_S7 for temporaries + if (allocatedTemporaries < REG_T9 - REG_A3) + allocatedTemporaries = allocatedTemporaries + 1; + else { + syntaxErrorMessage((int*) "out of registers"); + + exit(-1); + } +} + +int currentTemporary() { + if (allocatedTemporaries > 0) + return allocatedTemporaries + REG_A3; + else { + syntaxErrorMessage((int*) "illegal register access"); - allocatedRegisters = allocatedRegisters - 1; + exit(-1); } } -void restore_registers(int numberOfRegisters) { +int previousTemporary() { + if (allocatedTemporaries > 1) + return currentTemporary() - 1; + else { + syntaxErrorMessage((int*) "illegal register access"); - while (allocatedRegisters < numberOfRegisters) { - allocatedRegisters = allocatedRegisters + 1; + exit(-1); + } +} + +int nextTemporary() { + if (allocatedTemporaries < REG_T9 - REG_A3) + return currentTemporary() + 1; + else { + syntaxErrorMessage((int*) "out of registers"); - emitIFormat(OP_LW, REG_SP, allocatedRegisters, 0); + exit(-1); + } +} + +void tfree(int numberOfTemporaries) { + allocatedTemporaries = allocatedTemporaries - numberOfTemporaries; + + if (allocatedTemporaries < 0) { + syntaxErrorMessage((int*) "illegal register deallocation"); + + exit(-1); + } +} + +void save_temporaries() { + while (allocatedTemporaries > 0) { + emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); + emitIFormat(OP_SW, REG_SP, currentTemporary(), 0); + + tfree(1); + } +} + +void restore_temporaries(int numberOfTemporaries) { + while (allocatedTemporaries < numberOfTemporaries) { + talloc(); + + emitIFormat(OP_LW, REG_SP, currentTemporary(), 0); emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); } } +void syntaxErrorSymbol(int expected) { + printLineNumber((int*) "error"); + + printSymbol(expected); + print((int*) " expected but "); + + printSymbol(symbol); + print((int*) " found"); + + println(); +} + +void syntaxErrorUnexpected() { + printLineNumber((int*) "error"); + + print((int*) "unexpected symbol "); + printSymbol(symbol); + print((int*) " found"); + + println(); +} + +int* putType(int type) { + if (type == INT_T) + return (int*) "int"; + else if (type == INTSTAR_T) + return (int*) "int*"; + else if (type == VOID_T) + return (int*) "void"; + else + return (int*) "unknown"; +} + +void typeWarning(int expected, int found) { + printLineNumber((int*) "warning"); + + print((int*) "type mismatch, "); + + print(putType(expected)); + + print((int*) " expected but "); + + print(putType(found)); + + print((int*) " found"); + + println(); +} + int* getVariable(int *variable) { - int* entry; + int *entry; + + entry = getSymbolTableEntry(variable, VARIABLE, local_symbol_table); - entry = getSymbolTableEntry(variable, local_symbol_table); + if (entry == (int*) 0) { + entry = getSymbolTableEntry(variable, VARIABLE, global_symbol_table); - if ((int)entry == 0) { - entry = getSymbolTableEntry(variable, global_symbol_table); + if (entry == (int*) 0) { + printLineNumber((int*) "error"); - if ((int)entry == 0) - syntaxError(ERR_UNDECLARED_VARIABLE); + print(variable); + + print((int*) " undeclared"); + println(); + + exit(-1); + } } return entry; @@ -1704,68 +1783,81 @@ int load_variable(int *variable) { entry = getVariable(variable); - allocatedRegisters = allocatedRegisters + 1; + talloc(); - emitIFormat(OP_LW, getRegister(entry), allocatedRegisters, getData(entry)); + emitIFormat(OP_LW, getRegister(entry), currentTemporary(), getData(entry)); return getType(entry); } void load_integer() { - // assert: ivalue >= 0 or ivalue == INT_MIN - - allocatedRegisters = allocatedRegisters + 1; + // assert: constant >= 0 or constant == INT_MIN - if (ivalue >= 0) { - mayBeINTMINConstant = 0; + talloc(); - if (ivalue < twoToThePowerOf(15)) + if (constant >= 0) { + if (constant < twoToThePowerOf(15)) // ADDIU can only load numbers < 2^15 without sign extension - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, ivalue); - else if (ivalue < twoToThePowerOf(28)) { + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), constant); + else if (constant < twoToThePowerOf(28)) { // load 14 msbs of a 28-bit number first - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, rightShift(ivalue, 14)); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), rightShift(constant, 14)); // shift left by 14 bits emitLeftShiftBy(14); // and finally add 14 lsbs - emitIFormat(OP_ADDIU, allocatedRegisters, allocatedRegisters, rightShift(leftShift(ivalue, 18), 18)); + emitIFormat(OP_ADDIU, currentTemporary(), currentTemporary(), rightShift(leftShift(constant, 18), 18)); } else { // load 14 msbs of a 31-bit number first - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, rightShift(ivalue, 17)); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), rightShift(constant, 17)); emitLeftShiftBy(14); // then add the next 14 msbs - emitIFormat(OP_ADDIU, allocatedRegisters, allocatedRegisters, rightShift(leftShift(ivalue, 15), 18)); + emitIFormat(OP_ADDIU, currentTemporary(), currentTemporary(), rightShift(leftShift(constant, 15), 18)); emitLeftShiftBy(3); // and finally add the remaining 3 lsbs - emitIFormat(OP_ADDIU, allocatedRegisters, allocatedRegisters, rightShift(leftShift(ivalue, 29), 29)); + emitIFormat(OP_ADDIU, currentTemporary(), currentTemporary(), rightShift(leftShift(constant, 29), 29)); } } else { // load largest positive 16-bit number with a single bit set: 2^14 - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, twoToThePowerOf(14)); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), twoToThePowerOf(14)); // and then multiply 2^14 by 2^14*2^3 to get to 2^31 == INT_MIN emitLeftShiftBy(14); emitLeftShiftBy(3); } +} - getSymbol(); +void load_string() { + int l; + + l = stringLength(string) + 1; + + allocatedMemory = allocatedMemory + l; + + if (l % 4 != 0) + allocatedMemory = allocatedMemory + 4 - l % 4; + + createSymbolTableEntry(GLOBAL_TABLE, string, -allocatedMemory, STRING, INTSTAR_T, 0); + + talloc(); + + emitIFormat(OP_ADDIU, REG_GP, currentTemporary(), -allocatedMemory); } int help_call_codegen(int *entry, int *procedure) { int type; - type = UNKNOWN; - - if ((int)entry == 0) { + if (entry == (int*) 0) { // CASE 1: function call, no definition, no declaration. - createSymbolTableEntry(GLOBAL_TABLE, procedure, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, procedure, binaryLength, FUNCTION, INT_T, 0); + emitJFormat(OP_JAL, 0); + type = INT_T; //assume default return type 'int' } else { @@ -1773,156 +1865,174 @@ int help_call_codegen(int *entry, int *procedure) { if (getData(entry) == 0) { // CASE 2: function call, no definition, but declared. - setData(entry, codeLength); + setData(entry, binaryLength); + emitJFormat(OP_JAL, 0); - } else if (getOpcode(*(memory + getData(entry))) == OP_JAL) { + } else if (getOpcode(loadMemory(getData(entry))) == OP_JAL) { // CASE 3: function call, no declaration - emitJFormat(OP_JAL, getData(entry)); - setData(entry, codeLength - 2); + emitJFormat(OP_JAL, getData(entry) / 4); + + setData(entry, binaryLength - 8); } else // CASE 4: function defined, use the address - emitJFormat(OP_JAL, getData(entry)); + emitJFormat(OP_JAL, getData(entry) / 4); } return type; } void help_procedure_prologue(int localVariables) { - // save return address + // allocate space for return address emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); - emitIFormat(OP_SW, REG_SP, REG_LINK, 0); - // save caller's frame + // save return address + emitIFormat(OP_SW, REG_SP, REG_RA, 0); + + // allocate space for caller's frame pointer emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); + + // save caller's frame pointer emitIFormat(OP_SW, REG_SP, REG_FP, 0); - // allocate callee's frame + // set callee's frame pointer emitIFormat(OP_ADDIU, REG_SP, REG_FP, 0); - // allocate callee's local variables - if (localVariables != 0) { - emitIFormat(OP_ADDIU, REG_SP, REG_SP, localVariables * (-4)); - } + // allocate space for callee's local variables + if (localVariables != 0) + emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4 * localVariables); } -void help_procedure_epilogue(int parameters, int functionStart, int functionType) { - // deallocate callee's frame and local variables +void help_procedure_epilogue(int parameters) { + // deallocate space for callee's frame pointer and local variables emitIFormat(OP_ADDIU, REG_FP, REG_SP, 0); - // restore caller's frame + // restore caller's frame pointer emitIFormat(OP_LW, REG_SP, REG_FP, 0); + + // deallocate space for caller's frame pointer emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); - // restore return address and deallocate parameters - emitIFormat(OP_LW, REG_SP, REG_LINK, 0); - emitIFormat(OP_ADDIU, REG_SP, REG_SP, ((parameters+1)*4)); + // restore return address + emitIFormat(OP_LW, REG_SP, REG_RA, 0); + + // deallocate space for return address and parameters + emitIFormat(OP_ADDIU, REG_SP, REG_SP, (parameters + 1) * 4); // return - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } int gr_call(int *procedure) { int *entry; - int numberOfRegisters; + int numberOfTemporaries; int type; - // assert: n = allocatedRegisters + // assert: n = allocatedTemporaries - entry = getSymbolTableEntry(procedure, global_symbol_table); + entry = getSymbolTableEntry(procedure, FUNCTION, global_symbol_table); - numberOfRegisters = allocatedRegisters; + numberOfTemporaries = allocatedTemporaries; - save_registers(); + save_temporaries(); - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 if (isExpression()) { gr_expression(); - // TODO: check if types/number of params is correct. - // PSH first parameter onto stack + // TODO: check if types/number of parameters is correct + // push first parameter onto stack emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); - emitIFormat(OP_SW, REG_SP, allocatedRegisters, 0); - allocatedRegisters = allocatedRegisters - 1; + emitIFormat(OP_SW, REG_SP, currentTemporary(), 0); + + tfree(1); while (symbol == SYM_COMMA) { getSymbol(); + gr_expression(); - // PSH more parameters onto stack + // push more parameters onto stack emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); - emitIFormat(OP_SW, REG_SP, allocatedRegisters, 0); - allocatedRegisters = allocatedRegisters - 1; + emitIFormat(OP_SW, REG_SP, currentTemporary(), 0); + + tfree(1); } + if (symbol == SYM_RPARENTHESIS) { getSymbol(); + type = help_call_codegen(entry, procedure); } else { - syntaxWarn(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); + type = INT_T; } } else if (symbol == SYM_RPARENTHESIS) { getSymbol(); + type = help_call_codegen(entry, procedure); } else { - syntaxWarn(ERR_EXPRESSION); + syntaxErrorSymbol(SYM_RPARENTHESIS); + type = INT_T; } - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 - restore_registers(numberOfRegisters); + restore_temporaries(numberOfTemporaries); - // assert: allocatedRegisters == n + // assert: allocatedTemporaries == n return type; } int gr_factor() { + int hasCast; int cast; int type; + int *variableOrProcedureName; - // assert: n = allocatedRegisters + // assert: n = allocatedTemporaries + + hasCast = 0; + + type = INT_T; - cast = 0; // turn off cast by default + while (lookForFactor()) { + syntaxErrorUnexpected(); - while (waitForFactor()) - syntaxError(ERR_IDENT_OR_CONST_OR_EXP); + if (symbol == SYM_EOF) + exit(-1); + else + getSymbol(); + } // optional cast: [ cast ] if (symbol == SYM_LPARENTHESIS) { getSymbol(); - mayBeINTMINConstant = 0; - - // (int) + // cast: "(" "int" [ "*" ] ")" if (symbol == SYM_INT) { - getSymbol(); + hasCast = 1; - cast = INT_T; - - // (int*) - if (symbol == SYM_ASTERISK) { - getSymbol(); - - cast = INTSTAR_T; - } + cast = gr_type(); if (symbol == SYM_RPARENTHESIS) getSymbol(); else - syntaxWarn(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); - // Not a cast: "(" expression ")" + // not a cast: "(" expression ")" } else { type = gr_expression(); if (symbol == SYM_RPARENTHESIS) getSymbol(); else - syntaxWarn(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 return type; } @@ -1932,15 +2042,13 @@ int gr_factor() { if (symbol == SYM_ASTERISK) { getSymbol(); - mayBeINTMINConstant = 0; - // ["*"] identifier if (symbol == SYM_IDENTIFIER) { type = load_variable(identifier); getSymbol(); - // * "(" simpleExpression ")" + // * "(" expression ")" } else if (symbol == SYM_LPARENTHESIS) { getSymbol(); @@ -1949,19 +2057,17 @@ int gr_factor() { if (symbol == SYM_RPARENTHESIS) getSymbol(); else - syntaxWarn(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); } else - syntaxError(ERR_IDENTIFIER_OR_LPARENTHESIS); + syntaxErrorUnexpected(); - // dereference - emitIFormat(OP_LW, allocatedRegisters, allocatedRegisters, 0); + if (type != INTSTAR_T) + typeWarning(INTSTAR_T, type); - if (cast == 0) { - if (type != INTSTAR_T) - syntaxWarn(ERR_ILLEGAL_DEREF); + // dereference + emitIFormat(OP_LW, currentTemporary(), currentTemporary(), 0); - type = INT_T; - } + type = INT_T; // identifier? } else if (symbol == SYM_IDENTIFIER) { @@ -1969,111 +2075,107 @@ int gr_factor() { getSymbol(); - mayBeINTMINConstant = 0; - if (symbol == SYM_LPARENTHESIS) { getSymbol(); - // function call: identifier "(" ... ")" ... + // function call: identifier "(" ... ")" type = gr_call(variableOrProcedureName); - allocatedRegisters = allocatedRegisters + 1; + talloc(); - emitIFormat(OP_ADDIU, REG_RR, allocatedRegisters, 0); + emitIFormat(OP_ADDIU, REG_V0, currentTemporary(), 0); } else - // else.. it is just an 'identifier' + // variable access: identifier type = load_variable(variableOrProcedureName); // integer? } else if (symbol == SYM_INTEGER) { load_integer(); + + getSymbol(); + type = INT_T; // character? } else if (symbol == SYM_CHARACTER) { - mayBeINTMINConstant = 0; + talloc(); - allocatedRegisters = allocatedRegisters + 1; - - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, ivalue); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), constant); getSymbol(); + type = INT_T; + // string? + } else if (symbol == SYM_STRING) { + load_string(); + + getSymbol(); + + type = INTSTAR_T; + // "(" expression ")" } else if (symbol == SYM_LPARENTHESIS) { - mayBeINTMINConstant = 0; getSymbol(); + type = gr_expression(); if (symbol == SYM_RPARENTHESIS) getSymbol(); else - syntaxWarn(SYM_RPARENTHESIS); - } + syntaxErrorSymbol(SYM_RPARENTHESIS); + } else + syntaxErrorUnexpected(); - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 - if (cast == 0) - return type; - else + if (hasCast) return cast; + else + return type; } int gr_term() { int ltype; + int operatorSymbol; int rtype; - // assert: n = allocatedRegisters + // assert: n = allocatedTemporaries ltype = gr_factor(); - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 // * / or % ? while (isStarOrDivOrModulo()) { - if (symbol == SYM_ASTERISK) { - // assert: allocatedRegisters == n + 2 - getSymbol(); - rtype = gr_factor(); - - - if (ltype == rtype) { - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, 0, FCT_MULTU); - emitRFormat(OP_SPECIAL, 0, 0, allocatedRegisters-1, FCT_MFLO); - - allocatedRegisters = allocatedRegisters - 1; - } else - syntaxError(ERR_TYPE_MISMATCH); + operatorSymbol = symbol; - } else if (symbol == SYM_DIV) { - getSymbol(); - rtype = gr_factor(); + getSymbol(); + rtype = gr_factor(); - if (ltype == rtype) { - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, 0, FCT_DIVU); - emitRFormat(OP_SPECIAL, 0, 0, allocatedRegisters-1, FCT_MFLO); + // assert: allocatedTemporaries == n + 2 - allocatedRegisters = allocatedRegisters - 1; - } else - syntaxError(ERR_TYPE_MISMATCH); + if (ltype != rtype) + typeWarning(ltype, rtype); - } else if (symbol == SYM_MOD) { - getSymbol(); - rtype = gr_factor(); + if (operatorSymbol == SYM_ASTERISK) { + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), 0, FCT_MULTU); + emitRFormat(OP_SPECIAL, 0, 0, previousTemporary(), FCT_MFLO); - if (ltype == rtype) { - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, 0, FCT_DIVU); - emitRFormat(OP_SPECIAL, 0, 0, allocatedRegisters-1, FCT_MFHI); + } else if (operatorSymbol == SYM_DIV) { + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), 0, FCT_DIVU); + emitRFormat(OP_SPECIAL, 0, 0, previousTemporary(), FCT_MFLO); - allocatedRegisters = allocatedRegisters - 1; - } else - syntaxError(ERR_TYPE_MISMATCH); + } else if (operatorSymbol == SYM_MOD) { + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), 0, FCT_DIVU); + emitRFormat(OP_SPECIAL, 0, 0, previousTemporary(), FCT_MFHI); } + + tfree(1); } - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 return ltype; } @@ -2081,192 +2183,164 @@ int gr_term() { int gr_simpleExpression() { int sign; int ltype; - int rtype; int operatorSymbol; + int rtype; - // assert: n = allocatedRegisters + // assert: n = allocatedTemporaries // optional: - if (symbol == SYM_MINUS) { sign = 1; + mayBeINTMINConstant = 1; + isINTMINConstant = 0; + getSymbol(); + + mayBeINTMINConstant = 0; + + if (isINTMINConstant) { + isINTMINConstant = 0; + + // avoids 0-INT_MIN overflow when bootstrapping + // even though 0-INT_MIN == INT_MIN + sign = 0; + } } else sign = 0; ltype = gr_term(); - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 if (sign == 1) { - if (mayBeINTMINConstant) - // avoids 0-INT_MIN overflow when bootstrapping - // even though 0-INT_MIN == INT_MIN - mayBeINTMINConstant = 0; - else - emitRFormat(OP_SPECIAL, REG_ZR, allocatedRegisters, allocatedRegisters, FCT_SUBU); + if (ltype != INT_T) { + typeWarning(INT_T, ltype); + + ltype = INT_T; + } + + emitRFormat(OP_SPECIAL, REG_ZR, currentTemporary(), currentTemporary(), FCT_SUBU); } // + or -? while (isPlusOrMinus()) { operatorSymbol = symbol; + getSymbol(); rtype = gr_term(); - // assert: allocatedRegisters == n + 2 + // assert: allocatedTemporaries == n + 2 if (operatorSymbol == SYM_PLUS) { - if (ltype == rtype) { // base case, normal arithmetic - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_ADDU); - } else if (ltype == INTSTAR_T) { - if (rtype == INT_T) { - // pointer arithmetic requires factor of 2^2 - emitLeftShiftBy(2); - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_ADDU); - } else { - syntaxError(ERR_TYPE_MISMATCH); - } - } else if (rtype == INTSTAR_T) { - if (ltype == INT_T) { - // pointer arithmetic requires factor of 2^2 + if (ltype == INTSTAR_T) { + if (rtype == INT_T) + // pointer arithmetic: factor of 2^2 of integer operand emitLeftShiftBy(2); - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_ADDU); - } else - syntaxError(ERR_TYPE_MISMATCH); - } - } else { - if (ltype == rtype) - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_SUBU); - else - syntaxError(ERR_TYPE_MISMATCH); + } else if (rtype == INTSTAR_T) + typeWarning(ltype, rtype); + + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), previousTemporary(), FCT_ADDU); + + } else if (operatorSymbol == SYM_MINUS) { + if (ltype != rtype) + typeWarning(ltype, rtype); + + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), previousTemporary(), FCT_SUBU); } - allocatedRegisters = allocatedRegisters - 1; + tfree(1); } - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 return ltype; } int gr_expression() { int ltype; + int operatorSymbol; int rtype; - // assert: n = allocatedRegisters + // assert: n = allocatedTemporaries - ltype = gr_simpleExpression(); // type of left element + ltype = gr_simpleExpression(); - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 //optional: ==, !=, <, >, <=, >= simpleExpression - if (symbol == SYM_EQUAL) { + if (isComparison()) { + operatorSymbol = symbol; + getSymbol(); - rtype = gr_simpleExpression(); - // assert: allocatedRegisters == n + 2 + rtype = gr_simpleExpression(); - if (ltype == rtype) { - // subtract, if result = 0 then 1, else 0 - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_SUBU); + // assert: allocatedTemporaries == n + 2 - allocatedRegisters = allocatedRegisters - 1; + if (ltype != rtype) + typeWarning(ltype, rtype); - emitIFormat(OP_BEQ, REG_ZR, allocatedRegisters, 4); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 0); - emitIFormat(OP_BEQ, REG_ZR, allocatedRegisters, 2); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 1); - } else - syntaxError(ERR_TYPE_MISMATCH); + if (operatorSymbol == SYM_EQUALITY) { + // subtract, if result = 0 then 1, else 0 + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), previousTemporary(), FCT_SUBU); - } else if (symbol == SYM_NOTEQ) { - getSymbol(); - rtype = gr_simpleExpression(); + tfree(1); - // assert: allocatedRegisters == n + 2 + emitIFormat(OP_BEQ, REG_ZR, currentTemporary(), 4); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 0); + emitIFormat(OP_BEQ, REG_ZR, currentTemporary(), 2); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 1); - if (ltype == rtype) { + } else if (operatorSymbol == SYM_NOTEQ) { // subtract, if result = 0 then 0, else 1 - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_SUBU); - - allocatedRegisters = allocatedRegisters - 1; - - emitIFormat(OP_BNE, REG_ZR, allocatedRegisters, 4); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 0); - emitIFormat(OP_BEQ, REG_ZR, allocatedRegisters, 2); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 1); - } else - syntaxError(ERR_TYPE_MISMATCH); + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), previousTemporary(), FCT_SUBU); - } else if (symbol == SYM_LT) { - getSymbol(); - rtype = gr_simpleExpression(); + tfree(1); - // assert: allocatedRegisters == n + 2 + emitIFormat(OP_BNE, REG_ZR, currentTemporary(), 4); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 0); + emitIFormat(OP_BEQ, REG_ZR, currentTemporary(), 2); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 1); - if (ltype == rtype) { + } else if (operatorSymbol == SYM_LT) { // set to 1 if a < b, else 0 - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_SLT); - - allocatedRegisters = allocatedRegisters - 1; - } else - syntaxError(ERR_TYPE_MISMATCH); - - } else if (symbol == SYM_GT) { - getSymbol(); - rtype = gr_simpleExpression(); + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), previousTemporary(), FCT_SLT); - // assert: allocatedRegisters == n + 2 + tfree(1); - if (ltype == rtype) { + } else if (operatorSymbol == SYM_GT) { // set to 1 if b < a, else 0 - emitRFormat(OP_SPECIAL, allocatedRegisters, allocatedRegisters-1, allocatedRegisters-1, FCT_SLT); + emitRFormat(OP_SPECIAL, currentTemporary(), previousTemporary(), previousTemporary(), FCT_SLT); - allocatedRegisters = allocatedRegisters - 1; - } else - syntaxError(ERR_TYPE_MISMATCH); - - } else if (symbol == SYM_LEQ) { - getSymbol(); - rtype = gr_simpleExpression(); - - // assert: allocatedRegisters == n + 2 + tfree(1); - if (ltype == rtype) { + } else if (operatorSymbol == SYM_LEQ) { // if b < a set 0, else 1 - emitRFormat(OP_SPECIAL, allocatedRegisters, allocatedRegisters-1, allocatedRegisters-1, FCT_SLT); + emitRFormat(OP_SPECIAL, currentTemporary(), previousTemporary(), previousTemporary(), FCT_SLT); - allocatedRegisters = allocatedRegisters - 1; + tfree(1); - emitIFormat(OP_BNE, REG_ZR, allocatedRegisters, 4); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 1); + emitIFormat(OP_BNE, REG_ZR, currentTemporary(), 4); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 1); emitIFormat(OP_BEQ, REG_ZR, REG_ZR, 2); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 0); - } else - syntaxError(ERR_TYPE_MISMATCH); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 0); - } else if (symbol == SYM_GEQ) { - getSymbol(); - rtype = gr_simpleExpression(); - - // assert: allocatedRegisters == n + 2 - - if (ltype == rtype) { + } else if (operatorSymbol == SYM_GEQ) { // if a < b set 0, else 1 - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_SLT); + emitRFormat(OP_SPECIAL, previousTemporary(), currentTemporary(), previousTemporary(), FCT_SLT); - allocatedRegisters = allocatedRegisters - 1; + tfree(1); - emitIFormat(OP_BNE, REG_ZR, allocatedRegisters, 4); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 1); + emitIFormat(OP_BNE, REG_ZR, currentTemporary(), 4); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 1); emitIFormat(OP_BEQ, REG_ZR, REG_ZR, 2); - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters, 0); - } else - syntaxError(ERR_TYPE_MISMATCH); + emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 0); + } } - // assert: allocatedRegisters == n + 1 + // assert: allocatedTemporaries == n + 1 return ltype; } @@ -2275,75 +2349,92 @@ void gr_while() { int brBackToWhile; int brForwardToEnd; - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 + + brBackToWhile = binaryLength; - brBackToWhile = codeLength; + brForwardToEnd = 0; // while ( expression ) if (symbol == SYM_WHILE) { getSymbol(); + if (symbol == SYM_LPARENTHESIS) { getSymbol(); + gr_expression(); - //don't know where to branch, fixup later - brForwardToEnd = codeLength; - emitIFormat(OP_BEQ, REG_ZR, allocatedRegisters, 0); - allocatedRegisters = allocatedRegisters - 1; + // do not know where to branch, fixup later + brForwardToEnd = binaryLength; + + emitIFormat(OP_BEQ, REG_ZR, currentTemporary(), 0); + + tfree(1); if (symbol == SYM_RPARENTHESIS) { getSymbol(); + // zero or more statements: { statement } if (symbol == SYM_LBRACE) { getSymbol(); + while (isNotRbraceOrEOF()) gr_statement(); if (symbol == SYM_RBRACE) getSymbol(); - else - syntaxWarn(SYM_RBRACE); + else { + syntaxErrorSymbol(SYM_RBRACE); + + exit(-1); + } } // only one statement without {} else gr_statement(); } else - syntaxError(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); } else - syntaxError(SYM_LPARENTHESIS); + syntaxErrorSymbol(SYM_LPARENTHESIS); } else - syntaxError(SYM_WHILE); + syntaxErrorSymbol(SYM_WHILE); // unconditional branch to beginning of while - emitIFormat(OP_BEQ, 0, 0, brBackToWhile - codeLength - 1); + emitIFormat(OP_BEQ, 0, 0, (brBackToWhile - binaryLength - 4) / 4); - // first instr after loop comes here, now we have - // our address for the conditional jump from above - fixup_relative(brForwardToEnd); + if (brForwardToEnd != 0) + // first instruction after loop comes here + // now we have our address for the conditional jump from above + fixup_relative(brForwardToEnd); - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 } void gr_if() { int brForwardToElseOrEnd; int brForwardToEnd; - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 // if ( expression ) if (symbol == SYM_IF) { getSymbol(); + if (symbol == SYM_LPARENTHESIS) { getSymbol(); + gr_expression(); // if the "if" case is not true, we jump to "else" (if provided) - brForwardToElseOrEnd = codeLength; - emitIFormat(OP_BEQ, REG_ZR, allocatedRegisters, 0); - allocatedRegisters = allocatedRegisters - 1; + brForwardToElseOrEnd = binaryLength; + + emitIFormat(OP_BEQ, REG_ZR, currentTemporary(), 0); + + tfree(1); if (symbol == SYM_RPARENTHESIS) { getSymbol(); + // zero or more statements: { statement } if (symbol == SYM_LBRACE) { getSymbol(); @@ -2353,8 +2444,11 @@ void gr_if() { if (symbol == SYM_RBRACE) getSymbol(); - else - syntaxWarn(SYM_RBRACE); + else { + syntaxErrorSymbol(SYM_RBRACE); + + exit(-1); + } } // only one statement without {} else @@ -2365,7 +2459,7 @@ void gr_if() { getSymbol(); // if the "if" case was true, we jump to the end - brForwardToEnd = codeLength; + brForwardToEnd = binaryLength; emitIFormat(OP_BEQ, 0, 0, 0); // if the "if" case was not true, we jump here @@ -2374,13 +2468,18 @@ void gr_if() { // zero or more statements: { statement } if (symbol == SYM_LBRACE) { getSymbol(); + while (isNotRbraceOrEOF()) gr_statement(); if (symbol == SYM_RBRACE) getSymbol(); - else - syntaxWarn(SYM_RBRACE); + else { + syntaxErrorSymbol(SYM_RBRACE); + + exit(-1); + } + // only one statement without {} } else gr_statement(); @@ -2391,142 +2490,144 @@ void gr_if() { // if the "if" case was not true, we jump here fixup_relative(brForwardToElseOrEnd); } else - syntaxError(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); } else - syntaxError(SYM_LPARENTHESIS); + syntaxErrorSymbol(SYM_LPARENTHESIS); } else - syntaxError(SYM_IF); + syntaxErrorSymbol(SYM_IF); - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 } void gr_return(int returnType) { - // assert: allocatedRegisters == 0 + int type; + + // assert: allocatedTemporaries == 0 - // keyword return if (symbol == SYM_RETURN) getSymbol(); else - syntaxError(SYM_RETURN); + syntaxErrorSymbol(SYM_RETURN); // optional: expression if (symbol != SYM_SEMICOLON) { - if (returnType != VOID_T) { - // TODO check for other wrong types, too - gr_expression(); + type = gr_expression(); - // save value of expression in return register - emitRFormat(OP_SPECIAL, REG_ZR, allocatedRegisters, REG_RR, FCT_ADDU); - allocatedRegisters = allocatedRegisters - 1; - } else - syntaxError(ERR_WRONG_RETURNTYPE); + if (returnType == VOID_T) + typeWarning(type, returnType); + else if (type != returnType) + typeWarning(returnType, type); + + // save value of expression in return register + emitRFormat(OP_SPECIAL, REG_ZR, currentTemporary(), REG_V0, FCT_ADDU); + + tfree(1); } // unconditional branch to procedure epilogue // maintain fixup chain for later fixup - emitJFormat(OP_J, returnBranches); + emitJFormat(OP_J, returnBranches / 4); // new head of fixup chain - returnBranches = codeLength-2; + // offest is 8 rather than 4 bytes because of delay slot NOP + returnBranches = binaryLength - 8; - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 } void gr_statement() { + int ltype; + int rtype; int *variableOrProcedureName; int *entry; - // assert: allocatedRegisters == 0; + // assert: allocatedTemporaries == 0; + + while (lookForStatement()) { + syntaxErrorUnexpected(); - while (waitForStatement()) - syntaxError(ERR_STATEMENT); + if (symbol == SYM_EOF) + exit(-1); + else + getSymbol(); + } // ["*"] if (symbol == SYM_ASTERISK) { getSymbol(); - // ["*"] identifier + + // "*" identifier if (symbol == SYM_IDENTIFIER) { - load_variable(identifier); + ltype = load_variable(identifier); + + if (ltype != INTSTAR_T) + typeWarning(INTSTAR_T, ltype); + getSymbol(); - // ["*"] identifier "=" + // "*" identifier "=" if (symbol == SYM_ASSIGN) { getSymbol(); - gr_expression(); + rtype = gr_expression(); + + if (rtype != INT_T) + typeWarning(INT_T, rtype); + + emitIFormat(OP_SW, previousTemporary(), currentTemporary(), 0); - emitIFormat(OP_SW, allocatedRegisters-1, allocatedRegisters, 0); - allocatedRegisters = allocatedRegisters - 2; + tfree(2); } else - syntaxError(ERR_ASSIGN); + syntaxErrorSymbol(SYM_ASSIGN); if (symbol == SYM_SEMICOLON) getSymbol(); else - syntaxWarn(SYM_SEMICOLON); + syntaxErrorSymbol(SYM_SEMICOLON); - // "*" "(" identifier [ "+" integer ] + // "*" "(" expression ")" } else if (symbol == SYM_LPARENTHESIS) { getSymbol(); - if (symbol == SYM_IDENTIFIER) { - load_variable(identifier); - - getSymbol(); - - if (symbol == SYM_PLUS) { - getSymbol(); - if (symbol == SYM_IDENTIFIER) { - load_variable(identifier); - getSymbol(); - } else if (symbol == SYM_INTEGER) - load_integer(); - else - syntaxError(ERR_IDENTIFIER_OR_INTEGER); + ltype = gr_expression(); - // pointer arithmetic requires factor of 2^2 - emitLeftShiftBy(2); - emitRFormat(OP_SPECIAL, allocatedRegisters-1, allocatedRegisters, allocatedRegisters-1, FCT_ADDU); + if (ltype != INTSTAR_T) + typeWarning(INTSTAR_T, ltype); - allocatedRegisters = allocatedRegisters - 1; - } + if (symbol == SYM_RPARENTHESIS) { + getSymbol(); - if (symbol == SYM_RPARENTHESIS) { + // "*" "(" expression ")" "=" + if (symbol == SYM_ASSIGN) { getSymbol(); - // "*" "(" identifier ["+" integer] ")" =" - if (symbol == SYM_ASSIGN) { - getSymbol(); - - gr_expression(); + rtype = gr_expression(); - emitIFormat(OP_SW, allocatedRegisters-1, allocatedRegisters, 0); + if (rtype != INT_T) + typeWarning(INT_T, rtype); - allocatedRegisters = allocatedRegisters - 2; - } else - syntaxError(ERR_ASSIGN); + emitIFormat(OP_SW, previousTemporary(), currentTemporary(), 0); - if (symbol == SYM_SEMICOLON) - getSymbol(); - else - syntaxWarn(SYM_SEMICOLON); + tfree(2); } else - syntaxWarn(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_ASSIGN); + + if (symbol == SYM_SEMICOLON) + getSymbol(); + else + syntaxErrorSymbol(SYM_SEMICOLON); } else - syntaxError(ERR_IDENTIFIER); + syntaxErrorSymbol(SYM_RPARENTHESIS); } else - syntaxError(SYM_LPARENTHESIS); + syntaxErrorSymbol(SYM_LPARENTHESIS); } - - // identifier = [ "*" ] identifier "=" expression ";" | - // identifier = call ";" - // call; + // identifier "=" expression | call else if (symbol == SYM_IDENTIFIER) { variableOrProcedureName = identifier; getSymbol(); - // call ";" + // call if (symbol == SYM_LPARENTHESIS) { getSymbol(); @@ -2535,24 +2636,31 @@ void gr_statement() { if (symbol == SYM_SEMICOLON) getSymbol(); else - syntaxWarn(SYM_SEMICOLON); + syntaxErrorSymbol(SYM_SEMICOLON); - // identifier = expression ";" + // identifier = expression } else if (symbol == SYM_ASSIGN) { entry = getVariable(variableOrProcedureName); + + ltype = getType(entry); + getSymbol(); - gr_expression(); - emitIFormat(OP_SW, getRegister(entry), allocatedRegisters, getData(entry)); + rtype = gr_expression(); + + if (ltype != rtype) + typeWarning(ltype, rtype); - allocatedRegisters = allocatedRegisters - 1; + emitIFormat(OP_SW, getRegister(entry), currentTemporary(), getData(entry)); + + tfree(1); if (symbol == SYM_SEMICOLON) getSymbol(); else - syntaxError(SYM_SEMICOLON); + syntaxErrorSymbol(SYM_SEMICOLON); } else - syntaxError(ERR_IDENTIFIER_OR_ASSIGN); + syntaxErrorUnexpected(); } // while statement? else if (symbol == SYM_WHILE) { @@ -2564,28 +2672,23 @@ void gr_statement() { } // return statement? else if (symbol == SYM_RETURN) { - entry = getSymbolTableEntry(currentFuncName, global_symbol_table); + entry = getSymbolTableEntry(currentProcedureName, FUNCTION, global_symbol_table); gr_return(getType(entry)); if (symbol == SYM_SEMICOLON) getSymbol(); else - syntaxWarn(SYM_SEMICOLON); + syntaxErrorSymbol(SYM_SEMICOLON); } } -int gr_variable() { +int gr_type() { int type; - while (waitForVariable()) - syntaxError(ERR_TYPE); - - type = UNKNOWN; + type = INT_T; if (symbol == SYM_INT) { - type = INT_T; - getSymbol(); if (symbol == SYM_ASTERISK) { @@ -2593,117 +2696,204 @@ int gr_variable() { getSymbol(); } - - if (symbol != SYM_IDENTIFIER) - syntaxError(ERR_IDENTIFIER); } else - syntaxError(ERR_EOF); + syntaxErrorSymbol(SYM_INT); return type; } +void gr_variable(int offset) { + int type; + + type = gr_type(); + + if (symbol == SYM_IDENTIFIER) { + createSymbolTableEntry(LOCAL_TABLE, identifier, offset, VARIABLE, type, 0); + + getSymbol(); + } else { + syntaxErrorSymbol(SYM_IDENTIFIER); + + createSymbolTableEntry(LOCAL_TABLE, (int*) "missing variable name", offset, VARIABLE, type, 0); + } +} + +void gr_initialization(int *name, int offset, int type) { + int hasCast; + int cast; + int sign; + + initialValue = 0; + + hasCast = 0; + + if (symbol == SYM_SEMICOLON) + getSymbol(); + else if (symbol == SYM_ASSIGN) { + getSymbol(); + + // optional cast: [ cast ] + if (symbol == SYM_LPARENTHESIS) { + hasCast = 1; + + getSymbol(); + + cast = gr_type(); + + if (symbol == SYM_RPARENTHESIS) + getSymbol(); + else + syntaxErrorSymbol(SYM_RPARENTHESIS); + } + + // optional: - + if (symbol == SYM_MINUS) { + sign = 1; + + mayBeINTMINConstant = 1; + isINTMINConstant = 0; + + getSymbol(); + + mayBeINTMINConstant = 0; + + if (isINTMINConstant) { + isINTMINConstant = 0; + + // avoids 0-INT_MIN overflow when bootstrapping + // even though 0-INT_MIN == INT_MIN + sign = 0; + } + } else + sign = 0; + + if (isConstant()) { + initialValue = constant; + + getSymbol(); + + if (sign == 1) + initialValue = -initialValue; + } else + syntaxErrorUnexpected(); + + if (symbol == SYM_SEMICOLON) + getSymbol(); + else + syntaxErrorSymbol(SYM_SEMICOLON); + } else + syntaxErrorUnexpected(); + + if (hasCast) { + if (type != cast) + typeWarning(type, cast); + } else if (type != INT_T) + typeWarning(type, INT_T); + + createSymbolTableEntry(GLOBAL_TABLE, name, offset, VARIABLE, type, initialValue); +} + void gr_procedure(int *procedure, int returnType) { + int numberOfParameters; int parameters; - int oparam; - int offset; int localVariables; - int type; int functionStart; int *entry; - currentFuncName = procedure; + currentProcedureName = procedure; - oparam = 0; + numberOfParameters = 0; // ( variable , variable ) ; if (symbol == SYM_LPARENTHESIS) { getSymbol(); - parameters = 0; - if (symbol != SYM_RPARENTHESIS) { - type = gr_variable(); + gr_variable(0); - createSymbolTableEntry(LOCAL_TABLE, identifier, 0, VARIABLE, type); - - getSymbol(); - - parameters = 1; + numberOfParameters = 1; while (symbol == SYM_COMMA) { getSymbol(); - type = gr_variable(); - - createSymbolTableEntry(LOCAL_TABLE, identifier, 0, VARIABLE, type); + gr_variable(0); - getSymbol(); - - parameters = parameters + 1; + numberOfParameters = numberOfParameters + 1; } - oparam = parameters; entry = local_symbol_table; - offset = 8; // skip fp and link - while (parameters > 0) { - setData(entry, offset); - parameters = parameters - 1; - offset = offset + 4; + + parameters = 0; + + while (parameters < numberOfParameters) { + // 8 bytes offset to skip frame pointer and link + setData(entry, parameters * 4 + 8); + + parameters = parameters + 1; entry = getNext(entry); } if (symbol == SYM_RPARENTHESIS) getSymbol(); else - syntaxWarn(SYM_RPARENTHESIS); + syntaxErrorSymbol(SYM_RPARENTHESIS); } else getSymbol(); } else - syntaxError(SYM_LPARENTHESIS); + syntaxErrorSymbol(SYM_LPARENTHESIS); if (symbol == SYM_SEMICOLON) { - entry = getSymbolTableEntry(currentFuncName, global_symbol_table); + entry = getSymbolTableEntry(currentProcedureName, FUNCTION, global_symbol_table); - if ((int)entry == 0) - createSymbolTableEntry(GLOBAL_TABLE, currentFuncName, 0, FUNCTION, returnType); + if (entry == (int*) 0) + createSymbolTableEntry(GLOBAL_TABLE, currentProcedureName, 0, FUNCTION, returnType, 0); getSymbol(); // ( variable, variable ) { variable; variable; statement } } else if (symbol == SYM_LBRACE) { - functionStart = codeLength; + functionStart = binaryLength; + getSymbol(); - localVariables = 0; - entry = getSymbolTableEntry(currentFuncName, global_symbol_table); + entry = getSymbolTableEntry(currentProcedureName, FUNCTION, global_symbol_table); - if ((int)entry == 0) { - createSymbolTableEntry(GLOBAL_TABLE, currentFuncName, codeLength, FUNCTION, returnType); - } else { - if (getData(entry) != 0) - if (getOpcode(*(memory + getData(entry))) == OP_JAL) + if (entry == (int*) 0) + createSymbolTableEntry(GLOBAL_TABLE, currentProcedureName, binaryLength, FUNCTION, returnType, 0); + else { + if (getData(entry) != 0) { + if (getOpcode(loadMemory(getData(entry))) == OP_JAL) fixlink_absolute(getData(entry), functionStart); + else { + printLineNumber((int*) "error"); + + print((int*) "multiple definitions of "); + + print(currentProcedureName); + + println(); + } + } - // TODO: overwrites previous definitions setData(entry, functionStart); - // TODO: check type of declaration and definition + if (getType(entry) != returnType) + typeWarning(getType(entry), returnType); + setType(entry, returnType); } - while (symbol == SYM_INT) { - type = gr_variable(); + localVariables = 0; + while (symbol == SYM_INT) { localVariables = localVariables + 1; - createSymbolTableEntry(LOCAL_TABLE, identifier, -4 * localVariables, VARIABLE, type); - - getSymbol(); + gr_variable(-4 * localVariables); if (symbol == SYM_SEMICOLON) getSymbol(); else - syntaxWarn(SYM_SEMICOLON); + syntaxErrorSymbol(SYM_SEMICOLON); } help_procedure_prologue(localVariables); @@ -2716,84 +2906,81 @@ void gr_procedure(int *procedure, int returnType) { if (symbol == SYM_RBRACE) getSymbol(); - else - syntaxWarn(SYM_RBRACE); + else { + syntaxErrorSymbol(SYM_RBRACE); + + exit(-1); + } - fixlink_absolute(returnBranches, codeLength); + fixlink_absolute(returnBranches, binaryLength); returnBranches = 0; - help_procedure_epilogue(oparam, functionStart, returnType); + help_procedure_epilogue(numberOfParameters); } else - syntaxError(ERR_LBRACE_OR_SEMICOLON); + syntaxErrorUnexpected(); - local_symbol_table = 0; + local_symbol_table = (int*) 0; - // assert: allocatedRegisters == 0 + // assert: allocatedTemporaries == 0 } void gr_cstar() { - int offset; int type; int *variableOrProcedureName; - type = UNKNOWN; + while (symbol != SYM_EOF) { + while (lookForType()) { + syntaxErrorUnexpected(); - while (isVariableOrProcedure()) { - // type identifier - if (symbol == SYM_INT) { - type = INT_T; + if (symbol == SYM_EOF) + exit(-1); + else + getSymbol(); + } - getSymbol(); + // void identifier procedure + if (symbol == SYM_VOID) { + type = VOID_T; - if (symbol == SYM_ASTERISK) { - type = INTSTAR_T; - getSymbol(); - } + getSymbol(); if (symbol == SYM_IDENTIFIER) { variableOrProcedureName = identifier; getSymbol(); - // type identifier, this means it is a global variable - if (symbol == SYM_SEMICOLON) { - getSymbol(); - - offset = allocatedGlobalVariables * (-4); - - createSymbolTableEntry(GLOBAL_TABLE, variableOrProcedureName, offset, VARIABLE, type); - - allocatedGlobalVariables = allocatedGlobalVariables + 1; - } - // type identifier procedure - else - gr_procedure(variableOrProcedureName, type); + gr_procedure(variableOrProcedureName, type); } else - syntaxError(ERR_IDENTIFIER); - - // void identifier procedure - } else if (symbol == SYM_VOID) { - type = VOID_T; - getSymbol(); + syntaxErrorSymbol(SYM_IDENTIFIER); + } else { + type = gr_type(); if (symbol == SYM_IDENTIFIER) { variableOrProcedureName = identifier; getSymbol(); - gr_procedure(variableOrProcedureName, type); - } - } else - syntaxError(ERR_PROCEDURE_OR_VARIABLE); - } + // type identifier "(" procedure declaration or definition + if (symbol == SYM_LPARENTHESIS) + gr_procedure(variableOrProcedureName, type); + else { + allocatedMemory = allocatedMemory + 4; - // when we leave while, we don't expect any more - // code to come, but if it does, it's a syntax error - if (symbol != SYM_EOF) { - syntaxError(ERR_EOF); - exit(-1); + // type identifier ";" global variable declaration + if (symbol == SYM_SEMICOLON) { + getSymbol(); + + createSymbolTableEntry(GLOBAL_TABLE, variableOrProcedureName, -allocatedMemory, VARIABLE, type, 0); + + // type identifier "=" global variable definition + } else + gr_initialization(variableOrProcedureName, -allocatedMemory, type); + } + } else + syntaxErrorSymbol(SYM_IDENTIFIER); + } } } @@ -2805,20 +2992,18 @@ void emitLeftShiftBy(int b) { // assert: 0 <= b < 15 // load multiplication factor less than 2^15 to avoid sign extension - emitIFormat(OP_ADDIU, REG_ZR, allocatedRegisters+1, twoToThePowerOf(b)); - emitRFormat(OP_SPECIAL, allocatedRegisters, allocatedRegisters+1, 0, FCT_MULTU); - emitRFormat(OP_SPECIAL, 0, 0, allocatedRegisters, FCT_MFLO); + emitIFormat(OP_ADDIU, REG_ZR, nextTemporary(), twoToThePowerOf(b)); + emitRFormat(OP_SPECIAL, currentTemporary(), nextTemporary(), 0, FCT_MULTU); + emitRFormat(OP_SPECIAL, 0, 0, currentTemporary(), FCT_MFLO); } void emitMainEntry() { - int *label; - - emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_NOP); // null page + // instruction at address zero cannot be fixed up + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_NOP); - // "main": entry point - label = (int*)createString('m','a','i','n',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "main", binaryLength, FUNCTION, INT_T, 0); - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + mainJumpAddress = binaryLength; emitJFormat(OP_JAL, 0); } @@ -2829,28 +3014,37 @@ void emitMainEntry() { int main_compiler() { initScanner(); - initSymbolTable(); initParser(); - allocateMachineMemory(maxCodeLength*4); + // memory in bytes and executable file name "out" + initMemory(maxBinaryLength, (int*) "out"); getSymbol(); + // jump to main emitMainEntry(); - // Library functions: - emitExit(); // first library function because this marks - // also 'default'-exit when programmer hasn't - // inserted exit() call in main + // library: + // exit must be first to exit main + // if exit call in main is missing + emitExit(); emitRead(); emitWrite(); emitOpen(); emitMalloc(); emitGetchar(); emitPutchar(); + emitYield(); - gr_cstar(); // invoke compiler - emitBinary(); + // parser + gr_cstar(); + + if (getInstrIndex(loadMemory(mainJumpAddress)) != 0) + emitBinary(); + else { + print((int*) "cstarc: main function missing"); + println(); + } exit(0); } @@ -2861,6 +3055,16 @@ int main_compiler() { // ----------------------------------------------------------------- // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ +void schedule_and_switch(); + +// ----------------------------------------------------------------- +// ---------------------------- REGISTER --------------------------- +// ----------------------------------------------------------------- + +void printRegister(int reg) { + print((int*) *(REGISTERS + reg)); +} + // ----------------------------------------------------------------- // ---------------------------- ENCODER ---------------------------- // ----------------------------------------------------------------- @@ -2953,6 +3157,14 @@ int signExtend(int immediate) { // ---------------------------- DECODER ---------------------------- // ----------------------------------------------------------------- +void printOpcode(int opcode) { + print((int*) *(OPCODES + opcode)); +} + +void printFunction(int function) { + print((int*) *(FUNCTIONS + function)); +} + void decode() { opcode = getOpcode(ir); @@ -3018,8 +3230,20 @@ void decodeJFormat() { // ---------------------------- MEMORY ----------------------------- // ----------------------------------------------------------------- -void allocateMachineMemory(int size) { - memory = (int*)malloc(size); +int tlb(int vaddr) { + if (vaddr % 4 != 0) + exception_handler(EXCEPTION_ADDRESSERROR); + + // physical memory is word-addressed for lack of byte-sized data type + return vaddr / 4; +} + +int loadMemory(int vaddr) { + return *(memory + tlb(vaddr)); +} + +void storeMemory(int vaddr, int data) { + *(memory + tlb(vaddr)) = data; } // ----------------------------------------------------------------- @@ -3027,12 +3251,13 @@ void allocateMachineMemory(int size) { // ----------------------------------------------------------------- void emitInstruction(int instruction) { - if (codeLength >= maxCodeLength) { - syntaxError(ERR_MAXCODELENGTH); + if (binaryLength >= maxBinaryLength) { + syntaxErrorMessage((int*) "exceeded maximum binary length"); exit(-1); } else { - *(memory + codeLength) = instruction; - codeLength = codeLength + 1; + storeMemory(binaryLength, instruction); + + binaryLength = binaryLength + 4; } } @@ -3070,95 +3295,111 @@ void emitJFormat(int opcode, int instr_index) { } void fixup_relative(int fromAddress) { - *(memory + fromAddress) = encodeIFormat( - getOpcode(*(memory + fromAddress)), - getRS(*(memory + fromAddress)), - getRT(*(memory + fromAddress)), - codeLength - fromAddress - 1); + int instruction; + + instruction = loadMemory(fromAddress); + + storeMemory(fromAddress, + encodeIFormat(getOpcode(instruction), + getRS(instruction), + getRT(instruction), + (binaryLength - fromAddress - 4) / 4)); } void fixup_absolute(int fromAddress, int toAddress) { - *(memory + fromAddress) = - encodeJFormat(getOpcode(*(memory + fromAddress)), toAddress); + storeMemory(fromAddress, + encodeJFormat(getOpcode(loadMemory(fromAddress)), toAddress / 4)); } void fixlink_absolute(int fromAddress, int toAddress) { int previousAddress; while (fromAddress != 0) { - previousAddress = getInstrIndex(*(memory + fromAddress)); + previousAddress = getInstrIndex(loadMemory(fromAddress)) * 4; fixup_absolute(fromAddress, toAddress); fromAddress = previousAddress; } } +int copyStringToMemory(int *s, int a) { + int l; + int w; + + l = stringLength(s) + 1; + + w = a + l; + + if (l % 4 != 0) + w = w + 4 - l % 4; + + while (a < w) { + storeMemory(a, *s); + + s = s + 1; + a = a + 4; + } + + return w; +} + void emitBinary() { - int i; - int *filename; + int *entry; int fd; - i = 0; + entry = global_symbol_table; - // put global variables as 0 at end of codearray - while (i < allocatedGlobalVariables) { - *(memory + codeLength) = 0; + // allocate space for global variables and copy strings + while ((int) entry != 0) { + if (getClass(entry) == VARIABLE) { + storeMemory(binaryLength, getValue(entry)); - codeLength = codeLength + 1; + binaryLength = binaryLength + 4; + } else if (getClass(entry) == STRING) + binaryLength = copyStringToMemory(getString(entry), binaryLength); - i = i + 1; + entry = getNext(entry); } - filename = (int*)malloc(4*4); - *filename = 7632239; //filename: out - - // assumption: file with name "out" exists prior to execution of compiler - fd = open(filename, 1); // 1 = O_WRONLY + // assert: file with name binaryName exists prior to execution of compiler + fd = open(binaryName, 1); // 1 = O_WRONLY if (fd < 0) { - syntaxError(ERR_FILE_NOT_FOUND); + syntaxErrorMessage((int*) "output file not found"); exit(-1); } - // The mipster_sycall 4004 writes the code array into a binary called 'out'. - // The syscall uses the 'write' system call of the underlying operating - // system and the compiler (gcc/x86). The write system call of our Linux uses - // Little Endian byte ordering. - write(fd, memory, codeLength*4); + // The mipster_syscall 4004 writes the code array into a file. + // The syscall uses the "write" system call of the OS and compiler. + // The write system call of our Linux uses little endian byte ordering. + write(fd, memory, binaryLength); } -int loadBinary(int *filename) { +void loadBinary() { int fd; - int i; - int ret; + int numberOfReadBytes; - fd = open(filename, 0); + fd = open(binaryName, 0); // 0 = O_RDONLY if (fd < 0) exit(-1); - i = 0; - - ret = 4; + numberOfReadBytes = 4; - while (ret == 4) { - ret = read(fd, memory + i, 4); + while (numberOfReadBytes == 4) { + numberOfReadBytes = read(fd, memory + tlb(binaryLength), 4); if (debug_load) { - memset(string_buffer, 33, 0); - print(itoa(i * 4, string_buffer, 16, 4)); - putchar(' '); - putchar('#'); - putchar(' '); - memset(string_buffer, 33, 0); - print(itoa(*(memory+i), string_buffer, 16, 8)); - putchar(CHAR_LF); + print(binaryName); + print((int*) ": "); + print(itoa(binaryLength, string_buffer, 16, 8)); + print((int*) ": "); + print(itoa(loadMemory(binaryLength), string_buffer, 16, 8)); + println(); } - i = i + 1; + if (numberOfReadBytes == 4) + binaryLength = binaryLength + 4; } - - // Return global pointer and bump pointer for malloc - return i * 4; } // ----------------------------------------------------------------- @@ -3166,12 +3407,7 @@ int loadBinary(int *filename) { // ----------------------------------------------------------------- void emitExit() { - int *label; - - // "exit" - label = createString('e','x','i','t',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "exit", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); @@ -3189,24 +3425,18 @@ void syscall_exit() { exitCode = *(registers+REG_A0); - printString('[','O','S',']',' ','T', 'e', 'r','m','i','n','a','t','e','d',' ','w','i','t','h'); - putchar(' '); - *(registers+REG_V0) = exitCode; + print(binaryName); + print((int*) ": exiting with error code "); print(itoa(exitCode, string_buffer, 10, 0)); - putchar(CHAR_LF); + println(); exit(0); } void emitRead() { - int *label; - - // "read" - label = createString('r','e','a','d',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "read", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); @@ -3222,48 +3452,40 @@ void emitRead() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_READ); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitIFormat(OP_ADDIU, REG_V0, REG_RR, 0); - - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } void syscall_read() { int count; - int address; + int vaddr; int fd; int *buffer; int size; - count = *(registers+REG_A2); - address = *(registers+REG_A1) / 4; - fd = *(registers+REG_A0); + count = *(registers+REG_A2); + vaddr = *(registers+REG_A1); + fd = *(registers+REG_A0); - buffer = memory + address; + buffer = memory + tlb(vaddr); size = read(fd, buffer, count); *(registers+REG_V0) = size; - if (debug_syscalls) { - printString('[','O','S',']',' ','c', 'a', 'l','l',' ','r','e','a','d',' ',CHAR_TAB,0,0,0,0); - - print(itoa(fd, string_buffer, 10, 0)); - putchar(' '); - memset(string_buffer, 33, 0); - print(itoa((int)buffer, string_buffer, 16, 8)); - putchar(' '); + if (debug_read) { + print(binaryName); + print((int*) ": read "); print(itoa(size, string_buffer, 10, 0)); - putchar(CHAR_LF); + print((int*) " bytes from file with descriptor "); + print(itoa(fd, string_buffer, 10, 0)); + print((int*) " into buffer at address "); + print(itoa((int) buffer, string_buffer, 16, 8)); + println(); } } void emitWrite() { - int *label; - - // "write" - label = createString('w','r','i','t','e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "write", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); @@ -3279,38 +3501,39 @@ void emitWrite() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_WRITE); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitIFormat(OP_ADDIU, REG_V0, REG_RR, 0); - - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } void syscall_write() { int size; - int address; + int vaddr; int fd; int *buffer; - size = *(registers+REG_A2); - address = *(registers+REG_A1) / 4; - fd = *(registers+REG_A0); + size = *(registers+REG_A2); + vaddr = *(registers+REG_A1); + fd = *(registers+REG_A0); - buffer = memory + address; + buffer = memory + tlb(vaddr); size = write(fd, buffer, size); *(registers+REG_V0) = size; - if (debug_syscalls) - printString('[','O','S',']',' ','c', 'a', 'l','l',' ','w','r','i','t','e',CHAR_LF,0,0,0,0); + if (debug_write) { + print(binaryName); + print((int*) ": wrote "); + print(itoa(size, string_buffer, 10, 0)); + print((int*) " bytes from buffer at address "); + print(itoa((int) buffer, string_buffer, 16, 8)); + print((int*) " into file with descriptor "); + print(itoa(fd, string_buffer, 10, 0)); + println(); + } } void emitOpen() { - int *label; - - // "open" - label = createString('o','p','e','n',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "open", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); @@ -3324,41 +3547,38 @@ void emitOpen() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_OPEN); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitIFormat(OP_ADDIU, REG_V0, REG_RR, 0); - - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } void syscall_open() { int flags; - int address; + int vaddr; int *filename; int fd; - flags = *(registers+REG_A1); - address = *(registers+REG_A0) / 4; + flags = *(registers+REG_A1); + vaddr = *(registers+REG_A0); - filename = memory + address; + filename = memory + tlb(vaddr); fd = open(filename, flags); *(registers+REG_V0) = fd; - if (debug_syscalls) { - printString('[','O','S',']',' ','c', 'a', 'l','l',' ','o','p','e','n',' ',CHAR_TAB,0,0,0,0); - + if (debug_open) { + print(binaryName); + print((int*) ": opened file "); + printString(filename); + print((int*) " with flags "); + print(itoa(flags, string_buffer, 10, 0)); + print((int*) " returning file descriptor "); print(itoa(fd, string_buffer, 10, 0)); - putchar(CHAR_LF); + println(); } } void emitMalloc() { - int *label; - - // "malloc" - label = createString('m','a','l','l','o','c',0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INTSTAR_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "malloc", binaryLength, FUNCTION, INTSTAR_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); @@ -3374,11 +3594,8 @@ void emitMalloc() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_MALLOC); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - // put return value into return register - emitIFormat(OP_ADDIU, REG_V0, REG_RR, 0); - - // jump back to caller - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + // jump back to caller, return value is in REG_V0 + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } void syscall_malloc() { @@ -3388,7 +3605,7 @@ void syscall_malloc() { size = *(registers+REG_A0); if (size % 4 != 0) - size = size + (4 - size % 4); + size = size + 4 - size % 4; bump = *(registers+REG_K1); @@ -3398,17 +3615,18 @@ void syscall_malloc() { *(registers+REG_K1) = bump + size; *(registers+REG_V0) = bump; - if (debug_syscalls) - printString('[','O','S',']',' ','c', 'a', 'l','l',' ','m','a','l','l','o','c',CHAR_LF,0,0,0); + if (debug_malloc) { + print(binaryName); + print((int*) ": malloc "); + print(itoa(size, string_buffer, 10, 0)); + print((int*) " bytes returning address "); + print(itoa(bump, string_buffer, 16, 8)); + println(); + } } void emitGetchar() { - int *label; - - // "getchar" - label = createString('g','e','t','c','h','a','r',0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "getchar", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); @@ -3418,25 +3636,26 @@ void emitGetchar() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_GETCHAR); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitIFormat(OP_ADDIU, REG_V0, REG_RR, 0); - - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void syscall_getchar() { - *(registers+REG_V0) = getchar(); +void syscall_getchar() { + int c; + + c = getchar(); + + *(registers+REG_V0) = c; - if (debug_syscalls) - printString('[','O','S',']',' ','c', 'a', 'l','l',' ','g','e','t','c','h','a','r',CHAR_LF,0,0); + if (debug_getchar) { + print(binaryName); + print((int*) ": getchar "); + printCharacter(c); + println(); + } } void emitPutchar() { - int *label; - - // "putchar" - label = createString('p','u','t','c','h','a','r',0,0,0,0,0,0,0,0,0,0,0,0,0); - - createSymbolTableEntry(GLOBAL_TABLE, label, codeLength, FUNCTION, INT_T); + createSymbolTableEntry(GLOBAL_TABLE, (int*) "putchar", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); @@ -3450,7 +3669,35 @@ void emitPutchar() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_WRITE); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitRFormat(OP_SPECIAL, REG_LINK, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); +} + +void emitYield() { + + // create Symbol Table Entroy for yield + createSymbolTableEntry(GLOBAL_TABLE, (int*) "yield", binaryLength, FUNCTION, INT_T, 0); + + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_YIELD); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + +} + +void syscall_yield(){ + + schedule_and_switch(); + + if (debug_yield) { + print(binaryName); + println(); + print((int*) "yield"); + println(); + } + } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -3470,17 +3717,21 @@ int* ready_queue; int numb_of_instr; // getting maximal memory size int MAX_MEM; +// Size of Segment +int segment_size; // Address of the actual running thread int* running_process; +// Segmentation Table +int* segmentation_table; + void printList(int *list); -void printListPC(int *list); -void schedule_and_switch(); +void printListPC(int *list); void fct_syscall() { if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - putchar(CHAR_LF); + printFunction(function); + println(); } if (*(registers+REG_V0) == SYSCALL_EXIT) { @@ -3495,95 +3746,91 @@ void fct_syscall() { syscall_malloc(); } else if (*(registers+REG_V0) == SYSCALL_GETCHAR) { syscall_getchar(); + } else if (*(registers+REG_V0) == SYSCALL_YIELD) { + syscall_yield(); } else { exception_handler(EXCEPTION_UNKNOWNSYSCALL); } - pc = pc + 1; + pc = pc + 4; } void fct_nop() { - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - putchar(CHAR_LF); + printFunction(function); + println(); } } void op_jal() { - *(registers+REG_LINK) = pc * 4 + 8; + *(registers+REG_RA) = pc + 8; - pc = instr_index; + pc = instr_index * 4; // TODO: execute delay slot if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - memset(string_buffer, 33, 0); + printOpcode(opcode); + print((int*) " "); print(itoa(instr_index, string_buffer, 16, 8)); - putchar(CHAR_LF); + println(); } } void op_j() { - pc = instr_index; + pc = instr_index * 4; // TODO: execute delay slot if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - memset(string_buffer, 33, 0); + printOpcode(opcode); + print((int*) " "); print(itoa(instr_index, string_buffer, 16, 8)); - putchar(CHAR_LF); + println(); } } void op_beq() { - pc = pc + 1; + pc = pc + 4; if (*(registers+rs) == *(registers+rt)) { - pc = pc + signExtend(immediate); + pc = pc + signExtend(immediate) * 4; + // TODO: execute delay slot } if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - print((int*)(*(register_strings+rs))); + printOpcode(opcode); + print((int*) " "); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); + printRegister(rt); putchar(','); print(itoa(signExtend(immediate), string_buffer, 10, 0)); - - putchar(CHAR_LF); + println(); } } void op_bne() { - pc = pc + 1; + pc = pc + 4; if (*(registers+rs) != *(registers+rt)) { - pc = pc + signExtend(immediate); + pc = pc + signExtend(immediate) * 4; + // TODO: execute delay slot } if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - print((int*)(*(register_strings+rs))); + printOpcode(opcode); + print((int*) " "); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); + printRegister(rt); putchar(','); print(itoa(signExtend(immediate), string_buffer, 10, 0)); - - putchar(CHAR_LF); + println(); } } @@ -3592,80 +3839,69 @@ void op_addiu() { // TODO: check for overflow - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - print((int*)(*(register_strings+rt))); + printOpcode(opcode); + print((int*) " "); + printRegister(rt); putchar(','); - print((int*)(*(register_strings+rs))); + printRegister(rs); putchar(','); print(itoa(signExtend(immediate), string_buffer, 10, 0)); - - putchar(CHAR_LF); + println(); } } void fct_jr() { - pc = *(registers+rs) / 4; + pc = *(registers+rs); if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rs))); - - putchar(CHAR_LF); + printFunction(function); + print((int*) " "); + printRegister(rs); + println(); } } void op_lui() { *(registers+rt) = leftShift(immediate, 16); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - - print((int*)(*(register_strings+rt))); + printOpcode(opcode); + print((int*) " "); + printRegister(rt); putchar(','); print(itoa(signExtend(immediate), string_buffer, 10, 0)); - - putchar(CHAR_LF); + println(); } } void fct_mfhi() { *(registers+rd) = reg_hi; - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rd))); - - putchar(CHAR_LF); + printFunction(function); + print((int*) " "); + printRegister(rd); + println(); } } void fct_mflo() { *(registers+rd) = reg_lo; - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rd))); - - putchar(CHAR_LF); + printFunction(function); + print((int*) " "); + printRegister(rd); + println(); } } @@ -3673,17 +3909,15 @@ void fct_multu() { // TODO: 64-bit resolution currently not supported reg_lo = *(registers+rs) * *(registers+rt); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rs))); + printFunction(function); + print((int*) " "); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); - - putchar(CHAR_LF); + printRegister(rt); + println(); } } @@ -3691,82 +3925,71 @@ void fct_divu() { reg_lo = *(registers+rs) / *(registers+rt); reg_hi = *(registers+rs) % *(registers+rt); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rs))); + printFunction(function); + print((int*) " "); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); - - putchar(CHAR_LF); + printRegister(rt); + println(); } } void fct_addu() { *(registers+rd) = *(registers+rs) + *(registers+rt); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rd))); + printFunction(function); + print((int*) " "); + printRegister(rd); putchar(','); - print((int*)(*(register_strings+rs))); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); - putchar(CHAR_LF); + printRegister(rt); + println(); } } void fct_subu() { *(registers+rd) = *(registers+rs) - *(registers+rt); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rd))); + printFunction(function); + print((int*) " "); + printRegister(rd); putchar(','); - print((int*)(*(register_strings+rs))); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); - putchar(CHAR_LF); - + printRegister(rt); + println(); } } void op_lw() { int vaddr; - int paddr; vaddr = *(registers+rs) + signExtend(immediate); - paddr = addressTranslation(vaddr) / 4; + *(registers+rt) = loadMemory(vaddr); - *(registers+rt) = *(memory+paddr); - - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - print((int*)(*(register_strings+rt))); + printOpcode(opcode); + print((int*) " "); + printRegister(rt); putchar(','); print(itoa(signExtend(immediate), string_buffer, 10, 0)); - putchar('('); - print((int*)(*(register_strings+rs))); + printRegister(rs); putchar(')'); - - putchar(CHAR_LF); + println(); } } @@ -3776,48 +3999,39 @@ void fct_slt() { else *(registers+rd) = 0; - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(fct_strings+function))); - - putchar(' '); - print((int*)(*(register_strings+rd))); + printFunction(function); + print((int*) " "); + printRegister(rd); putchar(','); - print((int*)(*(register_strings+rs))); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); - - putchar(CHAR_LF); + printRegister(rt); + println(); } } void op_sw() { int vaddr; - int paddr; - int tmp; vaddr = *(registers+rs) + signExtend(immediate); - paddr = addressTranslation(vaddr) / 4; - - *(memory+paddr) = *(registers+rt); + storeMemory(vaddr, *(registers+rt)); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)(*(op_strings+opcode))); - - putchar(' '); - print((int*)(*(register_strings+rt))); + printOpcode(opcode); + print((int*) " "); + printRegister(rt); putchar(','); print(itoa(signExtend(immediate), string_buffer, 10, 0)); - putchar('('); - print((int*)(*(register_strings+rs))); + printRegister(rs); putchar(')'); - - putchar(CHAR_LF); + println(); } } @@ -3825,17 +4039,15 @@ void fct_teq() { if (*(registers+rs) == *(registers+rt)) exception_handler(EXCEPTION_SIGNAL); - pc = pc + 1; + pc = pc + 4; if (debug_disassemble) { - print((int*)*(fct_strings+function)); - - putchar(' '); - print((int*)(*(register_strings+rs))); + printFunction(function); + print((int*) " "); + printRegister(rs); putchar(','); - print((int*)(*(register_strings+rt))); - - putchar(CHAR_LF); + printRegister(rt); + println(); } } @@ -3843,34 +4055,25 @@ void fct_teq() { // -------------------------- INTERPRETER -------------------------- // ----------------------------------------------------------------- -void exception_handler(int enumber) { - if (enumber == EXCEPTION_SIGNAL) { - exit(EXCEPTION_SIGNAL); - } else if (enumber == EXCEPTION_ADDRESSERROR) { - exit(EXCEPTION_ADDRESSERROR); - } else if (enumber == EXCEPTION_UNKNOWNINSTRUCTION) { - exit(EXCEPTION_UNKNOWNINSTRUCTION); - } else if (enumber == EXCEPTION_HEAPOVERFLOW) { - exit(EXCEPTION_HEAPOVERFLOW); - } else if (enumber == EXCEPTION_UNKNOWNSYSCALL) { - exit(EXCEPTION_UNKNOWNSYSCALL); - } else if (enumber == EXCEPTION_UNKNOWNFUNCTION) { - exit(EXCEPTION_UNKNOWNFUNCTION); - } +void printException(int enumber) { + print((int*) *(EXCEPTIONS + enumber)); } -int addressTranslation(int vaddr) { - if (vaddr % 4 != 0) - exception_handler(EXCEPTION_ADDRESSERROR); +void exception_handler(int enumber) { + print(binaryName); + print((int*) ": exception: "); + printException(enumber); + println(); - return vaddr; + exit(enumber); } void pre_debug() { if (debug_disassemble) { - memset(string_buffer, 33, 0); // print current PC - print(itoa(4 * pc, string_buffer, 16, 4)); - putchar(CHAR_TAB); + print(binaryName); + print((int*) ": $pc="); + print(itoa(pc, string_buffer, 16, 8)); + print((int*) ": "); } } @@ -3881,21 +4084,21 @@ void post_debug() { while (i < 32) { if (*(registers+i) != 0) { - print((int*)*(register_strings+i)); - putchar(CHAR_TAB); - memset(string_buffer, 33, 0); + print(binaryName); + print((int*) ": "); + printRegister(i); + putchar(CHAR_EQUAL); print(itoa(*(registers+i), string_buffer, 16, 8)); - - putchar(CHAR_LF); + println(); } i = i + 1; } - putchar(CHAR_LF); + println(); } } void fetch() { - ir = *(memory+pc); + ir = loadMemory(pc); } void execute() { @@ -3947,19 +4150,16 @@ void execute() { void run() { int instr; int* nextprocess; - int *Buffer; - Buffer = (int*)malloc(4*10); - - instr = 0; + instr = 0; while (1) { - fetch(); + fetch(); decode(); pre_debug(); execute(); post_debug(); - instr = instr + 1; + instr = instr + 1; *(running_process+1) = *(running_process+1) + 1; if(instr == numb_of_instr){ @@ -3967,48 +4167,38 @@ void run() { schedule_and_switch(); instr = 0; } - } } -void debug_boot(int memorySize) { - printString('m','e','m',' ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - - print(itoa(memorySize/1024/1024*4, string_buffer, 10, 0)); - - printString('M','B',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); -} - -int* parse_args(int argc, int *argv, int *cstar_argv) { +void parse_args(int argc, int *argv) { // assert: ./selfie -m size executable {-m size executable} - int memorySize; - memorySize = atoi((int*)*(cstar_argv+2)) * 1024 * 1024 / 4; + // memory size in bytes and executable file name + initMemory(atoi((int*) *(argv+2)) * 1024 * 1024, (int*) *(argv+3)); - MAX_MEM = memorySize; - - allocateMachineMemory(memorySize*4); + MAX_MEM = memorySize; // initialize stack pointer - *(registers+REG_SP) = (memorySize - 1) * 4; - - debug_boot(memorySize); + *(registers+REG_SP) = memorySize - 4; - // return executable file name - return (int*)*(argv+3); + print(binaryName); + print((int*) ": memory size "); + print(itoa(memorySize / 1024 / 1024, string_buffer, 10, 0)); + print((int*) "MB"); + println(); } void up_push(int value) { - int address; + int vaddr; // allocate space for one value on the stack *(registers+REG_SP) = *(registers+REG_SP) - 4; // compute address - address = *(registers+REG_SP) / 4; + vaddr = *(registers+REG_SP); // store value - *(memory + address) = value; + storeMemory(vaddr, value); } int up_malloc(int size) { @@ -4019,59 +4209,23 @@ int up_malloc(int size) { return *(registers+REG_V0); } -int CStringLength(int* s) { - int l; - - l = 0; - - while (rightShift(leftShift(*s, 24 - (l % 4) * 8), 24) != 0) { - l = l + 1; - - if (l % 4 == 0) - s = s + 1; - } - - return l; -} - -int up_copyCString(int *s) { - int l; - int r; - int a; - - l = CStringLength(s); - - r = up_malloc(l+1); - - a = r / 4; - - while (a * 4 < r + l + 1) { - *(memory + a) = *s; - - s = s + 1; - a = a + 1; - } - - return r; -} - void up_copyArguments(int argc, int *argv) { - int c_argv; - - up_push(argc); + int vaddr; - c_argv = up_malloc(argc*4); + up_push(argc); - up_push(c_argv); + vaddr = up_malloc(argc * 4); - c_argv = c_argv / 4; + up_push(vaddr); while (argc > 0) { - *(memory + c_argv) = up_copyCString((int*)*argv); + storeMemory(vaddr, up_malloc(stringLength((int*) *argv) + 1)); - c_argv = c_argv + 1; - argv = argv + 1; + copyStringToMemory((int*) *argv, loadMemory(vaddr)); + + vaddr = vaddr + 4; + argv = argv + 1; argc = argc - 1; } } @@ -4156,7 +4310,7 @@ int* deleteFirstNodeFromList(int *list) { // Sort the list with Bubble Sort int* sortList(int *list) { - int size; + int size; int i; int *listitemX; int *listitemY; @@ -4189,9 +4343,9 @@ void printList(int *list) { int counter; int *nodeNumber; - int number; - int *Buffer; - + int number; + int *Buffer; + counter = sizeOfList(list)-1; while(counter >= 0) { @@ -4210,7 +4364,8 @@ int test00() { int *list; // Create new linked list (FIFO Linked List): // top -> [9,7,8,2,4,1,5,3] -> bottom - printString('I','n','s','e','r','t',' ','i','n','t','o',' ','l','i','s','t',CHAR_LF,0,0,0); + print((int*) "Insert into list"); + println(); list = initializeList(list); list = addToList(list, 9); list = addToList(list, 7); @@ -4224,7 +4379,8 @@ int test00() { // Delete the first node (FIFO Linked List): // top -> [2,4,1,5,3] -> bottom - printString('D','e','l','e','t','e',' ','f','i','r','s','t',' ','n','o','d','e',CHAR_LF,0,0); + print((int*) "Delete first Node"); + println(); list = deleteFirstNodeFromList(list); list = deleteFirstNodeFromList(list); list = deleteFirstNodeFromList(list); @@ -4232,7 +4388,8 @@ int test00() { // Sorting the list // top -> [5,4,3,2,1] -> bottom - printString('S','o','r','t','i','n','g',' ','t','h','e',' ','l','i','s','t',CHAR_LF,0,0,0); + print((int*) "Sorting the List"); + println(); list = sortList(list); printList(list); @@ -4253,17 +4410,17 @@ int test00() { //Deadline: Oct 22, end of day // ------------------------ DATA STRUCTURE FOR A PROCESS ----------------------- -// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), +// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), // Address to the Register (new_reg), Address to the Memory (new_mem), // hi register for multiplication/division (new_reg_hi) and // lo register for multiplication/division (new_reg_lo) and int* create_process(int new_pid, int* new_reg, int* new_mem, int new_reg_hi, int new_reg_lo){ - //initialization of the process - int* process; + //initialization of the process + int* process; //memory allocation process = malloc (6 * 4); - //initalization of the argments of the process + //initalization of the argments of the process *process = new_pid; *(process+1) = 0; *(process+2) = (int) new_reg; @@ -4274,15 +4431,50 @@ int* create_process(int new_pid, int* new_reg, int* new_mem, int new_reg_hi, int return process; } +int* create_process2(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ + //initialization of the process + int* process; + int start_n_segment; + //memory allocation + process = malloc (7 * 4); + start_n_segment = segment_number * segment_size; + + //initalization of the argments of the process + *process = new_pid; + *(process+1) = 0; + *(process+2) = (int) new_reg; + *(process+3) = *(memory) + start_n_segment; + *(process+4) = new_reg_hi; + *(process+5) = new_reg_lo; + *(process+6) = segment_number; + + return process; +} + +// ------------------------ DATA STRUCTURE FOR A SEGMENT ----------------------- +// Creating a new Segment with Startaddress (start) and Size (size). +int* create_segment(int* start, int size){ + //initialization of the process + int* segment; + //memory allocation + segment = malloc (2 * 4); + + //initalization of the argments of the process + *segment =(int) start; + *(segment+1) = size; + + return segment; +} + // ------------------------ READY QUEUE ---------------------------------------- // Creating a Ready queue with n processes and with m as number of instructions void create_ready_queue(int n, int m){ - + int *new_process; int pid; int *new_reg; int *new_mem; - + numb_of_instr = m; pid = 0; ready_queue = initializeList(ready_queue); @@ -4290,7 +4482,7 @@ void create_ready_queue(int n, int m){ while(pid < n){ new_reg = malloc(4*32); new_mem = malloc(4*MAX_MEM); - if(pid ==0){ + if(pid == 0){ running_process = create_process(pid, new_reg, new_mem, reg_hi, reg_lo); } else{ @@ -4301,6 +4493,33 @@ void create_ready_queue(int n, int m){ } } +void create_ready_queue2(int n, int m){ + + int *new_process; + int pid; + int *new_reg; + int segment_number; + + numb_of_instr = m; + pid = 0; + segment_number = 0; + ready_queue = initializeList(ready_queue); + + while(pid < n){ + new_reg = malloc(4*32); + if(pid == 0){ + running_process = create_process2(pid, new_reg, reg_hi, reg_lo, segment_number); + } + else{ + new_process = create_process2(pid, new_reg, reg_hi, reg_lo, segment_number); + ready_queue = addToList(ready_queue, (int) new_process); + } + pid = pid + 1; + segment_number = segment_number + 1; + } +} + + void printListPID(int *list) { int counter; int number; @@ -4327,7 +4546,7 @@ void printListPC(int *list) { int counter; int number; - int *Buffer; + int *Buffer; int *node; int *process; @@ -4338,7 +4557,7 @@ void printListPC(int *list) { process = (int*) *(node+1); number = *(process+1); Buffer = (int*)malloc(4*10); - print(itoa(number, Buffer, 10, 0)); + print(itoa(number, Buffer, 10, 0)); putchar(CHAR_LF); counter = counter - 1; } @@ -4351,9 +4570,10 @@ void schedule_and_switch(){ size = sizeOfList(ready_queue); //if the ready queue is empty, the running process can continue if(size == 0){ - printString('e','m','p','t','y','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); + print((int*) "empty---------"); + println(); return; - } + } //else the processes have to be switched so that the next process from the ready queue is allowed to run else{ // 1. Saving the states of the running process in the ready queue @@ -4363,196 +4583,349 @@ void schedule_and_switch(){ running_process = (int*) *(node+1); // 3. Delete the first Process from ready queue because it is the running process - ready_queue = deleteFirstNodeFromList(ready_queue); + ready_queue = deleteFirstNodeFromList(ready_queue); } } -void runtest() { +void create_segmentation_table(int segments){ + int *Buffer; + int memory_size; + + Buffer = (int*)malloc(4*10); + + segment_size = 1024 * 1024 / 4; + memory_size = segments * segment_size; + segmentation_table = (int*)malloc(segments * 4); + memory = (int*)malloc(memory_size); +} + +void runtest01() { int* nextprocess; int instr; int *Buffer; instr = 0; Buffer = (int*)malloc(4*10); - + while (1) { + fetch(); + decode(); + pre_debug(); + execute(); + post_debug(); + instr = instr + 1; - *(running_process+1) = *(running_process+1) + 1; - + *(running_process + 1) = *(running_process + 1) + 1; + if(instr == numb_of_instr){ //round robin scheduling and switching the running process - + //Printing the Ready queue and the running process - printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); - putchar(CHAR_LF); - printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); - putchar(CHAR_LF); - printString('R','e','a','d','y','Q','u','e','u','e',' ','a','f','t','e','r',' ','R','u','n'); - printString('n','i','n','g',' ', 'P','r','o','c','e','s','s',CHAR_LF,0,0,0,0,0,0,0); - printString('P','I','D','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + + print((int*) "--------------------"); + println(); + print((int*) "--------------------"); + println(); + print((int*) "Ready-Queue after running Process"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0)); + println(); + schedule_and_switch(); + print((int*) "--------------------"); + println(); + print((int*) "--------------------"); + println(); + print((int*) "Ready-Queue after switching Process"); + println(); + print((int*) "PIDs"); + println(); printListPID(ready_queue); - printString('P','C','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print((int*) "PCs"); + println(); printListPC(ready_queue); - printString('N','e','w',' ','R','u','n','n','i','n','g',' ','P','r','o','c','e','s','s',CHAR_LF); - printString('P','I','D',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); print(itoa(*(running_process), Buffer, 10, 0)); - putchar(CHAR_LF); - printString('P','C',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + println(); + print((int*) "PC"); + println(); print(itoa(*(running_process+1), Buffer, 10, 0)); - putchar(CHAR_LF); - schedule_and_switch(); + println(); instr = 0; + } + } +} + +void runtest02() { + int* nextprocess; + int instr; + int *Buffer; + + instr = 0; + Buffer = (int*)malloc(4*10); + + while (1) { + fetch(); + decode(); + pre_debug(); + execute(); + post_debug(); + + instr = instr + 1; + *(running_process + 1) = *(running_process + 1) + 1; + + if(instr == numb_of_instr){ + //round robin scheduling and switching the running process //Printing the Ready queue and the running process - printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); - putchar(CHAR_LF); - printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); - putchar(CHAR_LF); - printString('R','e','a','d','y','Q','u','e','u','e',' ','a','f','t','e','r',' ','S','w','i'); - printString('t','c','h','i','n','g',' ', 'P','r','o','c','e','s','s',CHAR_LF,0,0,0,0,0); - printString('P','I','D','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + + print((int*) "--------------------"); + println(); + print((int*) "--------------------"); + println(); + print((int*) "Ready-Queue after running Process"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0)); + println(); + syscall_yield(); + print((int*) "--------------------"); + println(); + print((int*) "--------------------"); + println(); + print((int*) "Ready-Queue after switching Process"); + println(); + print((int*) "PIDs"); + println(); printListPID(ready_queue); - printString('P','C','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print((int*) "PCs"); + println(); printListPC(ready_queue); - printString('N','e','w',' ','R','u','n','n','i','n','g',' ','P','r','o','c','e','s','s',CHAR_LF); - printString('P','I','D',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); print(itoa(*(running_process), Buffer, 10, 0)); - putchar(CHAR_LF); - printString('P','C',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + println(); + print((int*) "PC"); + println(); print(itoa(*(running_process+1), Buffer, 10, 0)); - putchar(CHAR_LF); - } + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0)); + println(); + instr = 0; + } } } -//Testing for Assignment 01 -int test01() { +int main_emulator(int argc, int *argv) { - int *Buffer; + int *Buffer; + int ticks; + int number_of_processes; - create_ready_queue(5,100000000); + ticks = 1000; + number_of_processes = 5; - Buffer = (int*)malloc(4*10); + if(testvar == 0){ + initInterpreter(); - printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); - putchar(CHAR_LF); - printString('-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-'); - putchar(CHAR_LF); - //Printing the Ready Queue after the creation (PID's and PC's) - printString('R','e','a','d','y','Q','u','e','u','e',' ','a','f','t','e','r',' ','C','r','e'); - printString('a','t','i','o','n',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - printString('P','I','D','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - printListPID(ready_queue); - printString('P','C','s',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - printListPC(ready_queue); + parse_args(argc, argv); - //Printing the PID and the PC of the running Process - printString('R','u','n','n','i','n','g',' ','P','r','o','c','e','s','s',CHAR_LF,0,0,0,0); - printString('P','I','D',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - print(itoa(*(running_process), Buffer, 10, 0)); - putchar(CHAR_LF); - printString('P','C',CHAR_LF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); - print(itoa(*(running_process+1), Buffer, 10, 0)); - putchar(CHAR_LF); + loadBinary(); - //Testversion of run of the Emulator - runtest(); + *(registers+REG_GP) = binaryLength; - exit(0); -} + *(registers+REG_K1) = *(registers+REG_GP); -int main_emulator(int argc, int *argv, int *cstar_argv) { - initInterpreter(); + up_copyArguments(argc-3, argv+3); - *(registers+REG_GP) = loadBinary(parse_args(argc, argv, cstar_argv)); + create_ready_queue(5,100); - *(registers+REG_K1) = *(registers+REG_GP); + run(); - up_copyArguments(argc-3, argv+3); + exit(0); + } + if(testvar == 1){ - //create a ready queue and 5 processes - create_ready_queue(5,10); + initInterpreter(); - run(); + parse_args(argc, argv); - exit(0); -} + loadBinary(); -// ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ -// ----------------------------------------------------------------- + *(registers+REG_GP) = binaryLength; -int* copyC2CStarString(int* s) { - int l; - int *r; - int i; + *(registers+REG_K1) = *(registers+REG_GP); - l = CStringLength(s); + up_copyArguments(argc-3, argv+3); - r = malloc((l + 1) * 4); + create_ready_queue(5,100); - i = 0; + Buffer = (int*)malloc(4*10); + print((int*) "--------------------"); + println(); + print((int*) "--------------------"); + println(); + //Printing the Ready Queue after the creation (PID's and PC's) + print((int*) "Ready Queue after Creation"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); - while (i <= l) { - *(r+i) = rightShift(leftShift(*s, 24 - (i % 4) * 8), 24); + //Printing the PID and the PC of the running Process + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0)); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0)); + println(); - i = i + 1; + //Testversion of run of the Emulator + runtest01(); - if (i % 4 == 0) - s = s + 1; + exit(0); } + if(testvar == 2){ - return r; -} + initInterpreter(); -int* copyC2CStarArguments(int argc, int *argv) { - int *cstar_argv; - int *cursor; + parse_args(argc, argv); - cstar_argv = malloc(argc * 4); + loadBinary(); - cursor = cstar_argv; + *(registers+REG_GP) = binaryLength; - while (argc > 0) { - *cursor = (int)copyC2CStarString((int*)*argv); + *(registers+REG_K1) = *(registers+REG_GP); - argv = argv + 1; - cursor = cursor + 1; - argc = argc - 1; - } + up_copyArguments(argc-3, argv+3); + + create_segmentation_table(number_of_processes); + + create_ready_queue2(number_of_processes,ticks); + + Buffer = (int*)malloc(4*10); + print((int*) "--------------------"); + println(); + print((int*) "--------------------"); + println(); + //Printing the Ready Queue after the creation (PID's and PC's) + print((int*) "Ready Queue after Creation"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0)); + println(); + + //Printing the PID and the PC of the running Process + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0)); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0)); + println(); + + //Testversion of run of the Emulator + runtest02(); - return cstar_argv; + exit(0); + } } +// ----------------------------------------------------------------- +// ----------------------------- MAIN ------------------------------ +// ----------------------------------------------------------------- + int main(int argc, int *argv) { - int *cstar_argv; int *firstParameter; initLibrary(); initRegister(); initDecoder(); - initSyscalls(); - - cstar_argv = copyC2CStarArguments(argc, argv); if (argc > 1) { - firstParameter = (int*) (*(cstar_argv+1)); + firstParameter = (int*) *(argv+1); - if (*firstParameter == '-') { - if (*(firstParameter+1) == 'c') + if (getCharacter(firstParameter, 0) == '-') { + if (getCharacter(firstParameter, 1) == 'c') main_compiler(); - else if (*(firstParameter+1) == 'm') { - if (argc > 3) - main_emulator(argc, argv, cstar_argv); - else + else if (getCharacter(firstParameter, 1) == 'm') { + if (argc > 3){ + testvar = 0; + main_emulator(argc, (int*) argv); + } + else { exit(-1); + } } - else if (*(firstParameter+1) == '0') { + else if (getCharacter(firstParameter, 1) == '0') { test00(); } - else if (*(firstParameter+1) == '1') { - test01(); + else if (getCharacter(firstParameter, 1) == '1') { + testvar = 1; + main_emulator(argc, (int*) argv); + } + else if (getCharacter(firstParameter, 1) == '2') { + testvar = 2; + main_emulator(argc, (int*) argv); } else { exit(-1); @@ -4563,4 +4936,4 @@ int main(int argc, int *argv) { } else // default: compiler main_compiler(); -} +} \ No newline at end of file From 8c12ad7364f70a17d7c46cab7ec0eeac5bcddb64 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Tue, 3 Nov 2015 12:50:03 +0100 Subject: [PATCH 12/15] - created function call for create_segment - removed redundant function declarations --- selfie.c | 221 ++++++++----------------------------------------------- 1 file changed, 30 insertions(+), 191 deletions(-) diff --git a/selfie.c b/selfie.c index ec32477..3a70b11 100755 --- a/selfie.c +++ b/selfie.c @@ -3727,6 +3727,7 @@ int* segmentation_table; void printList(int *list); void printListPC(int *list); +int* create_segment(int *start); void fct_syscall() { if (debug_disassemble) { @@ -4414,36 +4415,23 @@ int test00() { // Address to the Register (new_reg), Address to the Memory (new_mem), // hi register for multiplication/division (new_reg_hi) and // lo register for multiplication/division (new_reg_lo) and -int* create_process(int new_pid, int* new_reg, int* new_mem, int new_reg_hi, int new_reg_lo){ +int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ //initialization of the process - int* process; - //memory allocation - process = malloc (6 * 4); - - //initalization of the argments of the process - *process = new_pid; - *(process+1) = 0; - *(process+2) = (int) new_reg; - *(process+3) = (int) new_mem; - *(process+4) = new_reg_hi; - *(process+5) = new_reg_lo; - - return process; -} - -int* create_process2(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ - //initialization of the process - int* process; + int *process; + int *segment; + int *start; int start_n_segment; //memory allocation process = malloc (7 * 4); start_n_segment = segment_number * segment_size; + start = (int*) (*memory + start_n_segment); + segment = (int*) create_segment(start); //initalization of the argments of the process *process = new_pid; *(process+1) = 0; *(process+2) = (int) new_reg; - *(process+3) = *(memory) + start_n_segment; + *(process+3) = *segment; *(process+4) = new_reg_hi; *(process+5) = new_reg_lo; *(process+6) = segment_number; @@ -4453,15 +4441,15 @@ int* create_process2(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, // ------------------------ DATA STRUCTURE FOR A SEGMENT ----------------------- // Creating a new Segment with Startaddress (start) and Size (size). -int* create_segment(int* start, int size){ +int* create_segment(int *start){ //initialization of the process - int* segment; + int *segment; //memory allocation segment = malloc (2 * 4); //initalization of the argments of the process - *segment =(int) start; - *(segment+1) = size; + *segment = (int) start; + *(segment+1) = segment_size; return segment; } @@ -4470,31 +4458,6 @@ int* create_segment(int* start, int size){ // Creating a Ready queue with n processes and with m as number of instructions void create_ready_queue(int n, int m){ - int *new_process; - int pid; - int *new_reg; - int *new_mem; - - numb_of_instr = m; - pid = 0; - ready_queue = initializeList(ready_queue); - - while(pid < n){ - new_reg = malloc(4*32); - new_mem = malloc(4*MAX_MEM); - if(pid == 0){ - running_process = create_process(pid, new_reg, new_mem, reg_hi, reg_lo); - } - else{ - new_process = create_process(pid, new_reg, new_mem, reg_hi, reg_lo); - ready_queue = addToList(ready_queue, (int) new_process); - } - pid = pid + 1; - } -} - -void create_ready_queue2(int n, int m){ - int *new_process; int pid; int *new_reg; @@ -4508,10 +4471,10 @@ void create_ready_queue2(int n, int m){ while(pid < n){ new_reg = malloc(4*32); if(pid == 0){ - running_process = create_process2(pid, new_reg, reg_hi, reg_lo, segment_number); + running_process = create_process(pid, new_reg, reg_hi, reg_lo, segment_number); } else{ - new_process = create_process2(pid, new_reg, reg_hi, reg_lo, segment_number); + new_process = create_process(pid, new_reg, reg_hi, reg_lo, segment_number); ready_queue = addToList(ready_queue, (int) new_process); } pid = pid + 1; @@ -4599,80 +4562,7 @@ void create_segmentation_table(int segments){ memory = (int*)malloc(memory_size); } -void runtest01() { - int* nextprocess; - int instr; - int *Buffer; - - instr = 0; - Buffer = (int*)malloc(4*10); - - while (1) { - fetch(); - decode(); - pre_debug(); - execute(); - post_debug(); - - instr = instr + 1; - *(running_process + 1) = *(running_process + 1) + 1; - - if(instr == numb_of_instr){ - //round robin scheduling and switching the running process - - //Printing the Ready queue and the running process - - print((int*) "--------------------"); - println(); - print((int*) "--------------------"); - println(); - print((int*) "Ready-Queue after running Process"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0)); - println(); - print((int*) "PC"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0)); - println(); - schedule_and_switch(); - print((int*) "--------------------"); - println(); - print((int*) "--------------------"); - println(); - print((int*) "Ready-Queue after switching Process"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0)); - println(); - print((int*) "PC"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0)); - println(); - instr = 0; - } - } -} - -void runtest02() { +void runtest() { int* nextprocess; int instr; int *Buffer; @@ -4795,57 +4685,9 @@ int main_emulator(int argc, int *argv) { up_copyArguments(argc-3, argv+3); - create_ready_queue(5,100); - - Buffer = (int*)malloc(4*10); - print((int*) "--------------------"); - println(); - print((int*) "--------------------"); - println(); - //Printing the Ready Queue after the creation (PID's and PC's) - print((int*) "Ready Queue after Creation"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - - //Printing the PID and the PC of the running Process - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0)); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0)); - println(); - - //Testversion of run of the Emulator - runtest01(); - - exit(0); - } - if(testvar == 2){ - - initInterpreter(); - - parse_args(argc, argv); - - loadBinary(); - - *(registers+REG_GP) = binaryLength; - - *(registers+REG_K1) = *(registers+REG_GP); - - up_copyArguments(argc-3, argv+3); - create_segmentation_table(number_of_processes); - create_ready_queue2(number_of_processes,ticks); + create_ready_queue(number_of_processes,ticks); Buffer = (int*)malloc(4*10); print((int*) "--------------------"); @@ -4883,7 +4725,7 @@ int main_emulator(int argc, int *argv) { println(); //Testversion of run of the Emulator - runtest02(); + runtest(); exit(0); } @@ -4908,32 +4750,29 @@ int main(int argc, int *argv) { if (getCharacter(firstParameter, 1) == 'c') main_compiler(); else if (getCharacter(firstParameter, 1) == 'm') { - if (argc > 3){ - testvar = 0; + if (argc > 3) { + testvar = 0; main_emulator(argc, (int*) argv); - } + } else { exit(-1); - } + } + } + else if (getCharacter(firstParameter, 1) == '0') { + test00(); + } + else if (getCharacter(firstParameter, 1) == 't') { + testvar = 1; + main_emulator(argc, (int*) argv); } - else if (getCharacter(firstParameter, 1) == '0') { - test00(); - } - else if (getCharacter(firstParameter, 1) == '1') { - testvar = 1; - main_emulator(argc, (int*) argv); - } - else if (getCharacter(firstParameter, 1) == '2') { - testvar = 2; - main_emulator(argc, (int*) argv); - } else { exit(-1); } } else { exit(-1); } - } else + } else { // default: compiler main_compiler(); + } } \ No newline at end of file From eaa3aaf8ecd9ece76b3e0f722daa19825572979e Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Wed, 11 Nov 2015 13:27:22 +0100 Subject: [PATCH 13/15] - added assignment3 --- selfie.c | 1958 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 1330 insertions(+), 628 deletions(-) diff --git a/selfie.c b/selfie.c index 3a70b11..838da87 100755 --- a/selfie.c +++ b/selfie.c @@ -31,9 +31,9 @@ // into the emulator. Selfie is meant to be extended in numerous ways. // // C* is a tiny Turing-complete subset of C that includes dereferencing -// (the * operator) but excludes data structures, Boolean expressions, and -// many other features. There are only signed 32-bit integers and pointers, -// and character constants for constructing word-aligned strings manually. +// (the * operator) but excludes data structures, bitwise and Boolean +// operators, and many other features. There are only signed 32-bit +// integers and pointers as well as character and string constants. // This choice turns out to be helpful for students to understand the // true role of composite data structures such as arrays and records. // Bitwise operations are implemented in libcstar using signed integer @@ -63,6 +63,8 @@ // The design of the compiler is inspired by the Oberon compiler of // Professor Niklaus Wirth from ETH Zurich. +int *selfieName = (int*) 0; + // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- // --------------------- L I B R A R Y --------------------- @@ -84,7 +86,7 @@ void stringReverse(int *s); int stringCompare(int *s, int *t); int atoi(int *s); -int* itoa(int n, int *s, int b, int a); +int* itoa(int n, int *s, int b, int a, int p); void print(int *s); void println(); @@ -165,6 +167,7 @@ void initLibrary() { // ----------------------------------------------------------------- void initScanner(); +void resetScanner(); void printSymbol(int symbol); void printLineNumber(int* message); @@ -172,6 +175,8 @@ void printLineNumber(int* message); void syntaxErrorMessage(int *message); void syntaxErrorCharacter(int character); +void getCharacter(); + int isCharacterWhitespace(); int findNextCharacter(); int isCharacterLetter(); @@ -180,6 +185,7 @@ int isCharacterLetterOrDigitOrUnderscore(); int isNotDoubleQuoteOrEOF(); int identifierStringMatch(int stringIndex); int identifierOrKeyword(); + int getSymbol(); // ------------------------ GLOBAL CONSTANTS ----------------------- @@ -216,9 +222,11 @@ int SYM_STRING = 27; // string int *SYMBOLS; // array of strings representing symbols +int *character_buffer; // buffer for reading characters + int maxIdentifierLength = 64; // maximum number of characters in an identifier int maxIntegerLength = 10; // maximum number of characters in an integer -int maxStringLength = 64; // maximum number of characters in a string +int maxStringLength = 128; // maximum number of characters in a string // ------------------------ GLOBAL VARIABLES ----------------------- @@ -237,7 +245,54 @@ int isINTMINConstant = 0; int character; // most recently read character int symbol; // most recently recognized symbol -int testvar; + +int *sourceName = (int*) 0; // name of source file +int sourceFD = 0; // file descriptor of source file + + +// ------------------------ OWN GLOBAL VARIABLES ----------------------------------- +// ready queue +int* ready_queue; +// process list +int* process_list; +// number of instructions for one process in one run +int numb_of_instr; +// Size of Segment +int segment_size; +// Address of the actual running process +int* running_process; +// Address of the kernel process +int* kernel_process; +// Segmentation Table +int* segmentation_table; +// Number of ticks each Process can run +int ticks; +// Number of Processes +int number_of_processes; +// Number of Processes plus the kernel-process +int all_processes; +// id of the running process +int running_process_id; +// Interrupt Handling; +int booting; + +int* prev_node; +int* prev_process; +int* next_node; +int* next_process; + +void create_ready_queue(int n, int m); +int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number); +void create_segmentation_table(int segments); +int* initializeList(int *list); +int* addToList(int *list, int data); +void printListPID(int *list); +void printListPC(int *list); +void printListSegment(int *list); +int sizeOfList(int *list); +int getNodeFromList(int *list, int nthNode); +int* deleteFirstNodeFromList(int *list); +int* getNodeByIdFromProcessList(int id); // ------------------------- INITIALIZATION ------------------------ @@ -273,14 +328,25 @@ void initScanner () { *(SYMBOLS + SYM_CHARACTER) = (int) "character"; *(SYMBOLS + SYM_STRING) = (int) "string"; - character = getchar(); - symbol = SYM_EOF; + character_buffer = malloc(1); + + character = CHAR_EOF; + symbol = SYM_EOF; +} + +void resetScanner() { + lineNumber = 1; + + getCharacter(); + getSymbol(); } // ----------------------------------------------------------------- // ------------------------- SYMBOL TABLE -------------------------- // ----------------------------------------------------------------- +void resetGlobalSymbolTable(); + void createSymbolTableEntry(int which, int *string, int data, int class, int type, int value); int* getSymbolTableEntry(int *string, int class, int *symbol_table); @@ -322,12 +388,16 @@ int LOCAL_TABLE = 2; int *global_symbol_table = (int*) 0; int *local_symbol_table = (int*) 0; +// ------------------------- INITIALIZATION ------------------------ + +void resetGlobalSymbolTable() { + global_symbol_table = (int*) 0; +} + // ----------------------------------------------------------------- // ---------------------------- PARSER ----------------------------- // ----------------------------------------------------------------- -void initParser(); - int isNotRbraceOrEOF(); int isExpression(); int isStarOrDivOrModulo(); @@ -370,10 +440,6 @@ void gr_initialization(int *name, int offset, int type); void gr_procedure(int *procedure, int returnType); void gr_cstar(); -// ------------------------ GLOBAL CONSTANTS ----------------------- - -int maxBinaryLength; - // ------------------------ GLOBAL VARIABLES ----------------------- int allocatedTemporaries = 0; // number of allocated temporaries @@ -385,14 +451,6 @@ int returnBranches = 0; // fixup chain for return statements int *currentProcedureName = (int*) 0; // name of currently parsed procedure -// ------------------------- INITIALIZATION ------------------------ - -void -initParser() { - // set maximum code length in bytes for emitting code - maxBinaryLength = twoToThePowerOf(17); -} - // ----------------------------------------------------------------- // ---------------------- MACHINE CODE LIBRARY --------------------- // ----------------------------------------------------------------- @@ -400,6 +458,12 @@ initParser() { void emitLeftShiftBy(int b); void emitMainEntry(); +// ----------------------------------------------------------------- +// ----------------------------- MAIN ------------------------------ +// ----------------------------------------------------------------- + +void compile(); + // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- // ------------------- I N T E R F A C E ------------------- @@ -588,37 +652,13 @@ void initDecoder() { } // ----------------------------------------------------------------- -// ---------------------------- MEMORY ----------------------------- +// ---------------------------- BINARY ----------------------------- // ----------------------------------------------------------------- -void initMemory(int size, int* name); - -int tlb(int vaddr); - -int loadMemory(int vaddr); -void storeMemory(int vaddr, int data); - -// ------------------------ GLOBAL VARIABLES ----------------------- - -int *memory; -int memorySize; - -int *binaryName; -int binaryLength; - -// ------------------------- INITIALIZATION ------------------------ - -void initMemory(int size, int *name) { - memory = malloc(size); - memorySize = size; - - binaryName = name; - binaryLength = 0; -} +int loadBinary(int addr); +void storeBinary(int addr, int instruction); -// ----------------------------------------------------------------- -// ---------------------------- BINARY ----------------------------- -// ----------------------------------------------------------------- +void storeInstruction(int addr, int instruction); void emitInstruction(int instruction); void emitRFormat(int opcode, int rs, int rt, int rd, int function); @@ -629,10 +669,25 @@ void fixup_relative(int fromAddress); void fixup_absolute(int fromAddress, int toAddress); void fixlink_absolute(int fromAddress, int toAddress); -int copyStringToMemory(int *s, int a); +int copyStringToBinary(int *s, int a); + +void emitGlobalsStrings(); + +void emit(); +void load(); + +// ------------------------ GLOBAL CONSTANTS ----------------------- + +int maxBinaryLength = 131072; // 128KB + +// ------------------------ GLOBAL VARIABLES ----------------------- + +int *binary = (int*) 0; +int binaryLength = 0; -void emitBinary(); -void loadBinary(); +int *binaryName = (int*) 0; + +int *sourceLineNumber = (int*) 0; // ----------------------------------------------------------------- // --------------------------- SYSCALLS ---------------------------- @@ -653,23 +708,27 @@ void syscall_open(); void emitMalloc(); void syscall_malloc(); -void emitGetchar(); -void syscall_getchar(); - void emitPutchar(); void emitYield(); void syscall_yield(); +void emitSwitchEmu(); +void syscall_switchEmu(); + +void emitSwitchOS(); +void syscall_switchOS(); + // ------------------------ GLOBAL CONSTANTS ----------------------- -int SYSCALL_EXIT = 4001; -int SYSCALL_READ = 4003; -int SYSCALL_WRITE = 4004; -int SYSCALL_OPEN = 4005; -int SYSCALL_MALLOC = 5001; -int SYSCALL_GETCHAR = 5002; -int SYSCALL_YIELD = 5003; +int SYSCALL_EXIT = 4001; +int SYSCALL_READ = 4003; +int SYSCALL_WRITE = 4004; +int SYSCALL_OPEN = 4005; +int SYSCALL_MALLOC = 5001; +int SYSCALL_YIELD = 5003; +int SYSCALL_SWITCH_EMU = 5004; +int SYSCALL_SWITCH_OS = 5005; // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- @@ -677,6 +736,34 @@ int SYSCALL_YIELD = 5003; // ----------------------------------------------------------------- // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ +// ----------------------------------------------------------------- +// ---------------------------- MEMORY ----------------------------- +// ----------------------------------------------------------------- + +void initMemory(int megabytes); + +int tlb(int vaddr); + +int loadMemory(int vaddr); +void storeMemory(int vaddr, int data); + +// ------------------------ GLOBAL VARIABLES ----------------------- + +int memorySize = 0; +int *memory = (int*) 0; + +// ------------------------- INITIALIZATION ------------------------ + +void initMemory(int megabytes) { + if (megabytes < 0) + megabytes = 64; + else if (megabytes > 1024) + megabytes = 1024; + + memorySize = megabytes * 1024 * 1024; + memory = malloc(memorySize); +} + // ----------------------------------------------------------------- // ------------------------- INSTRUCTIONS -------------------------- // ----------------------------------------------------------------- @@ -689,7 +776,6 @@ void op_beq(); void op_bne(); void op_addiu(); void fct_jr(); -void op_lui(); void fct_mfhi(); void fct_mflo(); void fct_multu(); @@ -706,6 +792,7 @@ void op_teq(); // ----------------------------------------------------------------- void initInterpreter(); +void resetInterpreter(); void printException(int enumber); @@ -716,26 +803,38 @@ void post_debug(); void fetch(); void execute(); -void run(); +void run(int argc, int* argv); -void parse_args(int argc, int *argv); +// ----------------------------------------------------------------- +// ----------------------------- MAIN ------------------------------ +// ----------------------------------------------------------------- void up_push(int value); int up_malloc(int size); +int up_copyString(int *s); void up_copyArguments(int argc, int *argv); -int main_emulator(int argc, int *argv); +void copyBinaryToMemory(); + +int addressWithMaxCounter(int *counters, int max); +int fixedPointRatio(int a, int b); + +int printCounters(int total, int *counters, int max); +void printProfile(int *message, int total, int *counters); + +void emulate(int argc, int* argv); // ------------------------ GLOBAL CONSTANTS ----------------------- int debug_load = 0; -int debug_read = 0; -int debug_write = 0; -int debug_open = 0; -int debug_malloc = 0; -int debug_getchar = 0; -int debug_yield = 1; +int debug_read = 0; +int debug_write = 0; +int debug_open = 0; +int debug_malloc = 0; +int debug_yield = 1; +int debug_switch_emu = 1; +int debug_switch_os = 1; int debug_registers = 0; int debug_disassemble = 0; @@ -759,6 +858,20 @@ int ir = 0; // instruction record int reg_hi = 0; // hi register for multiplication/division int reg_lo = 0; // lo register for multiplication/division +int halt = 0; // flag for halting mipster + +int calls = 0; +int *callsPerAddress = (int*) 0; + +int loops = 0; +int *loopsPerAddress = (int*) 0; + +int loads = 0; +int *loadsPerAddress = (int*) 0; + +int stores = 0; +int *storesPerAddress = (int*) 0; + // ------------------------- INITIALIZATION ------------------------ void initInterpreter() { @@ -774,6 +887,25 @@ void initInterpreter() { registers = malloc(32*4); } +void resetInterpreter() { + pc = 0; + + reg_hi = 0; + reg_lo = 0; + + calls = 0; + callsPerAddress = malloc(maxBinaryLength); + + loops = 0; + loopsPerAddress = malloc(maxBinaryLength); + + loads = 0; + loadsPerAddress = malloc(maxBinaryLength); + + stores = 0; + storesPerAddress = malloc(maxBinaryLength); +} + // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- // --------------------- L I B R A R Y --------------------- @@ -811,7 +943,7 @@ int rightShift(int n, int b) { (INT_MAX / twoToThePowerOf(b) + 1); } -int getCharacter(int *s, int i) { +int loadCharacter(int *s, int i) { // assert: i >= 0 int a; @@ -820,13 +952,13 @@ int getCharacter(int *s, int i) { return rightShift(leftShift(*(s + a), 24 - (i % 4) * 8), 24); } -int* putCharacter(int *s, int i, int c) { +int* storeCharacter(int *s, int i, int c) { // assert: i >= 0, all characters are 7-bit int a; a = i / 4; - *(s + a) = (*(s + a) - leftShift(getCharacter(s, i), (i % 4) * 8)) + leftShift(c, (i % 4) * 8); + *(s + a) = (*(s + a) - leftShift(loadCharacter(s, i), (i % 4) * 8)) + leftShift(c, (i % 4) * 8); return s; } @@ -836,7 +968,7 @@ int stringLength(int *s) { i = 0; - while (getCharacter(s, i) != 0) + while (loadCharacter(s, i) != 0) i = i + 1; return i; @@ -851,10 +983,10 @@ void stringReverse(int *s) { j = stringLength(s) - 1; while (i < j) { - tmp = getCharacter(s, i); + tmp = loadCharacter(s, i); - putCharacter(s, i, getCharacter(s, j)); - putCharacter(s, j, tmp); + storeCharacter(s, i, loadCharacter(s, j)); + storeCharacter(s, j, tmp); i = i + 1; j = j - 1; @@ -867,12 +999,12 @@ int stringCompare(int *s, int *t) { i = 0; while (1) - if (getCharacter(s, i) == 0) - if (getCharacter(t, i) == 0) + if (loadCharacter(s, i) == 0) + if (loadCharacter(t, i) == 0) return 1; else return 0; - else if (getCharacter(s, i) == getCharacter(t, i)) + else if (loadCharacter(s, i) == loadCharacter(t, i)) i = i + 1; else return 0; @@ -881,32 +1013,54 @@ int stringCompare(int *s, int *t) { int atoi(int *s) { int i; int n; + int c; i = 0; n = 0; - while (getCharacter(s, i) != 0) { - n = n * 10 + getCharacter(s, i) - '0'; + c = loadCharacter(s, i); + + while (c != 0) { + c = c - '0'; + + if (c < 0) + return -1; + else if (c > 9) + return -1; + + n = n * 10 + c; i = i + 1; + + c = loadCharacter(s, i); + + if (n < 0) { + if (n != INT_MIN) + return -1; + else if (c != 0) + return -1; + } } return n; } -int* itoa(int n, int *s, int b, int a) { +int* itoa(int n, int *s, int b, int a, int p) { // assert: b in {2,4,8,10,16} int i; int sign; + int msb; i = 0; sign = 0; + msb = 0; + if (n == 0) { - putCharacter(s, 0, '0'); + storeCharacter(s, 0, '0'); i = 1; } else if (n < 0) { @@ -915,61 +1069,96 @@ int* itoa(int n, int *s, int b, int a) { if (b == 10) { if (n == INT_MIN) { // rightmost decimal digit of 32-bit INT_MIN - putCharacter(s, 0, '8'); + storeCharacter(s, 0, '8'); n = -(n / 10); - i = i + 1; + i = 1; } else n = -n; } else { if (n == INT_MIN) { // rightmost non-decimal digit of INT_MIN - putCharacter(s, 0, '0'); + storeCharacter(s, 0, '0'); n = (rightShift(INT_MIN, 1) / b) * 2; - i = i + 1; - } else - n = rightShift(leftShift(n, 1), 1); + i = 1; + } else { + n = rightShift(leftShift(n, 1), 1); + msb = 1; + } } } while (n != 0) { + if (p > 0) + if (i == p) { + storeCharacter(s, i, '.'); + + i = i + 1; + p = 0; + } + if (n % b > 9) - putCharacter(s, i, n % b - 10 + 'A'); + storeCharacter(s, i, n % b - 10 + 'A'); else - putCharacter(s, i, n % b + '0'); + storeCharacter(s, i, n % b + '0'); n = n / b; i = i + 1; - if (i == 1) { - if (sign) { - if (b != 10) - n = n + (rightShift(INT_MIN, 1) / b) * 2; - } + if (msb == 1) { + n = n + (rightShift(INT_MIN, 1) / b) * 2; + msb = 0; + } + } + + if (p > 0) { + while (i < p) { + storeCharacter(s, i, '0'); + + i = i + 1; } + + storeCharacter(s, i, '.'); + storeCharacter(s, i + 1, '0'); + + i = i + 2; + p = 0; } - if (b != 10) { + if (b == 10) { + if (sign) { + storeCharacter(s, i, '-'); + + i = i + 1; + } + + while (i < a) { + storeCharacter(s, i, ' '); // align with spaces + + i = i + 1; + } + } else { while (i < a) { - putCharacter(s, i, '0'); // align with zeros + storeCharacter(s, i, '0'); // align with zeros i = i + 1; } - if (b == 16) { - putCharacter(s, i, 'x'); - putCharacter(s, i + 1, '0'); + if (b == 8) { + storeCharacter(s, i, '0'); + storeCharacter(s, i + 1, '0'); i = i + 2; - } - } else if (sign) { - putCharacter(s, i, '-'); + } else if (b == 16) { + storeCharacter(s, i, 'x'); + storeCharacter(s, i + 1, '0'); - i = i + 1; + i = i + 2; + } } - putCharacter(s, i, 0); // null terminated string + storeCharacter(s, i, 0); // null terminated string stringReverse(s); @@ -981,8 +1170,8 @@ void print(int *s) { i = 0; - while (getCharacter(s, i) != 0) { - putchar(getCharacter(s, i)); + while (loadCharacter(s, i) != 0) { + putchar(loadCharacter(s, i)); i = i + 1; } @@ -1039,10 +1228,13 @@ void printSymbol(int symbol) { } void printLineNumber(int* message) { - print((int*) "cstarc: "); + print(selfieName); + print((int*) ": "); print(message); + print((int*) " in "); + print(sourceName); print((int*) " in line "); - print(itoa(lineNumber, string_buffer, 10, 0)); + print(itoa(lineNumber, string_buffer, 10, 0, 0)); print((int*) ": "); } @@ -1066,6 +1258,25 @@ void syntaxErrorCharacter(int expected) { println(); } +void getCharacter() { + int numberOfReadBytes; + + numberOfReadBytes = read(sourceFD, character_buffer, 1); + + if (numberOfReadBytes == 1) + character = *character_buffer; + else if (numberOfReadBytes == 0) + character = CHAR_EOF; + else { + print(selfieName); + print((int*) ": could not read character from input file "); + print(sourceName); + println(); + + exit(-1); + } +} + int isCharacterWhitespace() { if (character == CHAR_SPACE) return 1; @@ -1086,7 +1297,7 @@ int findNextCharacter() { while (1) { if (inComment) { - character = getchar(); + getCharacter(); if (character == CHAR_LF) inComment = 0; @@ -1101,14 +1312,16 @@ int findNextCharacter() { else if (character == CHAR_CR) lineNumber = lineNumber + 1; - character = getchar(); + getCharacter(); } else if (character == CHAR_HASH) { - character = getchar(); + getCharacter(); + inComment = 1; } else if (character == CHAR_SLASH) { - character = getchar(); + getCharacter(); + if (character == CHAR_SLASH) inComment = 1; else { @@ -1209,14 +1422,14 @@ int getSymbol() { exit(-1); } - putCharacter(identifier, i, character); + storeCharacter(identifier, i, character); i = i + 1; - character = getchar(); + getCharacter(); } - putCharacter(identifier, i, 0); // null terminated string + storeCharacter(identifier, i, 0); // null terminated string symbol = identifierOrKeyword(); @@ -1231,14 +1444,14 @@ int getSymbol() { exit(-1); } - putCharacter(integer, i, character); + storeCharacter(integer, i, character); i = i + 1; - character = getchar(); + getCharacter(); } - putCharacter(integer, i, 0); // null terminated string + storeCharacter(integer, i, 0); // null terminated string constant = atoi(integer); @@ -1259,7 +1472,7 @@ int getSymbol() { symbol = SYM_INTEGER; } else if (character == CHAR_SINGLEQUOTE) { - character = getchar(); + getCharacter(); constant = 0; @@ -1270,10 +1483,10 @@ int getSymbol() { } else constant = character; - character = getchar(); + getCharacter(); if (character == CHAR_SINGLEQUOTE) - character = getchar(); + getCharacter(); else if (character == CHAR_EOF) { syntaxErrorCharacter(CHAR_SINGLEQUOTE); @@ -1284,7 +1497,7 @@ int getSymbol() { symbol = SYM_CHARACTER; } else if (character == CHAR_DOUBLEQUOTE) { - character = getchar(); + getCharacter(); string = malloc(maxStringLength + 1); @@ -1296,96 +1509,113 @@ int getSymbol() { exit(-1); } - putCharacter(string, i, character); + storeCharacter(string, i, character); i = i + 1; - character = getchar(); + getCharacter(); } if (character == CHAR_DOUBLEQUOTE) - character = getchar(); + getCharacter(); else { syntaxErrorCharacter(CHAR_DOUBLEQUOTE); exit(-1); } - putCharacter(string, i, 0); // null terminated string + storeCharacter(string, i, 0); // null terminated string symbol = SYM_STRING; } else if (character == CHAR_SEMICOLON) { - character = getchar(); + getCharacter(); + symbol = SYM_SEMICOLON; } else if (character == CHAR_PLUS) { - character = getchar(); + getCharacter(); + symbol = SYM_PLUS; } else if (character == CHAR_DASH) { - character = getchar(); + getCharacter(); + symbol = SYM_MINUS; } else if (character == CHAR_ASTERISK) { - character = getchar(); + getCharacter(); + symbol = SYM_ASTERISK; } else if (character == CHAR_EQUAL) { - character = getchar(); + getCharacter(); + if (character == CHAR_EQUAL) { - character = getchar(); + getCharacter(); + symbol = SYM_EQUALITY; } else symbol = SYM_ASSIGN; } else if (character == CHAR_LPARENTHESIS) { - character = getchar(); + getCharacter(); + symbol = SYM_LPARENTHESIS; } else if (character == CHAR_RPARENTHESIS) { - character = getchar(); + getCharacter(); + symbol = SYM_RPARENTHESIS; } else if (character == CHAR_LBRACE) { - character = getchar(); + getCharacter(); + symbol = SYM_LBRACE; } else if (character == CHAR_RBRACE) { - character = getchar(); + getCharacter(); + symbol = SYM_RBRACE; } else if (character == CHAR_COMMA) { - character = getchar(); + getCharacter(); + symbol = SYM_COMMA; } else if (character == CHAR_LT) { - character = getchar(); + getCharacter(); + if (character == CHAR_EQUAL) { - character = getchar(); + getCharacter(); + symbol = SYM_LEQ; } else symbol = SYM_LT; } else if (character == CHAR_GT) { - character = getchar(); + getCharacter(); + if (character == CHAR_EQUAL) { - character = getchar(); + getCharacter(); + symbol = SYM_GEQ; } else symbol = SYM_GT; } else if (character == CHAR_EXCLAMATION) { - character = getchar(); + getCharacter(); + if (character == CHAR_EQUAL) - character = getchar(); + getCharacter(); else syntaxErrorCharacter(CHAR_EQUAL); symbol = SYM_NOTEQ; } else if (character == CHAR_PERCENTAGE) { - character = getchar(); + getCharacter(); + symbol = SYM_MOD; } else { @@ -1868,7 +2098,7 @@ int help_call_codegen(int *entry, int *procedure) { setData(entry, binaryLength); emitJFormat(OP_JAL, 0); - } else if (getOpcode(loadMemory(getData(entry))) == OP_JAL) { + } else if (getOpcode(loadBinary(getData(entry))) == OP_JAL) { // CASE 3: function call, no declaration emitJFormat(OP_JAL, getData(entry) / 4); @@ -2400,7 +2630,7 @@ void gr_while() { syntaxErrorSymbol(SYM_WHILE); // unconditional branch to beginning of while - emitIFormat(OP_BEQ, 0, 0, (brBackToWhile - binaryLength - 4) / 4); + emitIFormat(OP_BEQ, REG_ZR, REG_ZR, (brBackToWhile - binaryLength - 4) / 4); if (brForwardToEnd != 0) // first instruction after loop comes here @@ -2460,7 +2690,7 @@ void gr_if() { // if the "if" case was true, we jump to the end brForwardToEnd = binaryLength; - emitIFormat(OP_BEQ, 0, 0, 0); + emitIFormat(OP_BEQ, REG_ZR, REG_ZR, 0); // if the "if" case was not true, we jump here fixup_relative(brForwardToElseOrEnd); @@ -2862,7 +3092,7 @@ void gr_procedure(int *procedure, int returnType) { createSymbolTableEntry(GLOBAL_TABLE, currentProcedureName, binaryLength, FUNCTION, returnType, 0); else { if (getData(entry) != 0) { - if (getOpcode(loadMemory(getData(entry))) == OP_JAL) + if (getOpcode(loadBinary(getData(entry))) == OP_JAL) fixlink_absolute(getData(entry), functionStart); else { printLineNumber((int*) "error"); @@ -3005,21 +3235,47 @@ void emitMainEntry() { mainJumpAddress = binaryLength; + // jump and link to main, will return here only if there is no exit call emitJFormat(OP_JAL, 0); + + // we exit cleanly with error code 0 pushed onto the stack + emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); + emitIFormat(OP_SW, REG_SP, REG_ZR, 0); } // ----------------------------------------------------------------- // ----------------------------- MAIN ------------------------------ // ----------------------------------------------------------------- -int main_compiler() { - initScanner(); - initParser(); +void compile() { + print(selfieName); + print((int*) ": this is selfie's cstarc compiling "); + print(sourceName); + println(); - // memory in bytes and executable file name "out" - initMemory(maxBinaryLength, (int*) "out"); + sourceFD = open(sourceName, 0, 0); // 0 = O_RDONLY - getSymbol(); + if (sourceFD < 0) { + print(selfieName); + print((int*) ": could not open input file "); + print(sourceName); + println(); + + exit(-1); + } + + // reset scanner + resetScanner(); + + // reset global symbol table + resetGlobalSymbolTable(); + + // allocate space for storing binary + binary = malloc(maxBinaryLength); + binaryLength = 0; + + // allocate space for storing source code line numbers + sourceLineNumber = malloc(maxBinaryLength); // jump to main emitMainEntry(); @@ -3032,21 +3288,22 @@ int main_compiler() { emitWrite(); emitOpen(); emitMalloc(); - emitGetchar(); emitPutchar(); - emitYield(); // parser gr_cstar(); - if (getInstrIndex(loadMemory(mainJumpAddress)) != 0) - emitBinary(); - else { - print((int*) "cstarc: main function missing"); + // emit global variables and strings + emitGlobalsStrings(); + + if (getInstrIndex(loadBinary(mainJumpAddress)) == 0) { + print(selfieName); + print((int*) ": main function missing in "); + print(sourceName); println(); - } - exit(0); + exit(-1); + } } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -3227,35 +3484,29 @@ void decodeJFormat() { } // ----------------------------------------------------------------- -// ---------------------------- MEMORY ----------------------------- +// ---------------------------- BINARY ----------------------------- // ----------------------------------------------------------------- -int tlb(int vaddr) { - if (vaddr % 4 != 0) - exception_handler(EXCEPTION_ADDRESSERROR); - - // physical memory is word-addressed for lack of byte-sized data type - return vaddr / 4; +int loadBinary(int addr) { + return *(binary + addr / 4); } -int loadMemory(int vaddr) { - return *(memory + tlb(vaddr)); +void storeBinary(int addr, int instruction) { + *(binary + addr / 4) = instruction; } -void storeMemory(int vaddr, int data) { - *(memory + tlb(vaddr)) = data; -} +void storeInstruction(int addr, int instruction) { + *(sourceLineNumber + addr / 4) = lineNumber; -// ----------------------------------------------------------------- -// ---------------------------- BINARY ----------------------------- -// ----------------------------------------------------------------- + storeBinary(addr, instruction); +} void emitInstruction(int instruction) { if (binaryLength >= maxBinaryLength) { syntaxErrorMessage((int*) "exceeded maximum binary length"); exit(-1); } else { - storeMemory(binaryLength, instruction); + storeInstruction(binaryLength, instruction); binaryLength = binaryLength + 4; } @@ -3297,9 +3548,9 @@ void emitJFormat(int opcode, int instr_index) { void fixup_relative(int fromAddress) { int instruction; - instruction = loadMemory(fromAddress); + instruction = loadBinary(fromAddress); - storeMemory(fromAddress, + storeBinary(fromAddress, encodeIFormat(getOpcode(instruction), getRS(instruction), getRT(instruction), @@ -3307,21 +3558,21 @@ void fixup_relative(int fromAddress) { } void fixup_absolute(int fromAddress, int toAddress) { - storeMemory(fromAddress, - encodeJFormat(getOpcode(loadMemory(fromAddress)), toAddress / 4)); + storeBinary(fromAddress, + encodeJFormat(getOpcode(loadBinary(fromAddress)), toAddress / 4)); } void fixlink_absolute(int fromAddress, int toAddress) { int previousAddress; while (fromAddress != 0) { - previousAddress = getInstrIndex(loadMemory(fromAddress)) * 4; + previousAddress = getInstrIndex(loadBinary(fromAddress)) * 4; fixup_absolute(fromAddress, toAddress); fromAddress = previousAddress; } } -int copyStringToMemory(int *s, int a) { +int copyStringToBinary(int *s, int a) { int l; int w; @@ -3333,7 +3584,7 @@ int copyStringToMemory(int *s, int a) { w = w + 4 - l % 4; while (a < w) { - storeMemory(a, *s); + storeBinary(a, *s); s = s + 1; a = a + 4; @@ -3342,58 +3593,90 @@ int copyStringToMemory(int *s, int a) { return w; } -void emitBinary() { +void emitGlobalsStrings() { int *entry; - int fd; entry = global_symbol_table; + // assert: n = binaryLength + // allocate space for global variables and copy strings while ((int) entry != 0) { if (getClass(entry) == VARIABLE) { - storeMemory(binaryLength, getValue(entry)); + storeBinary(binaryLength, getValue(entry)); binaryLength = binaryLength + 4; } else if (getClass(entry) == STRING) - binaryLength = copyStringToMemory(getString(entry), binaryLength); + binaryLength = copyStringToBinary(getString(entry), binaryLength); entry = getNext(entry); } - // assert: file with name binaryName exists prior to execution of compiler - fd = open(binaryName, 1); // 1 = O_WRONLY + // assert: binaryLength == n + allocatedMemory + + allocatedMemory = 0; +} + +void emit() { + int fd; + + // 1537 = 0x0601 = O_CREAT (0x0200) | O_WRONLY (0x0001) | O_TRUNC (0x0400) + // 420 = 00644 = S_IRUSR (00400) | S_IWUSR (00200) | S_IRGRP (00040) | S_IROTH (00004) + fd = open(binaryName, 1537, 420); if (fd < 0) { - syntaxErrorMessage((int*) "output file not found"); + print(selfieName); + print((int*) ": could not create output file "); + print(binaryName); + println(); + exit(-1); } - // The mipster_syscall 4004 writes the code array into a file. - // The syscall uses the "write" system call of the OS and compiler. - // The write system call of our Linux uses little endian byte ordering. - write(fd, memory, binaryLength); + print(selfieName); + print((int*) ": writing code into output file "); + print(binaryName); + println(); + + write(fd, binary, binaryLength); } -void loadBinary() { +void load() { int fd; int numberOfReadBytes; - fd = open(binaryName, 0); // 0 = O_RDONLY + fd = open(binaryName, 0, 0); // 0 = O_RDONLY + + if (fd < 0) { + print(selfieName); + print((int*) ": could not open input file "); + print(binaryName); + println(); - if (fd < 0) exit(-1); + } + + binary = malloc(maxBinaryLength); + binaryLength = 0; + + sourceLineNumber = (int*) 0; numberOfReadBytes = 4; + print(selfieName); + print((int*) ": loading code from input file "); + print(binaryName); + println(); + while (numberOfReadBytes == 4) { - numberOfReadBytes = read(fd, memory + tlb(binaryLength), 4); + numberOfReadBytes = read(fd, binary + binaryLength / 4, 4); if (debug_load) { print(binaryName); print((int*) ": "); - print(itoa(binaryLength, string_buffer, 16, 8)); + print(itoa(binaryLength, string_buffer, 16, 8, 0)); print((int*) ": "); - print(itoa(loadMemory(binaryLength), string_buffer, 16, 8)); + print(itoa(loadBinary(binaryLength), string_buffer, 16, 8, 0)); println(); } @@ -3429,10 +3712,10 @@ void syscall_exit() { print(binaryName); print((int*) ": exiting with error code "); - print(itoa(exitCode, string_buffer, 10, 0)); + print(itoa(exitCode, string_buffer, 10, 0, 0)); println(); - exit(0); + halt = 1; } void emitRead() { @@ -3475,11 +3758,11 @@ void syscall_read() { if (debug_read) { print(binaryName); print((int*) ": read "); - print(itoa(size, string_buffer, 10, 0)); + print(itoa(size, string_buffer, 10, 0, 0)); print((int*) " bytes from file with descriptor "); - print(itoa(fd, string_buffer, 10, 0)); + print(itoa(fd, string_buffer, 10, 0, 0)); print((int*) " into buffer at address "); - print(itoa((int) buffer, string_buffer, 16, 8)); + print(itoa((int) buffer, string_buffer, 16, 8, 0)); println(); } } @@ -3523,11 +3806,11 @@ void syscall_write() { if (debug_write) { print(binaryName); print((int*) ": wrote "); - print(itoa(size, string_buffer, 10, 0)); + print(itoa(size, string_buffer, 10, 0, 0)); print((int*) " bytes from buffer at address "); - print(itoa((int) buffer, string_buffer, 16, 8)); + print(itoa((int) buffer, string_buffer, 16, 8, 0)); print((int*) " into file with descriptor "); - print(itoa(fd, string_buffer, 10, 0)); + print(itoa(fd, string_buffer, 10, 0, 0)); println(); } } @@ -3536,7 +3819,9 @@ void emitOpen() { createSymbolTableEntry(GLOBAL_TABLE, (int*) "open", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); + + emitIFormat(OP_ADDIU, REG_SP, REG_A2, 0); // mode + emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); emitIFormat(OP_LW, REG_SP, REG_A1, 0); // flags emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); @@ -3551,17 +3836,19 @@ void emitOpen() { } void syscall_open() { + int mode; int flags; int vaddr; int *filename; int fd; + mode = *(registers+REG_A2); flags = *(registers+REG_A1); vaddr = *(registers+REG_A0); filename = memory + tlb(vaddr); - fd = open(filename, flags); + fd = open(filename, flags, mode); *(registers+REG_V0) = fd; @@ -3570,9 +3857,11 @@ void syscall_open() { print((int*) ": opened file "); printString(filename); print((int*) " with flags "); - print(itoa(flags, string_buffer, 10, 0)); + print(itoa(flags, string_buffer, 16, 0, 0)); + print((int*) " and mode "); + print(itoa(mode, string_buffer, 8, 0, 0)); print((int*) " returning file descriptor "); - print(itoa(fd, string_buffer, 10, 0)); + print(itoa(fd, string_buffer, 10, 0, 0)); println(); } } @@ -3618,85 +3907,408 @@ void syscall_malloc() { if (debug_malloc) { print(binaryName); print((int*) ": malloc "); - print(itoa(size, string_buffer, 10, 0)); + print(itoa(size, string_buffer, 10, 0, 0)); print((int*) " bytes returning address "); - print(itoa(bump, string_buffer, 16, 8)); + print(itoa(bump, string_buffer, 16, 8, 0)); println(); } } -void emitGetchar() { - createSymbolTableEntry(GLOBAL_TABLE, (int*) "getchar", binaryLength, FUNCTION, INT_T, 0); +void emitPutchar() { + createSymbolTableEntry(GLOBAL_TABLE, (int*) "putchar", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_GETCHAR); + emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 4); // write one integer, 4 bytes + + emitIFormat(OP_ADDIU, REG_SP, REG_A1, 0); // pointer to character + emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); + + emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 1); // stdout file descriptor + + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_WRITE); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void syscall_getchar() { - int c; - - c = getchar(); +void emitYield() { - *(registers+REG_V0) = c; + // create Symbol Table Entroy for yield + createSymbolTableEntry(GLOBAL_TABLE, (int*) "yield", binaryLength, FUNCTION, INT_T, 0); - if (debug_getchar) { + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_YIELD); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + +} + +void syscall_yield(){ + + schedule_and_switch(); + + if (debug_yield) { print(binaryName); - print((int*) ": getchar "); - printCharacter(c); + println(); + print((int*) "yield"); println(); } + } -void emitPutchar() { - createSymbolTableEntry(GLOBAL_TABLE, (int*) "putchar", binaryLength, FUNCTION, INT_T, 0); +void emitSwitchEmu() { + + // create Symbol Table Entroy for switch_emu + createSymbolTableEntry(GLOBAL_TABLE, (int*) "switchEmu", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SWITCH_EMU); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); - emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 4); // write one integer, 4 bytes +} - emitIFormat(OP_ADDIU, REG_SP, REG_A1, 0); // pointer to character - emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); +void syscall_switchEmu(){ - emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 1); // stdout file descriptor + int* Buffer; + Buffer = (int*)malloc(4*10); - emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_WRITE); - emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + print((int*) "_________________________________________________"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "This is the Process List before running kernel"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(process_list); + print((int*) "PCs"); + println(); + printListPC(process_list); + print((int*) "Segment Start"); + println(); + printListSegment(process_list); + print((int*) "_________________________________________________"); + println(); + print((int*) "Ready-Queue before running Kernel"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + printListSegment(ready_queue); + print((int*) "_________________________________________________"); + println(); + + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0, 0)); + println(); + + print((int*) "Running Process ID"); + println(); + print(itoa(running_process_id, Buffer, 10, 0, 0)); + println(); + + prev_node = getNodeByIdFromProcessList(running_process_id); + prev_process = (int*) (prev_node); + + if(running_process_id == number_of_processes){ + running_process_id = 1; + print((int*) "if"); + println(); + } + else{ + running_process_id = running_process_id + 1; + print((int*) "else"); + println(); + } + + next_node = getNodeByIdFromProcessList(running_process_id); + next_process = (int*) (next_node); + + *(running_process + 1) = *(running_process + 1) + 1; + + running_process = next_process ; + + ready_queue = deleteFirstNodeFromList(ready_queue); + + print((int*) "_________________________________________________"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "This is the Process List after running kernel"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(process_list); + print((int*) "PCs"); + println(); + printListPC(process_list); + print((int*) "Segment Start"); + println(); + printListSegment(process_list); + + print((int*) "_________________________________________________"); + + println(); + print((int*) "Ready-Queue after running Kernel"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + printListSegment(ready_queue); + + print((int*) "_________________________________________________"); + println(); + + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0, 0)); + println(); + + print((int*) "Running Process ID"); + println(); + print(itoa(running_process_id, Buffer, 10, 0, 0)); + println(); + + if (debug_switch_emu) { + print(binaryName); + println(); + print((int*) "switchEmu"); + println(); + } - emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void emitYield() { +void emitSwitchOS() { - // create Symbol Table Entroy for yield - createSymbolTableEntry(GLOBAL_TABLE, (int*) "yield", binaryLength, FUNCTION, INT_T, 0); + // create Symbol Table Entroy for switch_os + createSymbolTableEntry(GLOBAL_TABLE, (int*) "switchOS", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_YIELD); + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SWITCH_OS); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void syscall_yield(){ +void syscall_switchOS(){ - schedule_and_switch(); + prev_node = getNodeByIdFromProcessList(running_process_id); + prev_process = (int*) (prev_node); - if (debug_yield) { - print(binaryName); - println(); - print((int*) "yield"); - println(); - } + next_node = getNodeByIdFromProcessList(0); + next_process = (int*) (next_node); + + running_process = next_process; + + ready_queue = addToList(ready_queue, (int) prev_process); + + if (debug_switch_os) { + print(binaryName); + println(); + print((int*) "switchOS"); + println(); + } + +} + +// *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ +// ----------------------------------------------------------------- +// --------------------------- kOS --------------------------- +// ----------------------------------------------------------------- +// *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ + +int* getNodeByIdFromProcessList(int id){ + + int* node_i; + int* process_i; + int i; + int j; + int* Buffer; + + i = 0; + + Buffer = (int*)malloc(4*10); + + while(i < all_processes) { + node_i = (int*) getNodeFromList(process_list, i); + process_i = (int*) *(node_i + 1); + + j = (int) *(process_i); + + if(j == id){ + + return process_i; + } + i = i + 1; + } + + +} + +void create_process_List(int number){ + int *node; + int *process; + int pid_process_list; + int pid_ready_queue; + + + pid_process_list = 0; + pid_ready_queue = number_of_processes - 1; + process_list = initializeList(process_list); + + while(pid_process_list < number){ + if(pid_process_list == 0){ + process_list = addToList(process_list, (int) kernel_process); + pid_process_list = pid_process_list + 1; + } + else{ + node = (int*) getNodeFromList(ready_queue, pid_ready_queue); + process = (int*) *(node+1); + process_list = addToList(process_list, (int) process); + pid_process_list = pid_process_list + 1; + pid_ready_queue = pid_ready_queue - 1; + } + } +} + +void runOS(int argc, int* argv){ + + while(1){ + syscall_switchEmu(); + run(argc, (int*) argv); + } + +} + +void kOS(int argc, int* argv) { + int *new_reg; + int* Buffer; + + if(booting == 1){ + + booting = 0; + + new_reg = malloc(4*32); + Buffer = (int*)malloc(4*10); + + all_processes = number_of_processes + 1; + + kernel_process = create_process(0, new_reg, reg_hi, reg_lo, 0); + running_process = kernel_process; + + create_segmentation_table(all_processes); + create_ready_queue(all_processes, ticks); + create_process_List(all_processes); + + print((int*) "_________________________________________________"); + println(); + print((int*) "__This is the Process List after initialization__"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(process_list); + print((int*) "PCs"); + println(); + printListPC(process_list); + print((int*) "Segment Start"); + println(); + printListSegment(process_list); + + print((int*) "_________________________________________________"); + println(); + print((int*) "__This is the Ready Queue after initialization___"); + println(); + print((int*) "_________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + printListSegment(ready_queue); + + print((int*) "____________________________________________________"); + println(); + print((int*) "__This is the Running Process after initialization__"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "Running Process"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0, 0)); + println(); + + runOS(argc, (int*) argv); + } + + else{ + runOS(argc, (int*) argv); + } } @@ -3707,27 +4319,36 @@ void syscall_yield(){ // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- -// ------------------------- INSTRUCTIONS -------------------------- +// ---------------------------- MEMORY ----------------------------- // ----------------------------------------------------------------- -// ------------------------ GLOBAL VARIABLES ----------------------------------- -// ready queue -int* ready_queue; -// number of instructions for one process in one run -int numb_of_instr; -// getting maximal memory size -int MAX_MEM; -// Size of Segment -int segment_size; -// Address of the actual running thread -int* running_process; -// Segmentation Table -int* segmentation_table; +int tlb(int vaddr) { + if (vaddr % 4 != 0) + exception_handler(EXCEPTION_ADDRESSERROR); + // physical memory is word-addressed for lack of byte-sized data type + return vaddr / 4; +} -void printList(int *list); -void printListPC(int *list); -int* create_segment(int *start); +int loadMemory(int vaddr) { + int paddr; + + paddr = tlb(vaddr); + + return *(memory + paddr); +} + +void storeMemory(int vaddr, int data) { + int paddr; + + paddr = tlb(vaddr); + + *(memory + paddr) = data; +} + +// ----------------------------------------------------------------- +// ------------------------- INSTRUCTIONS -------------------------- +// ----------------------------------------------------------------- void fct_syscall() { if (debug_disassemble) { @@ -3745,10 +4366,12 @@ void fct_syscall() { syscall_open(); } else if (*(registers+REG_V0) == SYSCALL_MALLOC) { syscall_malloc(); - } else if (*(registers+REG_V0) == SYSCALL_GETCHAR) { - syscall_getchar(); } else if (*(registers+REG_V0) == SYSCALL_YIELD) { syscall_yield(); + } else if (*(registers+REG_V0) == SYSCALL_SWITCH_EMU) { + syscall_switchEmu(); + } else if (*(registers+REG_V0) == SYSCALL_SWITCH_OS) { + syscall_switchOS(); } else { exception_handler(EXCEPTION_UNKNOWNSYSCALL); } @@ -3770,12 +4393,17 @@ void op_jal() { pc = instr_index * 4; + // keep track of number of procedure calls + calls = calls + 1; + + *(callsPerAddress + pc / 4) = *(callsPerAddress + pc / 4) + 1; + // TODO: execute delay slot if (debug_disassemble) { printOpcode(opcode); print((int*) " "); - print(itoa(instr_index, string_buffer, 16, 8)); + print(itoa(instr_index, string_buffer, 16, 8, 0)); println(); } } @@ -3788,7 +4416,7 @@ void op_j() { if (debug_disassemble) { printOpcode(opcode); print((int*) " "); - print(itoa(instr_index, string_buffer, 16, 8)); + print(itoa(instr_index, string_buffer, 16, 8, 0)); println(); } } @@ -3799,6 +4427,13 @@ void op_beq() { if (*(registers+rs) == *(registers+rt)) { pc = pc + signExtend(immediate) * 4; + if (signExtend(immediate) < 0) { + // keep track of number of loop iterations + loops = loops + 1; + + *(loopsPerAddress + pc / 4) = *(loopsPerAddress + pc / 4) + 1; + } + // TODO: execute delay slot } @@ -3809,7 +4444,7 @@ void op_beq() { putchar(','); printRegister(rt); putchar(','); - print(itoa(signExtend(immediate), string_buffer, 10, 0)); + print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); println(); } } @@ -3830,7 +4465,7 @@ void op_bne() { putchar(','); printRegister(rt); putchar(','); - print(itoa(signExtend(immediate), string_buffer, 10, 0)); + print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); println(); } } @@ -3849,7 +4484,7 @@ void op_addiu() { putchar(','); printRegister(rs); putchar(','); - print(itoa(signExtend(immediate), string_buffer, 10, 0)); + print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); println(); } } @@ -3865,21 +4500,6 @@ void fct_jr() { } } -void op_lui() { - *(registers+rt) = leftShift(immediate, 16); - - pc = pc + 4; - - if (debug_disassemble) { - printOpcode(opcode); - print((int*) " "); - printRegister(rt); - putchar(','); - print(itoa(signExtend(immediate), string_buffer, 10, 0)); - println(); - } -} - void fct_mfhi() { *(registers+rd) = reg_hi; @@ -3979,6 +4599,11 @@ void op_lw() { *(registers+rt) = loadMemory(vaddr); + // keep track of number of loads + loads = loads + 1; + + *(loadsPerAddress + pc / 4) = *(loadsPerAddress + pc / 4) + 1; + pc = pc + 4; if (debug_disassemble) { @@ -3986,7 +4611,7 @@ void op_lw() { print((int*) " "); printRegister(rt); putchar(','); - print(itoa(signExtend(immediate), string_buffer, 10, 0)); + print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); putchar('('); printRegister(rs); putchar(')'); @@ -4021,6 +4646,11 @@ void op_sw() { storeMemory(vaddr, *(registers+rt)); + // keep track of number of stores + stores = stores + 1; + + *(storesPerAddress + pc / 4) = *(storesPerAddress + pc / 4) + 1; + pc = pc + 4; if (debug_disassemble) { @@ -4028,7 +4658,7 @@ void op_sw() { print((int*) " "); printRegister(rt); putchar(','); - print(itoa(signExtend(immediate), string_buffer, 10, 0)); + print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); putchar('('); printRegister(rs); putchar(')'); @@ -4073,7 +4703,7 @@ void pre_debug() { if (debug_disassemble) { print(binaryName); print((int*) ": $pc="); - print(itoa(pc, string_buffer, 16, 8)); + print(itoa(pc, string_buffer, 16, 8, 0)); print((int*) ": "); } } @@ -4089,7 +4719,7 @@ void post_debug() { print((int*) ": "); printRegister(i); putchar(CHAR_EQUAL); - print(itoa(*(registers+i), string_buffer, 16, 8)); + print(itoa(*(registers+i), string_buffer, 16, 8, 0)); println(); } i = i + 1; @@ -4148,47 +4778,108 @@ void execute() { } } -void run() { - int instr; - int* nextprocess; +// Print the value of the Process IDs +void printListPID(int *list) { + int counter; + int number; + int *Buffer; + int *node; + int *process; - instr = 0; - while (1) { - fetch(); - decode(); - pre_debug(); - execute(); - post_debug(); - - instr = instr + 1; - *(running_process+1) = *(running_process+1) + 1; - - if(instr == numb_of_instr){ - //round robin scheduling and switching the running process - schedule_and_switch(); - instr = 0; - } - } -} + Buffer = (int*)malloc(4*10); -void parse_args(int argc, int *argv) { - // assert: ./selfie -m size executable {-m size executable} + counter = sizeOfList(list)-1; - // memory size in bytes and executable file name - initMemory(atoi((int*) *(argv+2)) * 1024 * 1024, (int*) *(argv+3)); + while(counter >= 0) { + node = (int*) getNodeFromList(list, counter); + process = (int*) *(node+1); + number = *(process); + print(itoa(number, Buffer, 10, 0, 0)); + putchar(CHAR_LF); + counter = counter - 1; + } - MAX_MEM = memorySize; +} - // initialize stack pointer - *(registers+REG_SP) = memorySize - 4; +// Print the value of the Program counters +void printListPC(int *list) { - print(binaryName); - print((int*) ": memory size "); - print(itoa(memorySize / 1024 / 1024, string_buffer, 10, 0)); - print((int*) "MB"); - println(); + int counter; + int number; + int *Buffer; + int *node; + int *process; + + counter = sizeOfList(list)-1; + + while(counter >= 0) { + node = (int*) getNodeFromList(list, counter); + process = (int*) *(node+1); + number = *(process+1); + Buffer = (int*)malloc(4*10); + print(itoa(number, Buffer, 10, 0, 0)); + putchar(CHAR_LF); + counter = counter - 1; + } } +// Print the value of the Segment Starts +void printListSegment(int *list) { + + int counter; + int number; + int *Buffer; + int *node; + int *process; + + counter = sizeOfList(list)-1; + + while(counter >= 0) { + node = (int*) getNodeFromList(list, counter); + process = (int*) *(node+1); + number = *(process+3); + Buffer = (int*)malloc(4*10); + print(itoa(number, Buffer, 10, 0, 0)); + putchar(CHAR_LF); + counter = counter - 1; + } +} + +void run(int argc, int* argv) { + + int instr; + int *Buffer; + + instr = 0; + halt = 0; + + while (halt == 0) { + //fetch(); + //decode(); + //pre_debug(); + //execute(); + //post_debug(); + + instr = instr + 1; + *(running_process + 1) = *(running_process + 1) + 1; + + if(instr == numb_of_instr){ + print((int*) "Running Process"); + println(); + halt = 1; + } + + } + + syscall_switchOS(); + kOS(argc, (int*) argv); + +} + +// ----------------------------------------------------------------- +// ----------------------------- MAIN ------------------------------ +// ----------------------------------------------------------------- + void up_push(int value) { int vaddr; @@ -4210,6 +4901,33 @@ int up_malloc(int size) { return *(registers+REG_V0); } +int up_copyString(int *s) { + int l; + int a; + int w; + int t; + + l = stringLength(s) + 1; + + a = up_malloc(l); + + w = a + l; + + if (l % 4 != 0) + w = w + 4 - l % 4; + + t = a; + + while (a < w) { + storeMemory(a, *s); + + s = s + 1; + a = a + 4; + } + + return t; +} + void up_copyArguments(int argc, int *argv) { int vaddr; @@ -4220,9 +4938,7 @@ void up_copyArguments(int argc, int *argv) { up_push(vaddr); while (argc > 0) { - storeMemory(vaddr, up_malloc(stringLength((int*) *argv) + 1)); - - copyStringToMemory((int*) *argv, loadMemory(vaddr)); + storeMemory(vaddr, up_copyString((int*) *argv)); vaddr = vaddr + 4; @@ -4231,6 +4947,108 @@ void up_copyArguments(int argc, int *argv) { } } +void copyBinaryToMemory() { + int a; + + a = 0; + + while (a < binaryLength) { + storeMemory(a, loadBinary(a)); + + a = a + 4; + } +} + +int addressWithMaxCounter(int *counters, int max) { + int a; + int n; + int i; + int c; + + a = -1; + + n = 0; + + i = 0; + + while (i < maxBinaryLength / 4) { + c = *(counters + i); + + if (n < c) + if (c < max) { + n = c; + a = i * 4; + } + + i = i + 1; + } + + return a; +} + +int fixedPointRatio(int a, int b) { + int r; + + r = 0; + + if (a <= INT_MAX / 100) { + if (b != 0) + r = a * 100 / b; + } else if (a <= INT_MAX / 10) { + if (b / 10 != 0) + r = a * 10 / (b / 10); + } else { + if (b / 100 != 0) + r = a / (b / 100); + } + + if (r != 0) + return 1000000 / r; + else + return 0; +} + +int printCounters(int total, int *counters, int max) { + int a; + + a = addressWithMaxCounter(counters, max); + + print(itoa(*(counters + a / 4), string_buffer, 10, 0, 0)); + + print((int*) "("); + print(itoa(fixedPointRatio(total, *(counters + a / 4)), string_buffer, 10, 0, 2)); + print((int*) "%)"); + + if (*(counters + a / 4) != 0) { + print((int*) "@"); + print(itoa(a, string_buffer, 16, 8, 0)); + if (sourceLineNumber != (int*) 0){ + print((int*) "(~"); + print(itoa(*(sourceLineNumber + a / 4), string_buffer, 10, 0, 0)); + print((int*) ")"); + } + } + + return a; +} + +void printProfile(int *message, int total, int *counters) { + int a; + + if (total > 0) { + print(selfieName); + print(message); + print(itoa(total, string_buffer, 10, 0, 0)); + print((int*) ","); + a = printCounters(total, counters, INT_MAX); + print((int*) ","); + a = printCounters(total, counters, *(counters + a / 4)); + print((int*) ","); + a = printCounters(total, counters, *(counters + a / 4)); + println(); + } +} + //// Assignment 0: Basic data structures //// //Review linked lists and implement a simple program using a singly linked list in C*. The minimal requirements are as follows: // @@ -4353,14 +5171,14 @@ void printList(int *list) { nodeNumber = (int*) getNodeFromList(list, counter); number = *(nodeNumber+1); Buffer = (int*)malloc(4*10); - print(itoa(number, Buffer, 10, 0)); + print(itoa(number, Buffer, 10, 0, 0)); putchar(CHAR_LF); counter = counter - 1; } } //Testing for Assignment 00 -int test00() { +int testList() { int *list; // Create new linked list (FIFO Linked List): @@ -4397,53 +5215,11 @@ int test00() { exit(0); } -//// Assignment 1: Loading, scheduling, switching, execution //// -//Implement basic concurrent execution of n processes in mipster. n >= 2 -//understand how mipster interprets and executes binary instructions. Tipp: add your own comments to the code -//mipster maintains a local state for a process (running executable), e.g., pc, registers, memory -//understand the purpose of each variable and data structure -//duplicate the process state n times -//running mipster like: ./selfie -m 32 yourbinary should generate n instances of yourbinary in a single instance of mipster -//implement preemptive multitasking, i.e., switching between the n instances of yourbinary is determined by mipster -//switch processes every m instructions. 1 <= m <= number of instructions in yourbinary -//implement round-robin scheduling -//add some output in yourbinary to demonstrate context switching -//Deadline: Oct 22, end of day - -// ------------------------ DATA STRUCTURE FOR A PROCESS ----------------------- -// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), -// Address to the Register (new_reg), Address to the Memory (new_mem), -// hi register for multiplication/division (new_reg_hi) and -// lo register for multiplication/division (new_reg_lo) and -int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ - //initialization of the process - int *process; - int *segment; - int *start; - int start_n_segment; - //memory allocation - process = malloc (7 * 4); - start_n_segment = segment_number * segment_size; - start = (int*) (*memory + start_n_segment); - segment = (int*) create_segment(start); - - //initalization of the argments of the process - *process = new_pid; - *(process+1) = 0; - *(process+2) = (int) new_reg; - *(process+3) = *segment; - *(process+4) = new_reg_hi; - *(process+5) = new_reg_lo; - *(process+6) = segment_number; - - return process; -} - // ------------------------ DATA STRUCTURE FOR A SEGMENT ----------------------- // Creating a new Segment with Startaddress (start) and Size (size). -int* create_segment(int *start){ +int* create_segment(int* start){ //initialization of the process - int *segment; + int* segment; //memory allocation segment = malloc (2 * 4); @@ -4454,77 +5230,64 @@ int* create_segment(int *start){ return segment; } -// ------------------------ READY QUEUE ---------------------------------------- -// Creating a Ready queue with n processes and with m as number of instructions -void create_ready_queue(int n, int m){ - - int *new_process; - int pid; - int *new_reg; - int segment_number; +// ------------------------ Segment Table ---------------------------------------- +void create_segmentation_table(int segments){ + int *Buffer; + int memory_size; - numb_of_instr = m; - pid = 0; - segment_number = 0; - ready_queue = initializeList(ready_queue); + Buffer = (int*)malloc(4*10); - while(pid < n){ - new_reg = malloc(4*32); - if(pid == 0){ - running_process = create_process(pid, new_reg, reg_hi, reg_lo, segment_number); - } - else{ - new_process = create_process(pid, new_reg, reg_hi, reg_lo, segment_number); - ready_queue = addToList(ready_queue, (int) new_process); - } - pid = pid + 1; - segment_number = segment_number + 1; - } + segment_size = 1024 * 1024 / 4; + memory_size = segments * segment_size; + segmentation_table = (int*)malloc(segments * 4); + memory = (int*)malloc(memory_size); } +// ------------------------ DATA STRUCTURE FOR A PROCESS ----------------------- +// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), +// Address to the Register (new_reg), Address to the Memory (new_mem), +// hi register for multiplication/division (new_reg_hi) and +// lo register for multiplication/division (new_reg_lo) and +int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ + //initialization of the process + int* process; + int start_n_segment; + int* segment; + int* start; -void printListPID(int *list) { - int counter; - int number; - int *Buffer; - int *node; - int *process; - - counter = sizeOfList(list)-1; + //memory allocation + process = malloc (7 * 4); - while(counter >= 0) { - node = (int*) getNodeFromList(list, counter); - process = (int*) *(node+1); - number = *(process); - Buffer = (int*)malloc(4*10); - print(itoa(number, Buffer, 10, 0)); - putchar(CHAR_LF); - counter = counter - 1; - } + if(new_pid == 0){ -} + //initalization of the argments of the process + *process = new_pid; + *(process+1) = 0; + *(process+2) = (int) new_reg; + *(process+3) = (int) memory; + *(process+4) = new_reg_hi; + *(process+5) = new_reg_lo; + *(process+6) = segment_number; -// Print the value of the Program counters -void printListPC(int *list) { + return process; + } + else{ + start_n_segment = segment_number * segment_size; + start = (int*) (*(memory) + start_n_segment); + segment = (int*) create_segment(start); - int counter; - int number; - int *Buffer; - int *node; - int *process; - counter = sizeOfList(list)-1; + //initalization of the argments of the process + *process = new_pid; + *(process+1) = 0; + *(process+2) = (int) new_reg; + *(process+3) = *segment; + *(process+4) = new_reg_hi; + *(process+5) = new_reg_lo; + *(process+6) = segment_number; - while(counter >= 0) { - node = (int*) getNodeFromList(list, counter); - process = (int*) *(node+1); - number = *(process+1); - Buffer = (int*)malloc(4*10); - print(itoa(number, Buffer, 10, 0)); - putchar(CHAR_LF); - counter = counter - 1; + return process; } - } void schedule_and_switch(){ @@ -4550,229 +5313,168 @@ void schedule_and_switch(){ } } -void create_segmentation_table(int segments){ - int *Buffer; - int memory_size; - - Buffer = (int*)malloc(4*10); - - segment_size = 1024 * 1024 / 4; - memory_size = segments * segment_size; - segmentation_table = (int*)malloc(segments * 4); - memory = (int*)malloc(memory_size); -} - -void runtest() { - int* nextprocess; - int instr; - int *Buffer; - - instr = 0; - Buffer = (int*)malloc(4*10); - - while (1) { - fetch(); - decode(); - pre_debug(); - execute(); - post_debug(); +// ------------------------ READY QUEUE ---------------------------------------- +// Creating a Ready queue with n processes and with m as number of instructions +void create_ready_queue(int n, int m){ + int *new_process; + int pid; + int *new_reg; + int segment_number; - instr = instr + 1; - *(running_process + 1) = *(running_process + 1) + 1; + numb_of_instr = m; + pid = 1; + segment_number = 1; + ready_queue = initializeList(ready_queue); + running_process_id = 0; - if(instr == numb_of_instr){ - //round robin scheduling and switching the running process - - //Printing the Ready queue and the running process - - print((int*) "--------------------"); - println(); - print((int*) "--------------------"); - println(); - print((int*) "Ready-Queue after running Process"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0)); - println(); - print((int*) "PC"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0)); - println(); - syscall_yield(); - print((int*) "--------------------"); - println(); - print((int*) "--------------------"); - println(); - print((int*) "Ready-Queue after switching Process"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0)); - println(); - print((int*) "PC"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0)); - println(); - instr = 0; + while(pid < n){ + new_reg = malloc(4*32); + new_process = create_process(pid, new_reg, reg_hi, reg_lo, segment_number); + ready_queue = addToList(ready_queue, (int) new_process); + pid = pid + 1; + segment_number = segment_number + 1; } - } } -int main_emulator(int argc, int *argv) { +void emulate(int argc, int *argv) { - int *Buffer; - int ticks; - int number_of_processes; + print(selfieName); + print((int*) ": this is selfie's mipster executing "); + print(binaryName); + print((int*) " with "); + print(itoa(memorySize / 1024 / 1024, string_buffer, 10, 0, 0)); + print((int*) "MB of memory"); + println(); - ticks = 1000; - number_of_processes = 5; + copyBinaryToMemory(); + resetInterpreter(); - if(testvar == 0){ - initInterpreter(); + *(registers+REG_SP) = memorySize - 4; + *(registers+REG_GP) = binaryLength; + *(registers+REG_K1) = *(registers+REG_GP); - parse_args(argc, argv); + up_copyArguments(argc, argv); - loadBinary(); + run(argc, (int*) argv); - *(registers+REG_GP) = binaryLength; + print(selfieName); + print((int*) ": this is selfie's mipster terminating "); + print(binaryName); + println(); - *(registers+REG_K1) = *(registers+REG_GP); + print(selfieName); + print((int*) ": profile: total,max(ratio%)@addr(line#),2max(ratio%)@addr(line#),3max(ratio%)@addr(line#)"); + println(); + printProfile((int*) ": calls: ", calls, callsPerAddress); + printProfile((int*) ": loops: ", loops, loopsPerAddress); + printProfile((int*) ": loads: ", loads, loadsPerAddress); + printProfile((int*) ": stores: ", stores, storesPerAddress); +} - up_copyArguments(argc-3, argv+3); +// ----------------------------------------------------------------- +// ----------------------------- MAIN ------------------------------ +// ----------------------------------------------------------------- - create_ready_queue(5,100); +int selfie(int argc, int* argv) { + if (argc < 2) + return -1; + else { + while (argc >= 2) { + if (stringCompare((int*) *argv, (int*) "-c")) { + sourceName = (int*) *(argv+1); + binaryName = sourceName; - run(); + argc = argc - 2; + argv = argv + 2; - exit(0); - } - if(testvar == 1){ + compile(); + } else if (stringCompare((int*) *argv, (int*) "-o")) { + binaryName = (int*) *(argv+1); - initInterpreter(); + argc = argc - 2; + argv = argv + 2; - parse_args(argc, argv); + if (binaryLength > 0) + emit(); + else { + print(selfieName); + print((int*) ": nothing to emit to output file "); + print(binaryName); + println(); + } + } else if (stringCompare((int*) *argv, (int*) "-l")) { + binaryName = (int*) *(argv+1); - loadBinary(); + argc = argc - 2; + argv = argv + 2; - *(registers+REG_GP) = binaryLength; + load(); + } else if (stringCompare((int*) *argv, (int*) "-m")) { + initMemory(atoi((int*) *(argv+1))); - *(registers+REG_K1) = *(registers+REG_GP); + argc = argc - 1; + argv = argv + 1; - up_copyArguments(argc-3, argv+3); + // pass binaryName as first argument replacing size + *argv = (int) binaryName; - create_segmentation_table(number_of_processes); + if (binaryLength > 0){ + print((int*) "here"); + println(); + emulate(argc, (int*) argv); + } + else { + print(selfieName); + print((int*) ": nothing to emulate"); + println(); - create_ready_queue(number_of_processes,ticks); + exit(-1); + } - Buffer = (int*)malloc(4*10); - print((int*) "--------------------"); - println(); - print((int*) "--------------------"); - println(); - //Printing the Ready Queue after the creation (PID's and PC's) - print((int*) "Ready Queue after Creation"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0)); - println(); + return 0; + } else if (stringCompare((int*) *argv, (int*) "-k")) { - //Printing the PID and the PC of the running Process - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0)); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0)); - println(); + argc = argc - 1; + argv = argv + 1; + booting = 1; + kOS(argc, (int*) argv); - //Testversion of run of the Emulator - runtest(); + return 0; + } else if (stringCompare((int*) *argv, (int*) "-t")) { + argc = argc - 1; + argv = argv + 1; + + testList(); - exit(0); + return 0; + } else + return -1; + } } -} -// ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ -// ----------------------------------------------------------------- + return 0; +} int main(int argc, int *argv) { - int *firstParameter; initLibrary(); - + initScanner(); initRegister(); initDecoder(); - if (argc > 1) { - firstParameter = (int*) *(argv+1); - - if (getCharacter(firstParameter, 0) == '-') { - if (getCharacter(firstParameter, 1) == 'c') - main_compiler(); - else if (getCharacter(firstParameter, 1) == 'm') { - if (argc > 3) { - testvar = 0; - main_emulator(argc, (int*) argv); - } - else { - exit(-1); - } - } - else if (getCharacter(firstParameter, 1) == '0') { - test00(); - } - else if (getCharacter(firstParameter, 1) == 't') { - testvar = 1; - main_emulator(argc, (int*) argv); - } - else { - exit(-1); - } - } else { - exit(-1); - } - } else { - // default: compiler - main_compiler(); + initInterpreter(); + + ticks = 1000000; + number_of_processes = 5; + + selfieName = (int*) *argv; + + argc = argc - 1; + argv = argv + 1; + + if (selfie(argc, (int*) argv) != 0) { + print(selfieName); + print((int*) ": usage: selfie { -c source | -o binary | -l binary } [ -m size ... | -k size ... ] "); + println(); } } \ No newline at end of file From 8c920fff0177fd753fedd78ac8679bed3bf3e7b0 Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Wed, 18 Nov 2015 11:34:42 +0100 Subject: [PATCH 14/15] - added assignment4 --- selfie.c | 2151 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 1509 insertions(+), 642 deletions(-) diff --git a/selfie.c b/selfie.c index 838da87..fbcb6a0 100755 --- a/selfie.c +++ b/selfie.c @@ -16,7 +16,7 @@ // resolve self-reference in systems code which is seen as the key // challenge when teaching systems engineering, hence the name. // -// Selfie is a fully self-referential 4k-line C implementation of: +// Selfie is a fully self-referential 5k-line C implementation of: // // 1. a self-compiling compiler called cstarc that compiles // a tiny but powerful subset of C called C Star (C*) to @@ -26,9 +26,10 @@ // 3. a tiny C* library called libcstar utilized by cstarc and mipster. // // Selfie is kept minimal for simplicity and implemented in a single file. -// There is no linker, assembler, or debugger. However, there is minimal +// There is neither a linker nor an assembler. However, there is a simple +// profiler and disassembler and even a simple debugger as well as minimal // operating system support in the form of MIPS32 o32 system calls built -// into the emulator. Selfie is meant to be extended in numerous ways. +// into the emulator. // // C* is a tiny Turing-complete subset of C that includes dereferencing // (the * operator) but excludes data structures, bitwise and Boolean @@ -88,6 +89,8 @@ int stringCompare(int *s, int *t); int atoi(int *s); int* itoa(int n, int *s, int b, int a, int p); +void putCharacter(int character); + void print(int *s); void println(); @@ -129,7 +132,23 @@ int *power_of_two_table; int INT_MAX; // maximum numerical value of an integer int INT_MIN; // minimum numerical value of an integer -int *string_buffer; +int *character_buffer; // buffer for reading and writing characters +int *string_buffer; // buffer for string output +int *io_buffer; // buffer for binary I/O + +// 0 = O_RDONLY (0x0000) +int O_RDONLY = 0; + +// 577 = 0x0241 = O_CREAT (0x0040) | O_WRONLY (0x0001) | O_TRUNC (0x0200) +int O_CREAT_WRONLY_TRUNC = 577; // flags for opening write-only files + +// 420 = 00644 = S_IRUSR (00400) | S_IWUSR (00200) | S_IRGRP (00040) | S_IROTH (00004) +int S_IRUSR_IWUSR_IRGRP_IROTH = 420; // flags for rw-r--r-- file permissions + +// ------------------------ GLOBAL VARIABLES ----------------------- + +int *outputName = (int*) 0; +int outputFD = 1; // ------------------------- INITIALIZATION ------------------------ @@ -152,8 +171,12 @@ void initLibrary() { INT_MAX = (twoToThePowerOf(30) - 1) * 2 + 1; INT_MIN = -INT_MAX - 1; - // accommodate 32-bit numbers for itoa + character_buffer = malloc(1); + + // accommodate at least 32-bit numbers for itoa string_buffer = malloc(33); + + io_buffer = malloc(4); } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -222,8 +245,6 @@ int SYM_STRING = 27; // string int *SYMBOLS; // array of strings representing symbols -int *character_buffer; // buffer for reading characters - int maxIdentifierLength = 64; // maximum number of characters in an identifier int maxIntegerLength = 10; // maximum number of characters in an integer int maxStringLength = 128; // maximum number of characters in a string @@ -247,8 +268,7 @@ int character; // most recently read character int symbol; // most recently recognized symbol int *sourceName = (int*) 0; // name of source file -int sourceFD = 0; // file descriptor of source file - +int sourceFD = 0; // file descriptor of open source file // ------------------------ OWN GLOBAL VARIABLES ----------------------------------- // ready queue @@ -273,8 +293,14 @@ int number_of_processes; int all_processes; // id of the running process int running_process_id; -// Interrupt Handling; +// variable if kernel is booting int booting; +// blocked queue +int* blocked_queue; +// Global lock +int* lock; +// Debugging Variable for locking which indicates the next Process who needs the lock +int debug_locking = 1; int* prev_node; int* prev_process; @@ -284,15 +310,16 @@ int* next_process; void create_ready_queue(int n, int m); int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number); void create_segmentation_table(int segments); -int* initializeList(int *list); +int* initializeList(int *list); int* addToList(int *list, int data); void printListPID(int *list); void printListPC(int *list); void printListSegment(int *list); int sizeOfList(int *list); -int getNodeFromList(int *list, int nthNode); +int getNodeFromList(int *list, int nthNode); int* deleteFirstNodeFromList(int *list); int* getNodeByIdFromProcessList(int id); +void schedule_and_switch(); // ------------------------- INITIALIZATION ------------------------ @@ -328,8 +355,6 @@ void initScanner () { *(SYMBOLS + SYM_CHARACTER) = (int) "character"; *(SYMBOLS + SYM_STRING) = (int) "string"; - character_buffer = malloc(1); - character = CHAR_EOF; symbol = SYM_EOF; } @@ -459,7 +484,7 @@ void emitLeftShiftBy(int b); void emitMainEntry(); // ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ +// --------------------------- COMPILER ---------------------------- // ----------------------------------------------------------------- void compile(); @@ -595,7 +620,7 @@ int OP_BNE = 5; int OP_ADDIU = 9; int OP_LW = 35; int OP_SW = 43; - + int *OPCODES; // array of strings representing MIPS opcodes int FCT_NOP = 0; @@ -652,7 +677,7 @@ void initDecoder() { } // ----------------------------------------------------------------- -// ---------------------------- BINARY ----------------------------- +// ----------------------------- CODE ------------------------------ // ----------------------------------------------------------------- int loadBinary(int addr); @@ -682,12 +707,18 @@ int maxBinaryLength = 131072; // 128KB // ------------------------ GLOBAL VARIABLES ----------------------- -int *binary = (int*) 0; -int binaryLength = 0; +int *binary = (int*) 0; // binary of emitted instructions + +int binaryLength = 0; // length of binary in bytes incl. globals & strings + +int codeLength = 0; // length of code portion of binary in bytes + +int *binaryName = (int*) 0; // file name of binary -int *binaryName = (int*) 0; +int *sourceLineNumber = (int*) 0; // source line number per emitted instruction -int *sourceLineNumber = (int*) 0; +int *assemblyName = (int*) 0; // name of assembly file +int assemblyFD = 0; // file descriptor of open assembly file // ----------------------------------------------------------------- // --------------------------- SYSCALLS ---------------------------- @@ -710,14 +741,20 @@ void syscall_malloc(); void emitPutchar(); -void emitYield(); -void syscall_yield(); +void emitSchedYield(); +void syscall_sched_yield(); -void emitSwitchEmu(); -void syscall_switchEmu(); +void emitSwitch(); +void syscall_switch(); -void emitSwitchOS(); -void syscall_switchOS(); +void emitMlock(); +void syscall_mlock(); + +void emitMunlock(); +void syscall_munlock(); + +void emitGetpid(); +void syscall_getpid(); // ------------------------ GLOBAL CONSTANTS ----------------------- @@ -726,9 +763,11 @@ int SYSCALL_READ = 4003; int SYSCALL_WRITE = 4004; int SYSCALL_OPEN = 4005; int SYSCALL_MALLOC = 5001; -int SYSCALL_YIELD = 5003; -int SYSCALL_SWITCH_EMU = 5004; -int SYSCALL_SWITCH_OS = 5005; +int SYSCALL_SCHED_YIELD = 5003; +int SYSCALL_SWITCH = 5004; +int SYSCALL_MLOCK = 5005; +int SYSCALL_MUNLOCK = 5006; +int SYSCALL_GETPID = 5007; // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ // ----------------------------------------------------------------- @@ -740,28 +779,34 @@ int SYSCALL_SWITCH_OS = 5005; // ---------------------------- MEMORY ----------------------------- // ----------------------------------------------------------------- -void initMemory(int megabytes); +void initMemory(int bytes); int tlb(int vaddr); int loadMemory(int vaddr); void storeMemory(int vaddr, int data); +// ------------------------ GLOBAL CONSTANTS ----------------------- + +int MEGABYTE = 1048576; + // ------------------------ GLOBAL VARIABLES ----------------------- -int memorySize = 0; -int *memory = (int*) 0; +int memorySize = 0; // size of memory in bytes + +int *memory = (int*) 0; // mipster memory // ------------------------- INITIALIZATION ------------------------ -void initMemory(int megabytes) { - if (megabytes < 0) - megabytes = 64; - else if (megabytes > 1024) - megabytes = 1024; +void initMemory(int bytes) { + if (bytes < 0) + memorySize = 64 * MEGABYTE; + else if (bytes > 1024 * MEGABYTE) + memorySize = 1024 * MEGABYTE; + else + memorySize = bytes; - memorySize = megabytes * 1024 * 1024; - memory = malloc(memorySize); + memory = malloc(memorySize); } // ----------------------------------------------------------------- @@ -798,16 +843,9 @@ void printException(int enumber); void exception_handler(int enumber); -void pre_debug(); -void post_debug(); - void fetch(); void execute(); -void run(int argc, int* argv); - -// ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ -// ----------------------------------------------------------------- +void run(int argc, int* argv) ; void up_push(int value); int up_malloc(int size); @@ -822,22 +860,17 @@ int fixedPointRatio(int a, int b); int printCounters(int total, int *counters, int max); void printProfile(int *message, int total, int *counters); -void emulate(int argc, int* argv); +void disassemble(int argc, int* argv); +void emulate(int argc, int *argv); // ------------------------ GLOBAL CONSTANTS ----------------------- -int debug_load = 0; - -int debug_read = 0; -int debug_write = 0; -int debug_open = 0; -int debug_malloc = 0; -int debug_yield = 1; -int debug_switch_emu = 1; -int debug_switch_os = 1; - -int debug_registers = 0; -int debug_disassemble = 0; +int debug_read = 0; +int debug_write = 0; +int debug_open = 0; +int debug_malloc = 0; +int debug_sched_yield = 1; +int debug_switch = 1; int EXCEPTION_SIGNAL = 1; int EXCEPTION_ADDRESSERROR = 2; @@ -860,17 +893,21 @@ int reg_lo = 0; // lo register for multiplication/division int halt = 0; // flag for halting mipster -int calls = 0; -int *callsPerAddress = (int*) 0; +int interpret = 0; + +int debug = 0; + +int calls = 0; // total number of executed procedure calls +int *callsPerAddress = (int*) 0; // number of executed calls of each procedure -int loops = 0; -int *loopsPerAddress = (int*) 0; +int loops = 0; // total number of executed loop iterations +int *loopsPerAddress = (int*) 0; // number of executed iterations of each loop -int loads = 0; -int *loadsPerAddress = (int*) 0; +int loads = 0; // total number of executed memory loads +int *loadsPerAddress = (int*) 0; // number of executed loads per load operation -int stores = 0; -int *storesPerAddress = (int*) 0; +int stores = 0; // total number of executed memory stores +int *storesPerAddress = (int*) 0; // number of executed stores per store operation // ------------------------- INITIALIZATION ------------------------ @@ -893,17 +930,19 @@ void resetInterpreter() { reg_hi = 0; reg_lo = 0; - calls = 0; - callsPerAddress = malloc(maxBinaryLength); + if (interpret) { + calls = 0; + callsPerAddress = malloc(maxBinaryLength); - loops = 0; - loopsPerAddress = malloc(maxBinaryLength); + loops = 0; + loopsPerAddress = malloc(maxBinaryLength); - loads = 0; - loadsPerAddress = malloc(maxBinaryLength); + loads = 0; + loadsPerAddress = malloc(maxBinaryLength); - stores = 0; - storesPerAddress = malloc(maxBinaryLength); + stores = 0; + storesPerAddress = malloc(maxBinaryLength); + } } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -938,7 +977,8 @@ int rightShift(int n, int b) { else if (n >= 0) return n / twoToThePowerOf(b); else - // works even if n == INT_MIN + // works even if n == INT_MIN: + // shift right n with msb reset and then restore msb return ((n + 1) + INT_MAX) / twoToThePowerOf(b) + (INT_MAX / twoToThePowerOf(b) + 1); } @@ -959,7 +999,7 @@ int* storeCharacter(int *s, int i, int c) { a = i / 4; *(s + a) = (*(s + a) - leftShift(loadCharacter(s, i), (i % 4) * 8)) + leftShift(c, (i % 4) * 8); - + return s; } @@ -984,7 +1024,7 @@ void stringReverse(int *s) { while (i < j) { tmp = loadCharacter(s, i); - + storeCharacter(s, i, loadCharacter(s, j)); storeCharacter(s, j, tmp); @@ -1030,7 +1070,7 @@ int atoi(int *s) { return -1; n = n * 10 + c; - + i = i + 1; c = loadCharacter(s, i); @@ -1071,6 +1111,7 @@ int* itoa(int n, int *s, int b, int a, int p) { // rightmost decimal digit of 32-bit INT_MIN storeCharacter(s, 0, '8'); + // avoids overflow n = -(n / 10); i = 1; } else @@ -1080,19 +1121,23 @@ int* itoa(int n, int *s, int b, int a, int p) { // rightmost non-decimal digit of INT_MIN storeCharacter(s, 0, '0'); + // avoids setting n to 0 n = (rightShift(INT_MIN, 1) / b) * 2; i = 1; } else { + // reset msb, restore below n = rightShift(leftShift(n, 1), 1); msb = 1; } } + + // assert: n > 0 } while (n != 0) { if (p > 0) if (i == p) { - storeCharacter(s, i, '.'); + storeCharacter(s, i, '.'); // set point of fixed point number i = i + 1; p = 0; @@ -1107,6 +1152,7 @@ int* itoa(int n, int *s, int b, int a, int p) { i = i + 1; if (msb == 1) { + // restore msb from above n = n + (rightShift(INT_MIN, 1) / b) * 2; msb = 0; } @@ -1114,13 +1160,13 @@ int* itoa(int n, int *s, int b, int a, int p) { if (p > 0) { while (i < p) { - storeCharacter(s, i, '0'); + storeCharacter(s, i, '0'); // no point yet, fill with 0s i = i + 1; } - storeCharacter(s, i, '.'); - storeCharacter(s, i + 1, '0'); + storeCharacter(s, i, '.'); // set point + storeCharacter(s, i + 1, '0'); // leading 0 i = i + 2; p = 0; @@ -1128,7 +1174,7 @@ int* itoa(int n, int *s, int b, int a, int p) { if (b == 10) { if (sign) { - storeCharacter(s, i, '-'); + storeCharacter(s, i, '-'); // negative decimal numbers start with - i = i + 1; } @@ -1140,24 +1186,24 @@ int* itoa(int n, int *s, int b, int a, int p) { } } else { while (i < a) { - storeCharacter(s, i, '0'); // align with zeros + storeCharacter(s, i, '0'); // align with 0s i = i + 1; } if (b == 8) { - storeCharacter(s, i, '0'); + storeCharacter(s, i, '0'); // octal numbers start with 00 storeCharacter(s, i + 1, '0'); i = i + 2; } else if (b == 16) { - storeCharacter(s, i, 'x'); + storeCharacter(s, i, 'x'); // hexadecimal numbers start with 0x storeCharacter(s, i + 1, '0'); i = i + 2; } } - + storeCharacter(s, i, 0); // null terminated string stringReverse(s); @@ -1165,24 +1211,43 @@ int* itoa(int n, int *s, int b, int a, int p) { return s; } +void putCharacter(int character) { + if (outputFD == 1) + putchar(character); + else { + *character_buffer = character; + + if (write(outputFD, character_buffer, 1) != 1) { + outputFD = 1; + + print(selfieName); + print((int*) ": could not write character to output file "); + print(outputName); + println(); + + exit(-1); + } + } +} + void print(int *s) { int i; i = 0; while (loadCharacter(s, i) != 0) { - putchar(loadCharacter(s, i)); + putCharacter(loadCharacter(s, i)); i = i + 1; } } void println() { - putchar(CHAR_LF); + putCharacter(CHAR_LF); } void printCharacter(int character) { - putchar(CHAR_SINGLEQUOTE); + putCharacter(CHAR_SINGLEQUOTE); if (character == CHAR_EOF) print((int*) "end of file"); @@ -1193,17 +1258,17 @@ void printCharacter(int character) { else if (character == CHAR_CR) print((int*) "carriage return"); else - putchar(character); + putCharacter(character); - putchar(CHAR_SINGLEQUOTE); + putCharacter(CHAR_SINGLEQUOTE); } void printString(int *s) { - putchar(CHAR_DOUBLEQUOTE); + putCharacter(CHAR_DOUBLEQUOTE); print(s); - - putchar(CHAR_DOUBLEQUOTE); + + putCharacter(CHAR_DOUBLEQUOTE); } // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ @@ -1217,14 +1282,14 @@ void printString(int *s) { // ----------------------------------------------------------------- void printSymbol(int symbol) { - putchar(CHAR_DOUBLEQUOTE); + putCharacter(CHAR_DOUBLEQUOTE); if (symbol == SYM_EOF) print((int*) "end of file"); else print((int*) *(SYMBOLS + symbol)); - putchar(CHAR_DOUBLEQUOTE); + putCharacter(CHAR_DOUBLEQUOTE); } void printLineNumber(int* message) { @@ -1242,7 +1307,7 @@ void syntaxErrorMessage(int *message) { printLineNumber((int*) "error"); print(message); - + println(); } @@ -1447,7 +1512,7 @@ int getSymbol() { storeCharacter(integer, i, character); i = i + 1; - + getCharacter(); } @@ -1512,7 +1577,7 @@ int getSymbol() { storeCharacter(string, i, character); i = i + 1; - + getCharacter(); } @@ -1622,7 +1687,7 @@ int getSymbol() { printLineNumber((int*) "error"); print((int*) "found unknown character "); printCharacter(character); - + println(); exit(-1); @@ -1674,7 +1739,7 @@ int* getSymbolTableEntry(int *string, int class, int *symbol_table) { if (stringCompare(string, getString(symbol_table))) if (class == getClass(symbol_table)) return symbol_table; - + // keep looking symbol_table = getNext(symbol_table); } @@ -1920,6 +1985,7 @@ void tfree(int numberOfTemporaries) { void save_temporaries() { while (allocatedTemporaries > 0) { + // push temporary onto stack emitIFormat(OP_ADDIU, REG_SP, REG_SP, -4); emitIFormat(OP_SW, REG_SP, currentTemporary(), 0); @@ -1931,6 +1997,7 @@ void restore_temporaries(int numberOfTemporaries) { while (allocatedTemporaries < numberOfTemporaries) { talloc(); + // restore temporary from stack emitIFormat(OP_LW, REG_SP, currentTemporary(), 0); emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); } @@ -2191,7 +2258,7 @@ int gr_call(int *procedure) { if (symbol == SYM_RPARENTHESIS) { getSymbol(); - + type = help_call_codegen(entry, procedure); } else { syntaxErrorSymbol(SYM_RPARENTHESIS); @@ -2333,9 +2400,9 @@ int gr_factor() { emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), constant); getSymbol(); - + type = INT_T; - + // string? } else if (symbol == SYM_STRING) { load_string(); @@ -2385,7 +2452,7 @@ int gr_term() { rtype = gr_factor(); // assert: allocatedTemporaries == n + 2 - + if (ltype != rtype) typeWarning(ltype, rtype); @@ -2431,7 +2498,7 @@ int gr_simpleExpression() { if (isINTMINConstant) { isINTMINConstant = 0; - + // avoids 0-INT_MIN overflow when bootstrapping // even though 0-INT_MIN == INT_MIN sign = 0; @@ -2569,7 +2636,7 @@ int gr_expression() { emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 0); } } - + // assert: allocatedTemporaries == n + 1 return ltype; @@ -2750,7 +2817,7 @@ void gr_return(int returnType) { // save value of expression in return register emitRFormat(OP_SPECIAL, REG_ZR, currentTemporary(), REG_V0, FCT_ADDU); - + tfree(1); } @@ -2917,7 +2984,7 @@ int gr_type() { int type; type = INT_T; - + if (symbol == SYM_INT) { getSymbol(); @@ -2989,7 +3056,7 @@ void gr_initialization(int *name, int offset, int type) { if (isINTMINConstant) { isINTMINConstant = 0; - + // avoids 0-INT_MIN overflow when bootstrapping // even though 0-INT_MIN == INT_MIN sign = 0; @@ -3083,7 +3150,7 @@ void gr_procedure(int *procedure, int returnType) { // ( variable, variable ) { variable; variable; statement } } else if (symbol == SYM_LBRACE) { functionStart = binaryLength; - + getSymbol(); entry = getSymbolTableEntry(currentProcedureName, FUNCTION, global_symbol_table); @@ -3228,7 +3295,7 @@ void emitLeftShiftBy(int b) { } void emitMainEntry() { - // instruction at address zero cannot be fixed up + // instruction at address zero cannot be fixed up, so just put a NOP there emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_NOP); createSymbolTableEntry(GLOBAL_TABLE, (int*) "main", binaryLength, FUNCTION, INT_T, 0); @@ -3244,7 +3311,7 @@ void emitMainEntry() { } // ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ +// --------------------------- COMPILER ---------------------------- // ----------------------------------------------------------------- void compile() { @@ -3253,7 +3320,7 @@ void compile() { print(sourceName); println(); - sourceFD = open(sourceName, 0, 0); // 0 = O_RDONLY + sourceFD = open(sourceName, O_RDONLY, 0); if (sourceFD < 0) { print(selfieName); @@ -3274,6 +3341,9 @@ void compile() { binary = malloc(maxBinaryLength); binaryLength = 0; + // reset code length + codeLength = 0; + // allocate space for storing source code line numbers sourceLineNumber = malloc(maxBinaryLength); @@ -3289,10 +3359,18 @@ void compile() { emitOpen(); emitMalloc(); emitPutchar(); + emitSchedYield(); + emitSwitch(); + emitMlock(); + emitMunlock(); + emitGetpid(); // parser gr_cstar(); + // set code length + codeLength = binaryLength; + // emit global variables and strings emitGlobalsStrings(); @@ -3312,8 +3390,6 @@ void compile() { // ----------------------------------------------------------------- // *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ *~*~ -void schedule_and_switch(); - // ----------------------------------------------------------------- // ---------------------------- REGISTER --------------------------- // ----------------------------------------------------------------- @@ -3484,7 +3560,7 @@ void decodeJFormat() { } // ----------------------------------------------------------------- -// ---------------------------- BINARY ----------------------------- +// ----------------------------- CODE ------------------------------ // ----------------------------------------------------------------- int loadBinary(int addr) { @@ -3507,7 +3583,7 @@ void emitInstruction(int instruction) { exit(-1); } else { storeInstruction(binaryLength, instruction); - + binaryLength = binaryLength + 4; } } @@ -3581,6 +3657,7 @@ int copyStringToBinary(int *s, int a) { w = a + l; if (l % 4 != 0) + // making sure w is a multiple of 4 bytes w = w + 4 - l % 4; while (a < w) { @@ -3619,10 +3696,8 @@ void emitGlobalsStrings() { void emit() { int fd; - - // 1537 = 0x0601 = O_CREAT (0x0200) | O_WRONLY (0x0001) | O_TRUNC (0x0400) - // 420 = 00644 = S_IRUSR (00400) | S_IWUSR (00200) | S_IRGRP (00040) | S_IROTH (00004) - fd = open(binaryName, 1537, 420); + + fd = open(binaryName, O_CREAT_WRONLY_TRUNC, S_IRUSR_IWUSR_IRGRP_IROTH); if (fd < 0) { print(selfieName); @@ -3638,6 +3713,12 @@ void emit() { print(binaryName); println(); + *io_buffer = codeLength; + + // first write code length + write(fd, io_buffer, 4); + + // then write binary write(fd, binary, binaryLength); } @@ -3645,7 +3726,7 @@ void load() { int fd; int numberOfReadBytes; - fd = open(binaryName, 0, 0); // 0 = O_RDONLY + fd = open(binaryName, O_RDONLY, 0); if (fd < 0) { print(selfieName); @@ -3659,30 +3740,37 @@ void load() { binary = malloc(maxBinaryLength); binaryLength = 0; - sourceLineNumber = (int*) 0; + codeLength = 0; - numberOfReadBytes = 4; + sourceLineNumber = (int*) 0; print(selfieName); print((int*) ": loading code from input file "); print(binaryName); println(); - while (numberOfReadBytes == 4) { - numberOfReadBytes = read(fd, binary + binaryLength / 4, 4); + // read code length first + numberOfReadBytes = read(fd, io_buffer, 4); - if (debug_load) { - print(binaryName); - print((int*) ": "); - print(itoa(binaryLength, string_buffer, 16, 8, 0)); - print((int*) ": "); - print(itoa(loadBinary(binaryLength), string_buffer, 16, 8, 0)); - println(); - } + if (numberOfReadBytes == 4) { + codeLength = *io_buffer; + + // now read binary + numberOfReadBytes = read(fd, binary, maxBinaryLength); - if (numberOfReadBytes == 4) - binaryLength = binaryLength + 4; + if (numberOfReadBytes > 0) { + binaryLength = numberOfReadBytes; + + return; + } } + + print(selfieName); + print((int*) ": failed to load code from input file "); + print(binaryName); + println(); + + exit(-1); } // ----------------------------------------------------------------- @@ -3696,11 +3784,17 @@ void emitExit() { emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); + // load argument for exit emitIFormat(OP_LW, REG_SP, REG_A0, 0); // exit code + + // remove the argument from the stack emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); + // load the correct syscall number and invoke syscall emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_EXIT); emitRFormat(0, 0, 0, 0, FCT_SYSCALL); + + // never returns here } void syscall_exit() { @@ -3735,6 +3829,7 @@ void emitRead() { emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_READ); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + // jump back to caller, return value is in REG_V0 emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } @@ -3820,7 +3915,7 @@ void emitOpen() { emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); - emitIFormat(OP_ADDIU, REG_SP, REG_A2, 0); // mode + emitIFormat(OP_LW, REG_SP, REG_A2, 0); // mode emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); emitIFormat(OP_LW, REG_SP, REG_A1, 0); // flags @@ -3873,17 +3968,12 @@ void emitMalloc() { emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); - // load argument for malloc (size) emitIFormat(OP_LW, REG_SP, REG_A0, 0); - - // remove the argument from the stack emitIFormat(OP_ADDIU, REG_SP, REG_SP, 4); - // load the correct syscall number and invoke syscall emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_MALLOC); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - // jump back to caller, return value is in REG_V0 emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } @@ -3932,232 +4022,209 @@ void emitPutchar() { emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void emitYield() { - +void emitSchedYield() { + // create Symbol Table Entroy for yield - createSymbolTableEntry(GLOBAL_TABLE, (int*) "yield", binaryLength, FUNCTION, INT_T, 0); - + createSymbolTableEntry(GLOBAL_TABLE, (int*) "sched_yield", binaryLength, FUNCTION, INT_T, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_YIELD); - emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SCHED_YIELD); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void syscall_yield(){ +void syscall_sched_yield(){ schedule_and_switch(); - if (debug_yield) { + if (debug_sched_yield) { print(binaryName); println(); - print((int*) "yield"); + print((int*) "sched_yield"); println(); } } -void emitSwitchEmu() { - - // create Symbol Table Entroy for switch_emu - createSymbolTableEntry(GLOBAL_TABLE, (int*) "switchEmu", binaryLength, FUNCTION, INT_T, 0); - +void emitSwitch() { + + // create Symbol Table Entry for swapoff + createSymbolTableEntry(GLOBAL_TABLE, (int*) "switch", binaryLength, FUNCTION, INT_T, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SWITCH_EMU); - emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SWITCH); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void syscall_switchEmu(){ +void syscall_switch() { - int* Buffer; - Buffer = (int*)malloc(4*10); + if(*(running_process) == 0){ - print((int*) "_________________________________________________"); - println(); - print((int*) "_________________________________________________"); - println(); - print((int*) "_________________________________________________"); - println(); - print((int*) "This is the Process List before running kernel"); - println(); - print((int*) "_________________________________________________"); - println(); - print((int*) "PIDs"); - println(); - printListPID(process_list); - print((int*) "PCs"); - println(); - printListPC(process_list); - print((int*) "Segment Start"); - println(); - printListSegment(process_list); - print((int*) "_________________________________________________"); - println(); - print((int*) "Ready-Queue before running Kernel"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - printListSegment(ready_queue); - print((int*) "_________________________________________________"); - println(); + prev_node = getNodeByIdFromProcessList(running_process_id); + prev_process = (int*) (prev_node); - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0, 0)); - println(); - print((int*) "PC"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0, 0)); - println(); + syscall_getpid(); - print((int*) "Running Process ID"); - println(); - print(itoa(running_process_id, Buffer, 10, 0, 0)); - println(); + next_node = getNodeByIdFromProcessList(running_process_id); + next_process = (int*) (next_node); + + *(running_process + 1) = *(running_process + 1) + 1; - prev_node = getNodeByIdFromProcessList(running_process_id); - prev_process = (int*) (prev_node); + running_process = next_process ; - if(running_process_id == number_of_processes){ - running_process_id = 1; - print((int*) "if"); + ready_queue = deleteFirstNodeFromList(ready_queue); + println(); + println(); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "Running Kernel Process and Switch to User Process"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); println(); } else{ - running_process_id = running_process_id + 1; - print((int*) "else"); + prev_node = getNodeByIdFromProcessList(running_process_id); + prev_process = (int*) (prev_node); + + next_node = getNodeByIdFromProcessList(0); + next_process = (int*) (next_node); + + running_process = next_process; + + ready_queue = addToList(ready_queue, (int) prev_process); println(); - } + println(); + println(); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "Running User Process and Switch to Kernel Process"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + + } + +} - next_node = getNodeByIdFromProcessList(running_process_id); - next_process = (int*) (next_node); +void emitMlock() { + createSymbolTableEntry(GLOBAL_TABLE, (int*) "mlock", binaryLength, FUNCTION, INT_T, 0); - *(running_process + 1) = *(running_process + 1) + 1; + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); + + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_MLOCK); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - running_process = next_process ; + // We don't have a return value so we just jump back + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); +} - ready_queue = deleteFirstNodeFromList(ready_queue); +void syscall_mlock() { + *lock = *(running_process); - print((int*) "_________________________________________________"); println(); - print((int*) "_________________________________________________"); + println(); println(); - print((int*) "_________________________________________________"); println(); - print((int*) "This is the Process List after running kernel"); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - print((int*) "_________________________________________________"); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - print((int*) "PIDs"); + print((int*) "Running User Process get's the lock"); println(); - printListPID(process_list); - print((int*) "PCs"); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - printListPC(process_list); - print((int*) "Segment Start"); - println(); - printListSegment(process_list); - - print((int*) "_________________________________________________"); - - println(); - print((int*) "Ready-Queue after running Kernel"); - println(); - print((int*) "PIDs"); - println(); - printListPID(ready_queue); - print((int*) "PCs"); - println(); - printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - printListSegment(ready_queue); - - print((int*) "_________________________________________________"); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); +} - print((int*) "Running Process"); - println(); - print((int*) "PID"); - println(); - print(itoa(*(running_process), Buffer, 10, 0, 0)); - println(); - print((int*) "PC"); - println(); - print(itoa(*(running_process+1), Buffer, 10, 0, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0, 0)); - println(); +void emitMunlock() { + createSymbolTableEntry(GLOBAL_TABLE, (int*) "munlock", binaryLength, FUNCTION, INT_T, 0); - print((int*) "Running Process ID"); - println(); - print(itoa(running_process_id, Buffer, 10, 0, 0)); - println(); + // doesn't have any arguments + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); + emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); - if (debug_switch_emu) { - print(binaryName); - println(); - print((int*) "switchEmu"); - println(); - } + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_MUNLOCK); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + // We don't have a return value so we just jump back + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void emitSwitchOS() { +void syscall_munlock() { + int size; + int new_size; + int i; + int* node; + int* process; + + i = 0; + size = sizeOfList(blocked_queue); + *lock = 0; + + while(i < size){ + new_size = sizeOfList(blocked_queue) - 1; + node = (int*) getNodeFromList(blocked_queue, new_size); + process = (int*) *(node + 1); + blocked_queue = deleteFirstNodeFromList(blocked_queue); + ready_queue = addToList(ready_queue,(int) process); + i = i + 1; + } +} - // create Symbol Table Entroy for switch_os - createSymbolTableEntry(GLOBAL_TABLE, (int*) "switchOS", binaryLength, FUNCTION, INT_T, 0); +void emitGetpid() { + createSymbolTableEntry(GLOBAL_TABLE, (int*) "getpid", binaryLength, FUNCTION, INT_T, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); - emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SWITCH_OS); + + emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_GETPID); emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + // We don't have a return value so we just jump back + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } -void syscall_switchOS(){ - - prev_node = getNodeByIdFromProcessList(running_process_id); - prev_process = (int*) (prev_node); - - next_node = getNodeByIdFromProcessList(0); - next_process = (int*) (next_node); +void syscall_getpid(int* list) { - running_process = next_process; + int* node; + int* process; + int size; - ready_queue = addToList(ready_queue, (int) prev_process); + size = sizeOfList(ready_queue)-1; - if (debug_switch_os) { - print(binaryName); - println(); - print((int*) "switchOS"); - println(); - } + node = (int*) getNodeFromList(ready_queue, size); + process = (int*) *(node + 1); + running_process_id = *(process); } @@ -4176,17 +4243,17 @@ int* getNodeByIdFromProcessList(int id){ int* Buffer; i = 0; - + Buffer = (int*)malloc(4*10); - + while(i < all_processes) { node_i = (int*) getNodeFromList(process_list, i); - process_i = (int*) *(node_i + 1); - + process_i = (int*) *(node_i + 1); + j = (int) *(process_i); - + if(j == id){ - + return process_i; } i = i + 1; @@ -4200,7 +4267,7 @@ void create_process_List(int number){ int *process; int pid_process_list; int pid_ready_queue; - + pid_process_list = 0; pid_ready_queue = number_of_processes - 1; @@ -4214,63 +4281,430 @@ void create_process_List(int number){ else{ node = (int*) getNodeFromList(ready_queue, pid_ready_queue); process = (int*) *(node+1); - process_list = addToList(process_list, (int) process); + process_list = addToList(process_list, (int) process); pid_process_list = pid_process_list + 1; - pid_ready_queue = pid_ready_queue - 1; + pid_ready_queue = pid_ready_queue - 1; } } } -void runOS(int argc, int* argv){ - - while(1){ - syscall_switchEmu(); - run(argc, (int*) argv); - } +// ------------------------ DATA STRUCTURE FOR THE LOCK ----------------------- +// Creating a the Lock with Process ID which holds the Lock +// and a Pointer to the Blocked Queue +void create_lock(){ + lock = malloc(2 * 4); + *lock = 0; + *(lock+1) = *blocked_queue; } -void kOS(int argc, int* argv) { - int *new_reg; - int* Buffer; - if(booting == 1){ +// Sort the list with Bubble Sort +int* sortListByPC(int *list) { - booting = 0; + int size; + int i; + int *listNodeX; + int *listNodeY; + int *tempNode; + int *listProcessX; + int *listProcessY; + int listProcessPCX; + int listProcessPCY; + int* Buffer; + + Buffer = (int*)malloc(4*10); + size = sizeOfList(list); - new_reg = malloc(4*32); - Buffer = (int*)malloc(4*10); - all_processes = number_of_processes + 1; + if(size == 0){ + print((int*) "List is empty"); + println(); + } + else{ + while(size > 1){ + + print((int*) "List is not empty"); + println(); + i = 0; + while(i < size-1) { + listNodeX = (int*) getNodeFromList(list, i); + listNodeY = (int*) getNodeFromList(list, i+1); + listProcessX = (int*) *(listNodeX + 1); + listProcessY = (int*) *(listNodeY + 1); + listProcessPCX = *(listProcessX+1); + listProcessPCY = *(listProcessY+1); + + println(); + print(itoa(listProcessPCX, Buffer, 10, 0, 0)); + println(); + + println(); + print(itoa(listProcessPCY, Buffer, 10, 0, 0)); + println(); + + if(listProcessPCX < listProcessPCY) { + print((int*) "change"); + println(); + *(listNodeX + 1) = (int) listProcessY; + *(listNodeY + 1) = (int) listProcessX; + } + else{ + print((int*) "no change"); + println(); + } + i = i + 1; + } + size = size - 1; + } + } - kernel_process = create_process(0, new_reg, reg_hi, reg_lo, 0); - running_process = kernel_process; + print((int*) "____________________________________________________"); + println(); + print((int*) "This is the Ready-Queue after sorting"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + printListSegment(ready_queue); - create_segmentation_table(all_processes); - create_ready_queue(all_processes, ticks); - create_process_List(all_processes); + return list; +} - print((int*) "_________________________________________________"); +void runOS(int argc, int* argv){ + + int* Buffer; + Buffer = (int*)malloc(4*10); + + + while(1){ println(); - print((int*) "__This is the Process List after initialization__"); println(); - print((int*) "_________________________________________________"); println(); - print((int*) "PIDs"); println(); - printListPID(process_list); - print((int*) "PCs"); println(); - printListPC(process_list); - print((int*) "Segment Start"); - println(); - printListSegment(process_list); - - print((int*) "_________________________________________________"); + print((int*) "BEFORE RUNNING KERNEL"); println(); - print((int*) "__This is the Ready Queue after initialization___"); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "This is the Process-List before running kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(process_list); + print((int*) "PCs"); + println(); + printListPC(process_list); + print((int*) "Segment Start"); + println(); + printListSegment(process_list); + print((int*) "____________________________________________________"); + println(); + print((int*) "This is the Ready-Queue before running Kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + printListSegment(ready_queue); + print((int*) "____________________________________________________"); + println(); + print((int*) "This is the Blocked-Queue before running Kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(blocked_queue); + print((int*) "PCs"); + println(); + printListPC(blocked_queue); + print((int*) "Segment Start"); + println(); + printListSegment(blocked_queue); + print((int*) "____________________________________________________"); + println(); + print((int*) "This is the Running Process before running Kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0, 0)); + println(); + + syscall_switch(); + + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "This is the Process-List after running kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "PIDs"); + println(); + printListPID(process_list); + print((int*) "PCs"); + println(); + printListPC(process_list); + print((int*) "Segment Start"); + println(); + printListSegment(process_list); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "This is the Ready-Queue after running kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "PIDs"); + println(); + printListPID(ready_queue); + print((int*) "PCs"); + println(); + printListPC(ready_queue); + print((int*) "Segment Start"); + println(); + printListSegment(ready_queue); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "This is the Blocked-Queue after running kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "PIDs"); + println(); + printListPID(blocked_queue); + print((int*) "PCs"); + println(); + printListPC(blocked_queue); + print((int*) "Segment Start"); + println(); + printListSegment(blocked_queue); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "This is the Running-Process after running kernel"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "PID"); + println(); + print(itoa(*(running_process), Buffer, 10, 0, 0)); + println(); + print((int*) "PC"); + println(); + print(itoa(*(running_process+1), Buffer, 10, 0, 0)); + println(); + print((int*) "Segment Start"); + println(); + print(itoa(*(running_process+3), Buffer, 10, 0, 0)); + println(); + + if(debug_locking == 1){ + if(*lock == 0){ + syscall_mlock(); + debug_locking = 0; + run(argc, (int*) argv); + } + else if(*lock == *running_process){ + + syscall_munlock(); + + ready_queue = sortListByPC(ready_queue); + + debug_locking = 0; + + println(); + println(); + println(); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "Unlocking and adding all User Process from the Blocked-Queue to the Ready-Queue"); + println(); + print((int*) "and then running the actual User Process"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + run(argc, (int*) argv); + } + else{ + blocked_queue = addToList(blocked_queue, (int) running_process); + running_process = kernel_process; + + println(); + println(); + println(); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "Running User Process added to Blocked-Queue"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + debug_locking = 0; + } + } + else{ + + if(*lock == *running_process){ + + syscall_munlock(); + + ready_queue = sortListByPC(ready_queue); + + debug_locking = 0; + + println(); + println(); + println(); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "Unlocking and adding all User Process from the Blocked-Queue to the Ready-Queue"); + println(); + print((int*) "and then running the actual User Process"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + run(argc, (int*) argv); + } + else{ + println(); + println(); + println(); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "Running User Process does not need the lock"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + println(); + debug_locking = 1; + run(argc, (int*) argv); + } + } + } + +} + +void kOS(int argc, int* argv) { + int *new_reg; + int* Buffer; + + if(booting == 1){ + + booting = 0; + + new_reg = malloc(4*32); + Buffer = (int*)malloc(4*10); + + all_processes = number_of_processes + 1; + + kernel_process = create_process(0, new_reg, reg_hi, reg_lo, 0); + running_process = kernel_process; + + create_segmentation_table(all_processes); + create_ready_queue(all_processes, ticks); + create_process_List(all_processes); + blocked_queue = initializeList(blocked_queue); + create_lock(); + + println(); + println(); + println(); + println(); + println(); + print((int*) "BOOTING"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "____________________________________________________"); + println(); + println(); + print((int*) "This is the Process-List after Booting"); + println(); + print((int*) "____________________________________________________"); + println(); + print((int*) "PIDs"); + println(); + printListPID(process_list); + print((int*) "PCs"); println(); - print((int*) "_________________________________________________"); + printListPC(process_list); + print((int*) "Segment Start"); + println(); + printListSegment(process_list); + print((int*) "____________________________________________________"); + println(); + print((int*) "This is the Ready-Queue after Booting"); + println(); + print((int*) "____________________________________________________"); println(); print((int*) "PIDs"); println(); @@ -4284,12 +4718,26 @@ void kOS(int argc, int* argv) { print((int*) "____________________________________________________"); println(); - print((int*) "__This is the Running Process after initialization__"); + print((int*) "This is the Blocked-Queue after Booting"); println(); print((int*) "____________________________________________________"); println(); - print((int*) "Running Process"); + print((int*) "PIDs"); + println(); + printListPID(blocked_queue); + print((int*) "PCs"); + println(); + printListPC(blocked_queue); + print((int*) "Segment Start"); + println(); + printListSegment(blocked_queue); + + print((int*) "____________________________________________________"); + println(); + print((int*) "This is the Running-Process after Booting"); println(); + print((int*) "____________________________________________________"); + println(); print((int*) "PID"); println(); print(itoa(*(running_process), Buffer, 10, 0, 0)); @@ -4297,15 +4745,15 @@ void kOS(int argc, int* argv) { print((int*) "PC"); println(); print(itoa(*(running_process+1), Buffer, 10, 0, 0)); - println(); + println(); print((int*) "Segment Start"); println(); print(itoa(*(running_process+3), Buffer, 10, 0, 0)); println(); - + runOS(argc, (int*) argv); } - + else{ runOS(argc, (int*) argv); } @@ -4351,243 +4799,491 @@ void storeMemory(int vaddr, int data) { // ----------------------------------------------------------------- void fct_syscall() { - if (debug_disassemble) { + if (debug) { printFunction(function); println(); } - if (*(registers+REG_V0) == SYSCALL_EXIT) { - syscall_exit(); - } else if (*(registers+REG_V0) == SYSCALL_READ) { - syscall_read(); - } else if (*(registers+REG_V0) == SYSCALL_WRITE) { - syscall_write(); - } else if (*(registers+REG_V0) == SYSCALL_OPEN) { - syscall_open(); - } else if (*(registers+REG_V0) == SYSCALL_MALLOC) { - syscall_malloc(); - } else if (*(registers+REG_V0) == SYSCALL_YIELD) { - syscall_yield(); - } else if (*(registers+REG_V0) == SYSCALL_SWITCH_EMU) { - syscall_switchEmu(); - } else if (*(registers+REG_V0) == SYSCALL_SWITCH_OS) { - syscall_switchOS(); - } else { - exception_handler(EXCEPTION_UNKNOWNSYSCALL); - } + if (interpret) { + if (*(registers+REG_V0) == SYSCALL_EXIT) { + syscall_exit(); + } else if (*(registers+REG_V0) == SYSCALL_READ) { + syscall_read(); + } else if (*(registers+REG_V0) == SYSCALL_WRITE) { + syscall_write(); + } else if (*(registers+REG_V0) == SYSCALL_OPEN) { + syscall_open(); + } else if (*(registers+REG_V0) == SYSCALL_MALLOC) { + syscall_malloc(); + } else if (*(registers+REG_V0) == SYSCALL_SCHED_YIELD) { + syscall_sched_yield(); + } else if (*(registers+REG_V0) == SYSCALL_SWITCH) { + syscall_switch(); + } else { + exception_handler(EXCEPTION_UNKNOWNSYSCALL); + } - pc = pc + 4; + pc = pc + 4; + } } void fct_nop() { - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); println(); } + + if (interpret) + pc = pc + 4; } void op_jal() { - *(registers+REG_RA) = pc + 8; + if (debug) { + printOpcode(opcode); + print((int*) " "); + print(itoa(instr_index, string_buffer, 16, 0, 0)); + print((int*) "["); + print(itoa(instr_index * 4, string_buffer, 16, 0, 0)); + print((int*) "]"); + if (interpret) { + print((int*) ": "); + printRegister(REG_RA); + print((int*) "="); + print(itoa(*(registers+REG_RA), string_buffer, 16, 0, 0)); + } + } - pc = instr_index * 4; + if (interpret) { + *(registers+REG_RA) = pc + 8; - // keep track of number of procedure calls - calls = calls + 1; + pc = instr_index * 4; - *(callsPerAddress + pc / 4) = *(callsPerAddress + pc / 4) + 1; + // keep track of number of procedure calls + calls = calls + 1; - // TODO: execute delay slot + *(callsPerAddress + pc / 4) = *(callsPerAddress + pc / 4) + 1; - if (debug_disassemble) { - printOpcode(opcode); - print((int*) " "); - print(itoa(instr_index, string_buffer, 16, 8, 0)); + // TODO: execute delay slot + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(REG_RA); + print((int*) "="); + print(itoa(*(registers+REG_RA), string_buffer, 16, 0, 0)); + print((int*) ",$pc="); + print(itoa(pc, string_buffer, 16, 0, 0)); + } println(); } } void op_j() { - pc = instr_index * 4; - - // TODO: execute delay slot - - if (debug_disassemble) { + if (debug) { printOpcode(opcode); print((int*) " "); - print(itoa(instr_index, string_buffer, 16, 8, 0)); - println(); + print(itoa(instr_index, string_buffer, 16, 0, 0)); + print((int*) "["); + print(itoa(instr_index * 4, string_buffer, 16, 0, 0)); + print((int*) "]"); } -} - -void op_beq() { - pc = pc + 4; - if (*(registers+rs) == *(registers+rt)) { - pc = pc + signExtend(immediate) * 4; + if (interpret) { + pc = instr_index * 4; - if (signExtend(immediate) < 0) { - // keep track of number of loop iterations - loops = loops + 1; + // TODO: execute delay slot + } - *(loopsPerAddress + pc / 4) = *(loopsPerAddress + pc / 4) + 1; + if (debug) { + if (interpret) { + print((int*) ": -> $pc="); + print(itoa(pc, string_buffer, 16, 0, 0)); } - - // TODO: execute delay slot + println(); } +} - if (debug_disassemble) { +void op_beq() { + if (debug) { printOpcode(opcode); print((int*) " "); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); - putchar(','); + print((int*) ","); print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); - println(); + print((int*) "["); + print(itoa(pc + 4 + signExtend(immediate) * 4, string_buffer, 16, 0, 0)); + print((int*) "]"); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } } -} -void op_bne() { - pc = pc + 4; + if (interpret) { + pc = pc + 4; - if (*(registers+rs) != *(registers+rt)) { - pc = pc + signExtend(immediate) * 4; + if (*(registers+rs) == *(registers+rt)) { + pc = pc + signExtend(immediate) * 4; - // TODO: execute delay slot + if (signExtend(immediate) < 0) { + // keep track of number of loop iterations + loops = loops + 1; + + *(loopsPerAddress + pc / 4) = *(loopsPerAddress + pc / 4) + 1; + } + + // TODO: execute delay slot + } } - if (debug_disassemble) { + if (debug) { + if (interpret) { + print((int*) " -> $pc="); + print(itoa(pc, string_buffer, 16, 0, 0)); + } + println(); + } +} + +void op_bne() { + if (debug) { printOpcode(opcode); print((int*) " "); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); - putchar(','); + print((int*) ","); print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); - println(); + print((int*) "["); + print(itoa(pc + 4 + signExtend(immediate) * 4, string_buffer, 16, 0, 0)); + print((int*) "]"); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } } -} -void op_addiu() { - *(registers+rt) = *(registers+rs) + signExtend(immediate); + if (interpret) { + pc = pc + 4; - // TODO: check for overflow + if (*(registers+rs) != *(registers+rt)) { + pc = pc + signExtend(immediate) * 4; - pc = pc + 4; + // TODO: execute delay slot + } + } - if (debug_disassemble) { + if (debug) { + if (interpret) { + print((int*) " -> $pc="); + print(itoa(pc, string_buffer, 16, 0, 0)); + } + println(); + } +} + +void op_addiu() { + if (debug) { printOpcode(opcode); print((int*) " "); printRegister(rt); - putchar(','); + print((int*) ","); printRegister(rs); - putchar(','); + print((int*) ","); print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); + if (interpret) { + print((int*) ": "); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + *(registers+rt) = *(registers+rs) + signExtend(immediate); + + // TODO: check for overflow + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } println(); } } void fct_jr() { - pc = *(registers+rs); - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rs); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 16, 0, 0)); + } + } + + if (interpret) + pc = *(registers+rs); + + if (debug) { + if (interpret) { + print((int*) " -> $pc="); + print(itoa(pc, string_buffer, 16, 0, 0)); + } println(); } } void fct_mfhi() { - *(registers+rd) = reg_hi; - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rd); + if (interpret) { + print((int*) ": "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + print((int*) ",$hi="); + print(itoa(reg_hi, string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + *(registers+rd) = reg_hi; + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + } println(); } } void fct_mflo() { - *(registers+rd) = reg_lo; - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rd); + if (interpret) { + print((int*) ": "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + print((int*) ",$lo="); + print(itoa(reg_lo, string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + *(registers+rd) = reg_lo; + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + } println(); } } void fct_multu() { - // TODO: 64-bit resolution currently not supported - reg_lo = *(registers+rs) * *(registers+rt); - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) ",$lo="); + print(itoa(reg_lo, string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + // TODO: 64-bit resolution currently not supported + reg_lo = *(registers+rs) * *(registers+rt); + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> $lo="); + print(itoa(reg_lo, string_buffer, 10, 0, 0)); + } println(); } } void fct_divu() { - reg_lo = *(registers+rs) / *(registers+rt); - reg_hi = *(registers+rs) % *(registers+rt); - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) ",$lo="); + print(itoa(reg_lo, string_buffer, 10, 0, 0)); + print((int*) ",$hi="); + print(itoa(reg_hi, string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + reg_lo = *(registers+rs) / *(registers+rt); + reg_hi = *(registers+rs) % *(registers+rt); + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> $lo="); + print(itoa(reg_lo, string_buffer, 10, 0, 0)); + print((int*) ",$hi="); + print(itoa(reg_hi, string_buffer, 10, 0, 0)); + } println(); } } void fct_addu() { - *(registers+rd) = *(registers+rs) + *(registers+rt); - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rd); - putchar(','); + print((int*) ","); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); + if (interpret) { + print((int*) ": "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + *(registers+rd) = *(registers+rs) + *(registers+rt); + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + } println(); } } void fct_subu() { - *(registers+rd) = *(registers+rs) - *(registers+rt); - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rd); - putchar(','); + print((int*) ","); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); + if (interpret) { + print((int*) ": "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + *(registers+rd) = *(registers+rs) - *(registers+rt); + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + } println(); } } @@ -4595,46 +5291,91 @@ void fct_subu() { void op_lw() { int vaddr; - vaddr = *(registers+rs) + signExtend(immediate); - - *(registers+rt) = loadMemory(vaddr); - - // keep track of number of loads - loads = loads + 1; - - *(loadsPerAddress + pc / 4) = *(loadsPerAddress + pc / 4) + 1; - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printOpcode(opcode); print((int*) " "); printRegister(rt); - putchar(','); + print((int*) ","); print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); - putchar('('); + print((int*) "("); printRegister(rs); - putchar(')'); + print((int*) ")"); + if (interpret) { + print((int*) ": "); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 16, 0, 0)); + } + } + + if (interpret) { + vaddr = *(registers+rs) + signExtend(immediate); + + *(registers+rt) = loadMemory(vaddr); + + // keep track of number of loads + loads = loads + 1; + + *(loadsPerAddress + pc / 4) = *(loadsPerAddress + pc / 4) + 1; + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) "=memory[vaddr="); + print(itoa(vaddr, string_buffer, 16, 0, 0)); + print((int*) "]"); + } println(); } } void fct_slt() { - if (*(registers+rs) < *(registers+rt)) - *(registers+rd) = 1; - else - *(registers+rd) = 0; - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rd); - putchar(','); + print((int*) ","); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } + } + + if (interpret) { + if (*(registers+rs) < *(registers+rt)) + *(registers+rd) = 1; + else + *(registers+rd) = 0; + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> "); + printRegister(rd); + print((int*) "="); + print(itoa(*(registers+rd), string_buffer, 10, 0, 0)); + } println(); } } @@ -4642,44 +5383,81 @@ void fct_slt() { void op_sw() { int vaddr; - vaddr = *(registers+rs) + signExtend(immediate); - - storeMemory(vaddr, *(registers+rt)); - - // keep track of number of stores - stores = stores + 1; - - *(storesPerAddress + pc / 4) = *(storesPerAddress + pc / 4) + 1; - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printOpcode(opcode); print((int*) " "); printRegister(rt); - putchar(','); + print((int*) ","); print(itoa(signExtend(immediate), string_buffer, 10, 0, 0)); - putchar('('); + print((int*) "("); printRegister(rs); - putchar(')'); + print((int*) ")"); + if (interpret) { + print((int*) ": "); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 16, 0, 0)); + } + } + + if (interpret) { + vaddr = *(registers+rs) + signExtend(immediate); + + storeMemory(vaddr, *(registers+rt)); + + // keep track of number of stores + stores = stores + 1; + + *(storesPerAddress + pc / 4) = *(storesPerAddress + pc / 4) + 1; + + pc = pc + 4; + } + + if (debug) { + if (interpret) { + print((int*) " -> memory[vaddr="); + print(itoa(vaddr, string_buffer, 16, 0, 0)); + print((int*) "]="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + print((int*) "="); + printRegister(rt); + } println(); } } void fct_teq() { - if (*(registers+rs) == *(registers+rt)) - exception_handler(EXCEPTION_SIGNAL); - - pc = pc + 4; - - if (debug_disassemble) { + if (debug) { printFunction(function); print((int*) " "); printRegister(rs); - putchar(','); + print((int*) ","); printRegister(rt); - println(); + if (interpret) { + print((int*) ": "); + printRegister(rs); + print((int*) "="); + print(itoa(*(registers+rs), string_buffer, 10, 0, 0)); + print((int*) ","); + printRegister(rt); + print((int*) "="); + print(itoa(*(registers+rt), string_buffer, 10, 0, 0)); + } } + + if (interpret) { + if (*(registers+rs) == *(registers+rt)) + exception_handler(EXCEPTION_SIGNAL); + + pc = pc + 4; + } + + if (debug) + println(); } // ----------------------------------------------------------------- @@ -4699,40 +5477,31 @@ void exception_handler(int enumber) { exit(enumber); } -void pre_debug() { - if (debug_disassemble) { - print(binaryName); - print((int*) ": $pc="); - print(itoa(pc, string_buffer, 16, 8, 0)); - print((int*) ": "); - } +void fetch() { + ir = loadMemory(pc); } -void post_debug() { - int i; - if (debug_registers) { - i = 0; +void execute() { + if (debug) + if (sourceLineNumber != (int*) 0) { + print(binaryName); + print((int*) ": "); + } - while (i < 32) { - if (*(registers+i) != 0) { - print(binaryName); - print((int*) ": "); - printRegister(i); - putchar(CHAR_EQUAL); - print(itoa(*(registers+i), string_buffer, 16, 8, 0)); - println(); - } - i = i + 1; + if (interpret) + if (debug) + print((int*) "$pc="); + + if (debug) { + print(itoa(pc, string_buffer, 16, 8, 0)); + if (sourceLineNumber != (int*) 0) { + print((int*) "(~"); + print(itoa(*(sourceLineNumber + pc / 4), string_buffer, 10, 0, 0)); + print((int*) ")"); } - println(); + print((int*) ": "); } -} - -void fetch() { - ir = loadMemory(pc); -} -void execute() { if (opcode == OP_SPECIAL) { if (function == FCT_NOP) { fct_nop(); @@ -4776,6 +5545,13 @@ void execute() { } else { exception_handler(EXCEPTION_UNKNOWNINSTRUCTION); } + + if (interpret == 0) { + if (pc == codeLength - 4) + halt = 1; + else + pc = pc + 4; + } } // Print the value of the Process IDs @@ -4806,7 +5582,7 @@ void printListPC(int *list) { int counter; int number; - int *Buffer; + int *Buffer; int *node; int *process; @@ -4828,7 +5604,7 @@ void printListSegment(int *list) { int counter; int number; - int *Buffer; + int *Buffer; int *node; int *process; @@ -4847,39 +5623,28 @@ void printListSegment(int *list) { void run(int argc, int* argv) { - int instr; - int *Buffer; + int instr; - instr = 0; - halt = 0; + instr = 0; + halt = 0; - while (halt == 0) { - //fetch(); - //decode(); - //pre_debug(); - //execute(); - //post_debug(); - - instr = instr + 1; - *(running_process + 1) = *(running_process + 1) + 1; - - if(instr == numb_of_instr){ - print((int*) "Running Process"); - println(); - halt = 1; - } + while (halt == 0) { - } + instr = instr + 1; + *(running_process + 1) = *(running_process + 1) + 1; + + if(instr == numb_of_instr){ + halt = 1; + } + } - syscall_switchOS(); - kOS(argc, (int*) argv); + interpret = 0; + debug = 0; + syscall_switch(); + kOS(argc, (int*) argv); } -// ----------------------------------------------------------------- -// ----------------------------- MAIN ------------------------------ -// ----------------------------------------------------------------- - void up_push(int value) { int vaddr; @@ -4914,6 +5679,7 @@ int up_copyString(int *s) { w = a + l; if (l % 4 != 0) + // making sure w is a multiple of 4 bytes w = w + 4 - l % 4; t = a; @@ -4987,9 +5753,14 @@ int addressWithMaxCounter(int *counters, int max) { } int fixedPointRatio(int a, int b) { + // assert: a >= b int r; + // compute fixed point ratio r with 2 fractional digits + r = 0; + + // multiply a/b with 100 but avoid overflow if (a <= INT_MAX / 100) { if (b != 0) @@ -5002,6 +5773,9 @@ int fixedPointRatio(int a, int b) { r = a / (b / 100); } + // compute a/b in percent + // 1000000 = 10000 (for 100.00%) * 100 (for 2 fractional digits of r) + if (r != 0) return 1000000 / r; else @@ -5014,15 +5788,15 @@ int printCounters(int total, int *counters, int max) { a = addressWithMaxCounter(counters, max); print(itoa(*(counters + a / 4), string_buffer, 10, 0, 0)); - + print((int*) "("); print(itoa(fixedPointRatio(total, *(counters + a / 4)), string_buffer, 10, 0, 2)); print((int*) "%)"); - + if (*(counters + a / 4) != 0) { print((int*) "@"); print(itoa(a, string_buffer, 16, 8, 0)); - if (sourceLineNumber != (int*) 0){ + if (sourceLineNumber != (int*) 0) { print((int*) "(~"); print(itoa(*(sourceLineNumber + a / 4), string_buffer, 10, 0, 0)); print((int*) ")"); @@ -5040,15 +5814,48 @@ void printProfile(int *message, int total, int *counters) { print(message); print(itoa(total, string_buffer, 10, 0, 0)); print((int*) ","); - a = printCounters(total, counters, INT_MAX); + a = printCounters(total, counters, INT_MAX); // max counter print((int*) ","); - a = printCounters(total, counters, *(counters + a / 4)); + a = printCounters(total, counters, *(counters + a / 4)); // 2nd max print((int*) ","); - a = printCounters(total, counters, *(counters + a / 4)); + a = printCounters(total, counters, *(counters + a / 4)); // 3rd max println(); } } +void disassemble(int argc, int* argv) { + assemblyFD = open(assemblyName, O_CREAT_WRONLY_TRUNC, S_IRUSR_IWUSR_IRGRP_IROTH); + + if (assemblyFD < 0) { + print(selfieName); + print((int*) ": could not create assembly output file "); + print(assemblyName); + println(); + + exit(-1); + } + + print(selfieName); + print((int*) ": writing assembly into output file "); + print(assemblyName); + println(); + + outputName = assemblyName; + outputFD = assemblyFD; + + interpret = 0; + debug = 1; + + copyBinaryToMemory(); + + resetInterpreter(); + + run(argc, (int*) argv); + + outputName = (int*) 0; + outputFD = 1; +} + //// Assignment 0: Basic data structures //// //Review linked lists and implement a simple program using a singly linked list in C*. The minimal requirements are as follows: // @@ -5118,10 +5925,16 @@ int* deleteFirstNodeFromList(int *list) { *prev = 0; *next = 0; size = sizeOfList(list); - - prev = (int*) getNodeFromList(list, size-2); - next = (int*) getNodeFromList(list, size); - *prev = (int) next; + + if(size == 1){ + list = initializeList(list); + } + else{ + + prev = (int*) getNodeFromList(list, size-2); + next = (int*) getNodeFromList(list, size); + *prev = (int) next; + } return list; } @@ -5129,7 +5942,7 @@ int* deleteFirstNodeFromList(int *list) { // Sort the list with Bubble Sort int* sortList(int *list) { - int size; + int size; int i; int *listitemX; int *listitemY; @@ -5138,21 +5951,28 @@ int* sortList(int *list) { size = sizeOfList(list); - while(size > 1){ - i = 0; - while(i < size-1) { - listitemX = (int*) getNodeFromList(list, i); - listitemY = (int*) getNodeFromList(list, i+1); - x = *(listitemX+1); - y = *(listitemY+1); - - if(x < y) { - *(listitemX + 1) = y; - *(listitemY + 1) = x; + + if(size == 0){ + print((int*) "List is empty"); + println(); + } + else{ + while(size > 1){ + i = 0; + while(i < size-1) { + listitemX = (int*) getNodeFromList(list, i); + listitemY = (int*) getNodeFromList(list, i+1); + x = *(listitemX+1); + y = *(listitemY+1); + + if(x < y) { + *(listitemX + 1) = y; + *(listitemY + 1) = x; + } + i = i + 1; } - i = i + 1; + size = size - 1; } - size = size - 1; } return list; } @@ -5162,9 +5982,9 @@ void printList(int *list) { int counter; int *nodeNumber; - int number; - int *Buffer; - + int number; + int *Buffer; + counter = sizeOfList(list)-1; while(counter >= 0) { @@ -5184,7 +6004,7 @@ int testList() { // Create new linked list (FIFO Linked List): // top -> [9,7,8,2,4,1,5,3] -> bottom print((int*) "Insert into list"); - println(); + println(); list = initializeList(list); list = addToList(list, 9); list = addToList(list, 7); @@ -5199,16 +6019,21 @@ int testList() { // Delete the first node (FIFO Linked List): // top -> [2,4,1,5,3] -> bottom print((int*) "Delete first Node"); - println(); - list = deleteFirstNodeFromList(list); - list = deleteFirstNodeFromList(list); - list = deleteFirstNodeFromList(list); + println(); + list = deleteFirstNodeFromList(list); //9 + list = deleteFirstNodeFromList(list); //7 + list = deleteFirstNodeFromList(list); //8 + list = deleteFirstNodeFromList(list); //2 + list = deleteFirstNodeFromList(list); //4 + list = deleteFirstNodeFromList(list); //1 + list = deleteFirstNodeFromList(list); //5 + list = deleteFirstNodeFromList(list); //3 printList(list); // Sorting the list // top -> [5,4,3,2,1] -> bottom print((int*) "Sorting the List"); - println(); + println(); list = sortList(list); printList(list); @@ -5218,15 +6043,15 @@ int testList() { // ------------------------ DATA STRUCTURE FOR A SEGMENT ----------------------- // Creating a new Segment with Startaddress (start) and Size (size). int* create_segment(int* start){ - //initialization of the process - int* segment; + //initialization of the process + int* segment; //memory allocation segment = malloc (2 * 4); - - //initalization of the argments of the process + + //initalization of the argments of the process *segment = (int) start; *(segment+1) = segment_size; - + return segment; } @@ -5240,27 +6065,27 @@ void create_segmentation_table(int segments){ segment_size = 1024 * 1024 / 4; memory_size = segments * segment_size; segmentation_table = (int*)malloc(segments * 4); - memory = (int*)malloc(memory_size); + memory = (int*)malloc(memory_size); } // ------------------------ DATA STRUCTURE FOR A PROCESS ----------------------- -// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), +// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), // Address to the Register (new_reg), Address to the Memory (new_mem), // hi register for multiplication/division (new_reg_hi) and // lo register for multiplication/division (new_reg_lo) and int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ - //initialization of the process + //initialization of the process int* process; - int start_n_segment; - int* segment; + int start_n_segment; + int* segment; int* start; //memory allocation - process = malloc (7 * 4); + process = malloc (7 * 4); if(new_pid == 0){ - //initalization of the argments of the process + //initalization of the argments of the process *process = new_pid; *(process+1) = 0; *(process+2) = (int) new_reg; @@ -5268,7 +6093,7 @@ int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, i *(process+4) = new_reg_hi; *(process+5) = new_reg_lo; *(process+6) = segment_number; - + return process; } else{ @@ -5277,7 +6102,7 @@ int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, i segment = (int*) create_segment(start); - //initalization of the argments of the process + //initalization of the argments of the process *process = new_pid; *(process+1) = 0; *(process+2) = (int) new_reg; @@ -5285,7 +6110,7 @@ int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, i *(process+4) = new_reg_hi; *(process+5) = new_reg_lo; *(process+6) = segment_number; - + return process; } } @@ -5299,7 +6124,7 @@ void schedule_and_switch(){ print((int*) "empty---------"); println(); return; - } + } //else the processes have to be switched so that the next process from the ready queue is allowed to run else{ // 1. Saving the states of the running process in the ready queue @@ -5309,7 +6134,7 @@ void schedule_and_switch(){ running_process = (int*) *(node+1); // 3. Delete the first Process from ready queue because it is the running process - ready_queue = deleteFirstNodeFromList(ready_queue); + ready_queue = deleteFirstNodeFromList(ready_queue); } } @@ -5320,7 +6145,7 @@ void create_ready_queue(int n, int m){ int pid; int *new_reg; int segment_number; - + numb_of_instr = m; pid = 1; segment_number = 1; @@ -5337,7 +6162,6 @@ void create_ready_queue(int n, int m){ } void emulate(int argc, int *argv) { - print(selfieName); print((int*) ": this is selfie's mipster executing "); print(binaryName); @@ -5346,12 +6170,17 @@ void emulate(int argc, int *argv) { print((int*) "MB of memory"); println(); + interpret = 1; + copyBinaryToMemory(); + resetInterpreter(); - *(registers+REG_SP) = memorySize - 4; - *(registers+REG_GP) = binaryLength; - *(registers+REG_K1) = *(registers+REG_GP); + *(registers+REG_SP) = memorySize - 4; // initialize stack pointer + + *(registers+REG_GP) = binaryLength; // initialize global pointer + + *(registers+REG_K1) = *(registers+REG_GP); // initialize bump pointer up_copyArguments(argc, argv); @@ -5396,12 +6225,28 @@ int selfie(int argc, int* argv) { if (binaryLength > 0) emit(); - else { + else { print(selfieName); print((int*) ": nothing to emit to output file "); print(binaryName); println(); } + } else if (stringCompare((int*) *argv, (int*) "-s")) { + assemblyName = (int*) *(argv+1); + + argc = argc - 2; + argv = argv + 2; + + if (binaryLength > 0) { + initMemory(binaryLength); + + disassemble(argc, (int*) argv); + } else { + print(selfieName); + print((int*) ": nothing to disassemble to output file "); + print(assemblyName); + println(); + } } else if (stringCompare((int*) *argv, (int*) "-l")) { binaryName = (int*) *(argv+1); @@ -5410,7 +6255,7 @@ int selfie(int argc, int* argv) { load(); } else if (stringCompare((int*) *argv, (int*) "-m")) { - initMemory(atoi((int*) *(argv+1))); + initMemory(atoi((int*) *(argv+1)) * MEGABYTE); argc = argc - 1; argv = argv + 1; @@ -5418,12 +6263,11 @@ int selfie(int argc, int* argv) { // pass binaryName as first argument replacing size *argv = (int) binaryName; - if (binaryLength > 0){ - print((int*) "here"); - println(); - emulate(argc, (int*) argv); - } - else { + if (binaryLength > 0) { + debug = 0; + + emulate(argc, argv); + } else { print(selfieName); print((int*) ": nothing to emulate"); println(); @@ -5431,6 +6275,28 @@ int selfie(int argc, int* argv) { exit(-1); } + return 0; + } else if (stringCompare((int*) *argv, (int*) "-d")) { + initMemory(atoi((int*) *(argv+1)) * MEGABYTE); + + argc = argc - 1; + argv = argv + 1; + + // pass binaryName as first argument replacing size + *argv = (int) binaryName; + + if (binaryLength > 0) { + debug = 1; + + emulate(argc, argv); + } else { + print(selfieName); + print((int*) ": nothing to debug"); + println(); + + exit(-1); + } + return 0; } else if (stringCompare((int*) *argv, (int*) "-k")) { @@ -5456,16 +6322,17 @@ int selfie(int argc, int* argv) { } int main(int argc, int *argv) { + initLibrary(); initScanner(); initRegister(); initDecoder(); - + initInterpreter(); - ticks = 1000000; - number_of_processes = 5; + ticks = 10000000; + number_of_processes = 10; selfieName = (int*) *argv; @@ -5474,7 +6341,7 @@ int main(int argc, int *argv) { if (selfie(argc, (int*) argv) != 0) { print(selfieName); - print((int*) ": usage: selfie { -c source | -o binary | -l binary } [ -m size ... | -k size ... ] "); + print((int*) ": usage: selfie { -c source | -o binary | -s assembly | -l binary } [ -m size ... | -d size ... | -k size ... ] "); println(); } -} \ No newline at end of file +} From d3686deab892f2468c0d62de26f59d7361d5246e Mon Sep 17 00:00:00 2001 From: Johannes Vollmer Date: Fri, 27 Nov 2015 20:39:04 +0100 Subject: [PATCH 15/15] - added page table for assignment 5 --- selfie.c | 463 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 232 insertions(+), 231 deletions(-) diff --git a/selfie.c b/selfie.c index fbcb6a0..9dc6325 100755 --- a/selfie.c +++ b/selfie.c @@ -277,14 +277,12 @@ int* ready_queue; int* process_list; // number of instructions for one process in one run int numb_of_instr; -// Size of Segment -int segment_size; // Address of the actual running process int* running_process; // Address of the kernel process int* kernel_process; -// Segmentation Table -int* segmentation_table; +// Frame Table +int* frame_table; // Number of ticks each Process can run int ticks; // Number of Processes @@ -300,7 +298,13 @@ int* blocked_queue; // Global lock int* lock; // Debugging Variable for locking which indicates the next Process who needs the lock -int debug_locking = 1; +int debug_locking = 1; +// one page has 4 KB size +int PAGE_SIZE = 4096; +// one frame has 4 KB size +int FRAME_SIZE = 4096; +// Current frame number +int current_frame_number; int* prev_node; int* prev_process; @@ -308,15 +312,15 @@ int* next_node; int* next_process; void create_ready_queue(int n, int m); -int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number); -void create_segmentation_table(int segments); -int* initializeList(int *list); +int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo); +void create_frame_table(); +int* create_page_table(int* page_table); +int* initializeList(int *list); int* addToList(int *list, int data); void printListPID(int *list); void printListPC(int *list); -void printListSegment(int *list); int sizeOfList(int *list); -int getNodeFromList(int *list, int nthNode); +int getNodeFromList(int *list, int nthNode); int* deleteFirstNodeFromList(int *list); int* getNodeByIdFromProcessList(int id); void schedule_and_switch(); @@ -620,7 +624,7 @@ int OP_BNE = 5; int OP_ADDIU = 9; int OP_LW = 35; int OP_SW = 43; - + int *OPCODES; // array of strings representing MIPS opcodes int FCT_NOP = 0; @@ -796,17 +800,22 @@ int memorySize = 0; // size of memory in bytes int *memory = (int*) 0; // mipster memory +// Initializing the size of the virtual memory +int virtual_memory_size = 0; + // ------------------------- INITIALIZATION ------------------------ -void initMemory(int bytes) { - if (bytes < 0) - memorySize = 64 * MEGABYTE; - else if (bytes > 1024 * MEGABYTE) - memorySize = 1024 * MEGABYTE; - else - memorySize = bytes; +void initMemory(int megabytes) { + if (megabytes < 0) + megabytes = 64; + else if (megabytes > 1024) + megabytes = 1024; + // Initializing the physical memory + memorySize = megabytes * 1024 * 1024; memory = malloc(memorySize); + + virtual_memory_size = 4 * 1024 * 1024; } // ----------------------------------------------------------------- @@ -999,7 +1008,7 @@ int* storeCharacter(int *s, int i, int c) { a = i / 4; *(s + a) = (*(s + a) - leftShift(loadCharacter(s, i), (i % 4) * 8)) + leftShift(c, (i % 4) * 8); - + return s; } @@ -1024,7 +1033,7 @@ void stringReverse(int *s) { while (i < j) { tmp = loadCharacter(s, i); - + storeCharacter(s, i, loadCharacter(s, j)); storeCharacter(s, j, tmp); @@ -1070,7 +1079,7 @@ int atoi(int *s) { return -1; n = n * 10 + c; - + i = i + 1; c = loadCharacter(s, i); @@ -1203,7 +1212,7 @@ int* itoa(int n, int *s, int b, int a, int p) { i = i + 2; } } - + storeCharacter(s, i, 0); // null terminated string stringReverse(s); @@ -1267,7 +1276,7 @@ void printString(int *s) { putCharacter(CHAR_DOUBLEQUOTE); print(s); - + putCharacter(CHAR_DOUBLEQUOTE); } @@ -1307,7 +1316,7 @@ void syntaxErrorMessage(int *message) { printLineNumber((int*) "error"); print(message); - + println(); } @@ -1512,7 +1521,7 @@ int getSymbol() { storeCharacter(integer, i, character); i = i + 1; - + getCharacter(); } @@ -1577,7 +1586,7 @@ int getSymbol() { storeCharacter(string, i, character); i = i + 1; - + getCharacter(); } @@ -1687,7 +1696,7 @@ int getSymbol() { printLineNumber((int*) "error"); print((int*) "found unknown character "); printCharacter(character); - + println(); exit(-1); @@ -1739,7 +1748,7 @@ int* getSymbolTableEntry(int *string, int class, int *symbol_table) { if (stringCompare(string, getString(symbol_table))) if (class == getClass(symbol_table)) return symbol_table; - + // keep looking symbol_table = getNext(symbol_table); } @@ -2258,7 +2267,7 @@ int gr_call(int *procedure) { if (symbol == SYM_RPARENTHESIS) { getSymbol(); - + type = help_call_codegen(entry, procedure); } else { syntaxErrorSymbol(SYM_RPARENTHESIS); @@ -2400,9 +2409,9 @@ int gr_factor() { emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), constant); getSymbol(); - + type = INT_T; - + // string? } else if (symbol == SYM_STRING) { load_string(); @@ -2452,7 +2461,7 @@ int gr_term() { rtype = gr_factor(); // assert: allocatedTemporaries == n + 2 - + if (ltype != rtype) typeWarning(ltype, rtype); @@ -2498,7 +2507,7 @@ int gr_simpleExpression() { if (isINTMINConstant) { isINTMINConstant = 0; - + // avoids 0-INT_MIN overflow when bootstrapping // even though 0-INT_MIN == INT_MIN sign = 0; @@ -2636,7 +2645,7 @@ int gr_expression() { emitIFormat(OP_ADDIU, REG_ZR, currentTemporary(), 0); } } - + // assert: allocatedTemporaries == n + 1 return ltype; @@ -2817,7 +2826,7 @@ void gr_return(int returnType) { // save value of expression in return register emitRFormat(OP_SPECIAL, REG_ZR, currentTemporary(), REG_V0, FCT_ADDU); - + tfree(1); } @@ -2984,7 +2993,7 @@ int gr_type() { int type; type = INT_T; - + if (symbol == SYM_INT) { getSymbol(); @@ -3056,7 +3065,7 @@ void gr_initialization(int *name, int offset, int type) { if (isINTMINConstant) { isINTMINConstant = 0; - + // avoids 0-INT_MIN overflow when bootstrapping // even though 0-INT_MIN == INT_MIN sign = 0; @@ -3150,7 +3159,7 @@ void gr_procedure(int *procedure, int returnType) { // ( variable, variable ) { variable; variable; statement } } else if (symbol == SYM_LBRACE) { functionStart = binaryLength; - + getSymbol(); entry = getSymbolTableEntry(currentProcedureName, FUNCTION, global_symbol_table); @@ -3583,7 +3592,7 @@ void emitInstruction(int instruction) { exit(-1); } else { storeInstruction(binaryLength, instruction); - + binaryLength = binaryLength + 4; } } @@ -3696,7 +3705,7 @@ void emitGlobalsStrings() { void emit() { int fd; - + fd = open(binaryName, O_CREAT_WRONLY_TRUNC, S_IRUSR_IWUSR_IRGRP_IROTH); if (fd < 0) { @@ -3754,7 +3763,7 @@ void load() { if (numberOfReadBytes == 4) { codeLength = *io_buffer; - + // now read binary numberOfReadBytes = read(fd, binary, maxBinaryLength); @@ -4023,17 +4032,17 @@ void emitPutchar() { } void emitSchedYield() { - + // create Symbol Table Entroy for yield createSymbolTableEntry(GLOBAL_TABLE, (int*) "sched_yield", binaryLength, FUNCTION, INT_T, 0); - + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SCHED_YIELD); - emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } @@ -4051,17 +4060,17 @@ void syscall_sched_yield(){ } void emitSwitch() { - + // create Symbol Table Entry for swapoff createSymbolTableEntry(GLOBAL_TABLE, (int*) "switch", binaryLength, FUNCTION, INT_T, 0); - + emitIFormat(OP_ADDIU, REG_ZR, REG_A3, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A2, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A1, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_A0, 0); emitIFormat(OP_ADDIU, REG_ZR, REG_V0, SYSCALL_SWITCH); - emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); - emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); + emitRFormat(OP_SPECIAL, 0, 0, 0, FCT_SYSCALL); + emitRFormat(OP_SPECIAL, REG_RA, 0, 0, FCT_JR); } @@ -4072,11 +4081,11 @@ void syscall_switch() { prev_node = getNodeByIdFromProcessList(running_process_id); prev_process = (int*) (prev_node); - syscall_getpid(); + syscall_getpid(); next_node = getNodeByIdFromProcessList(running_process_id); next_process = (int*) (next_node); - + *(running_process + 1) = *(running_process + 1) + 1; running_process = next_process ; @@ -4109,11 +4118,11 @@ void syscall_switch() { next_node = getNodeByIdFromProcessList(0); next_process = (int*) (next_node); - running_process = next_process; + running_process = next_process; ready_queue = addToList(ready_queue, (int) prev_process); println(); - println(); + println(); println(); println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -4126,8 +4135,8 @@ void syscall_switch() { println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - - } + + } } @@ -4149,7 +4158,7 @@ void syscall_mlock() { *lock = *(running_process); println(); - println(); + println(); println(); println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -4195,9 +4204,9 @@ void syscall_munlock() { node = (int*) getNodeFromList(blocked_queue, new_size); process = (int*) *(node + 1); blocked_queue = deleteFirstNodeFromList(blocked_queue); - ready_queue = addToList(ready_queue,(int) process); + ready_queue = addToList(ready_queue,(int) process); i = i + 1; - } + } } void emitGetpid() { @@ -4243,17 +4252,17 @@ int* getNodeByIdFromProcessList(int id){ int* Buffer; i = 0; - + Buffer = (int*)malloc(4*10); - + while(i < all_processes) { node_i = (int*) getNodeFromList(process_list, i); - process_i = (int*) *(node_i + 1); - + process_i = (int*) *(node_i + 1); + j = (int) *(process_i); - + if(j == id){ - + return process_i; } i = i + 1; @@ -4267,7 +4276,7 @@ void create_process_List(int number){ int *process; int pid_process_list; int pid_ready_queue; - + pid_process_list = 0; pid_ready_queue = number_of_processes - 1; @@ -4281,15 +4290,15 @@ void create_process_List(int number){ else{ node = (int*) getNodeFromList(ready_queue, pid_ready_queue); process = (int*) *(node+1); - process_list = addToList(process_list, (int) process); + process_list = addToList(process_list, (int) process); pid_process_list = pid_process_list + 1; - pid_ready_queue = pid_ready_queue - 1; + pid_ready_queue = pid_ready_queue - 1; } } } // ------------------------ DATA STRUCTURE FOR THE LOCK ----------------------- -// Creating a the Lock with Process ID which holds the Lock +// Creating a the Lock with Process ID which holds the Lock // and a Pointer to the Blocked Queue void create_lock(){ @@ -4302,7 +4311,7 @@ void create_lock(){ // Sort the list with Bubble Sort int* sortListByPC(int *list) { - int size; + int size; int i; int *listNodeX; int *listNodeY; @@ -4311,8 +4320,8 @@ int* sortListByPC(int *list) { int *listProcessY; int listProcessPCX; int listProcessPCY; - int* Buffer; - + int* Buffer; + Buffer = (int*)malloc(4*10); size = sizeOfList(list); @@ -4334,14 +4343,14 @@ int* sortListByPC(int *list) { listProcessY = (int*) *(listNodeY + 1); listProcessPCX = *(listProcessX+1); listProcessPCY = *(listProcessY+1); - + println(); print(itoa(listProcessPCX, Buffer, 10, 0, 0)); println(); println(); print(itoa(listProcessPCY, Buffer, 10, 0, 0)); - println(); + println(); if(listProcessPCX < listProcessPCY) { print((int*) "change"); @@ -4371,18 +4380,15 @@ int* sortListByPC(int *list) { print((int*) "PCs"); println(); printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - printListSegment(ready_queue); return list; } void runOS(int argc, int* argv){ - - int* Buffer; + + int* Buffer; Buffer = (int*)malloc(4*10); - + while(1){ println(); @@ -4411,9 +4417,6 @@ void runOS(int argc, int* argv){ print((int*) "PCs"); println(); printListPC(process_list); - print((int*) "Segment Start"); - println(); - printListSegment(process_list); print((int*) "____________________________________________________"); println(); print((int*) "This is the Ready-Queue before running Kernel"); @@ -4426,9 +4429,6 @@ void runOS(int argc, int* argv){ print((int*) "PCs"); println(); printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - printListSegment(ready_queue); print((int*) "____________________________________________________"); println(); print((int*) "This is the Blocked-Queue before running Kernel"); @@ -4441,9 +4441,6 @@ void runOS(int argc, int* argv){ print((int*) "PCs"); println(); printListPC(blocked_queue); - print((int*) "Segment Start"); - println(); - printListSegment(blocked_queue); print((int*) "____________________________________________________"); println(); print((int*) "This is the Running Process before running Kernel"); @@ -4457,10 +4454,6 @@ void runOS(int argc, int* argv){ print((int*) "PC"); println(); print(itoa(*(running_process+1), Buffer, 10, 0, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0, 0)); println(); syscall_switch(); @@ -4487,9 +4480,6 @@ void runOS(int argc, int* argv){ print((int*) "PCs"); println(); printListPC(process_list); - print((int*) "Segment Start"); - println(); - printListSegment(process_list); print((int*) "____________________________________________________"); println(); println(); @@ -4504,9 +4494,6 @@ void runOS(int argc, int* argv){ print((int*) "PCs"); println(); printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - printListSegment(ready_queue); print((int*) "____________________________________________________"); println(); println(); @@ -4521,9 +4508,6 @@ void runOS(int argc, int* argv){ print((int*) "PCs"); println(); printListPC(blocked_queue); - print((int*) "Segment Start"); - println(); - printListSegment(blocked_queue); print((int*) "____________________________________________________"); println(); println(); @@ -4539,28 +4523,24 @@ void runOS(int argc, int* argv){ print((int*) "PC"); println(); print(itoa(*(running_process+1), Buffer, 10, 0, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0, 0)); println(); if(debug_locking == 1){ if(*lock == 0){ syscall_mlock(); debug_locking = 0; - run(argc, (int*) argv); + run(argc, (int*) argv); } else if(*lock == *running_process){ - - syscall_munlock(); + + syscall_munlock(); ready_queue = sortListByPC(ready_queue); - debug_locking = 0; + debug_locking = 0; println(); - println(); + println(); println(); println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -4575,14 +4555,14 @@ void runOS(int argc, int* argv){ println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - run(argc, (int*) argv); + run(argc, (int*) argv); } else{ blocked_queue = addToList(blocked_queue, (int) running_process); running_process = kernel_process; println(); - println(); + println(); println(); println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -4595,21 +4575,21 @@ void runOS(int argc, int* argv){ println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - debug_locking = 0; + debug_locking = 0; } } else{ if(*lock == *running_process){ - + syscall_munlock(); ready_queue = sortListByPC(ready_queue); - debug_locking = 0; + debug_locking = 0; println(); - println(); + println(); println(); println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -4624,11 +4604,11 @@ void runOS(int argc, int* argv){ println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); - run(argc, (int*) argv); + run(argc, (int*) argv); } else{ println(); - println(); + println(); println(); println(); print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -4642,9 +4622,9 @@ void runOS(int argc, int* argv){ print((int*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); println(); debug_locking = 1; - run(argc, (int*) argv); + run(argc, (int*) argv); } - } + } } } @@ -4652,25 +4632,36 @@ void runOS(int argc, int* argv){ void kOS(int argc, int* argv) { int *new_reg; int* Buffer; - + if(booting == 1){ booting = 0; new_reg = malloc(4*32); Buffer = (int*)malloc(4*10); - + all_processes = number_of_processes + 1; - kernel_process = create_process(0, new_reg, reg_hi, reg_lo, 0); + kernel_process = create_process(0, new_reg, reg_hi, reg_lo); running_process = kernel_process; - create_segmentation_table(all_processes); + current_frame_number = 0; + + create_frame_table(); + + println(); + print((int*) "Memory Size"); + println(); + + println(); + print(itoa(memorySize, Buffer, 10, 0, 0)); + println(); + create_ready_queue(all_processes, ticks); create_process_List(all_processes); blocked_queue = initializeList(blocked_queue); create_lock(); - + println(); println(); println(); @@ -4697,9 +4688,6 @@ void kOS(int argc, int* argv) { print((int*) "PCs"); println(); printListPC(process_list); - print((int*) "Segment Start"); - println(); - printListSegment(process_list); print((int*) "____________________________________________________"); println(); print((int*) "This is the Ready-Queue after Booting"); @@ -4712,9 +4700,6 @@ void kOS(int argc, int* argv) { print((int*) "PCs"); println(); printListPC(ready_queue); - print((int*) "Segment Start"); - println(); - printListSegment(ready_queue); print((int*) "____________________________________________________"); println(); @@ -4728,16 +4713,13 @@ void kOS(int argc, int* argv) { print((int*) "PCs"); println(); printListPC(blocked_queue); - print((int*) "Segment Start"); - println(); - printListSegment(blocked_queue); print((int*) "____________________________________________________"); println(); print((int*) "This is the Running-Process after Booting"); println(); print((int*) "____________________________________________________"); - println(); + println(); print((int*) "PID"); println(); print(itoa(*(running_process), Buffer, 10, 0, 0)); @@ -4745,15 +4727,11 @@ void kOS(int argc, int* argv) { print((int*) "PC"); println(); print(itoa(*(running_process+1), Buffer, 10, 0, 0)); - println(); - print((int*) "Segment Start"); - println(); - print(itoa(*(running_process+3), Buffer, 10, 0, 0)); println(); - + runOS(argc, (int*) argv); } - + else{ runOS(argc, (int*) argv); } @@ -5582,7 +5560,7 @@ void printListPC(int *list) { int counter; int number; - int *Buffer; + int *Buffer; int *node; int *process; @@ -5599,28 +5577,6 @@ void printListPC(int *list) { } } -// Print the value of the Segment Starts -void printListSegment(int *list) { - - int counter; - int number; - int *Buffer; - int *node; - int *process; - - counter = sizeOfList(list)-1; - - while(counter >= 0) { - node = (int*) getNodeFromList(list, counter); - process = (int*) *(node+1); - number = *(process+3); - Buffer = (int*)malloc(4*10); - print(itoa(number, Buffer, 10, 0, 0)); - putchar(CHAR_LF); - counter = counter - 1; - } -} - void run(int argc, int* argv) { int instr; @@ -5632,7 +5588,7 @@ void run(int argc, int* argv) { instr = instr + 1; *(running_process + 1) = *(running_process + 1) + 1; - + if(instr == numb_of_instr){ halt = 1; } @@ -5757,9 +5713,9 @@ int fixedPointRatio(int a, int b) { int r; // compute fixed point ratio r with 2 fractional digits - + r = 0; - + // multiply a/b with 100 but avoid overflow if (a <= INT_MAX / 100) { @@ -5788,11 +5744,11 @@ int printCounters(int total, int *counters, int max) { a = addressWithMaxCounter(counters, max); print(itoa(*(counters + a / 4), string_buffer, 10, 0, 0)); - + print((int*) "("); print(itoa(fixedPointRatio(total, *(counters + a / 4)), string_buffer, 10, 0, 2)); print((int*) "%)"); - + if (*(counters + a / 4) != 0) { print((int*) "@"); print(itoa(a, string_buffer, 16, 8, 0)); @@ -5847,7 +5803,7 @@ void disassemble(int argc, int* argv) { debug = 1; copyBinaryToMemory(); - + resetInterpreter(); run(argc, (int*) argv); @@ -5925,12 +5881,12 @@ int* deleteFirstNodeFromList(int *list) { *prev = 0; *next = 0; size = sizeOfList(list); - + if(size == 1){ list = initializeList(list); } else{ - + prev = (int*) getNodeFromList(list, size-2); next = (int*) getNodeFromList(list, size); *prev = (int) next; @@ -5942,7 +5898,7 @@ int* deleteFirstNodeFromList(int *list) { // Sort the list with Bubble Sort int* sortList(int *list) { - int size; + int size; int i; int *listitemX; int *listitemY; @@ -5982,9 +5938,9 @@ void printList(int *list) { int counter; int *nodeNumber; - int number; - int *Buffer; - + int number; + int *Buffer; + counter = sizeOfList(list)-1; while(counter >= 0) { @@ -6004,7 +5960,7 @@ int testList() { // Create new linked list (FIFO Linked List): // top -> [9,7,8,2,4,1,5,3] -> bottom print((int*) "Insert into list"); - println(); + println(); list = initializeList(list); list = addToList(list, 9); list = addToList(list, 7); @@ -6019,7 +5975,7 @@ int testList() { // Delete the first node (FIFO Linked List): // top -> [2,4,1,5,3] -> bottom print((int*) "Delete first Node"); - println(); + println(); list = deleteFirstNodeFromList(list); //9 list = deleteFirstNodeFromList(list); //7 list = deleteFirstNodeFromList(list); //8 @@ -6033,84 +5989,129 @@ int testList() { // Sorting the list // top -> [5,4,3,2,1] -> bottom print((int*) "Sorting the List"); - println(); + println(); list = sortList(list); printList(list); exit(0); } -// ------------------------ DATA STRUCTURE FOR A SEGMENT ----------------------- -// Creating a new Segment with Startaddress (start) and Size (size). -int* create_segment(int* start){ - //initialization of the process - int* segment; +// ------------------------ DATA STRUCTURE FOR A PAGE TABLE ENTRY ----------------------- +// Creating a new Page table entry with physical Address and virtual Address. +int* create_page_table_entry(int* physical_address, int* virtual_address){ + //initialization of the process + int* page_table_entry; //memory allocation - segment = malloc (2 * 4); - - //initalization of the argments of the process - *segment = (int) start; - *(segment+1) = segment_size; - - return segment; + page_table_entry = malloc (2 * 4); + + //initalization of the argments of the process + *page_table_entry = (int) physical_address; + *(page_table_entry+1) = (int) virtual_address; + + return page_table_entry; } -// ------------------------ Segment Table ---------------------------------------- -void create_segmentation_table(int segments){ - int *Buffer; - int memory_size; +// partition the emulated memory (like physical memory on a real machine) into 4KB +// frames +// ------------------------ Frame Table ---------------------------------------- +void create_frame_table(){ + + int i; + int* address; + int* Buffer; + int number_of_frames; + + i = 0; Buffer = (int*)malloc(4*10); - segment_size = 1024 * 1024 / 4; - memory_size = segments * segment_size; - segmentation_table = (int*)malloc(segments * 4); - memory = (int*)malloc(memory_size); + number_of_frames = memorySize / FRAME_SIZE; + + frame_table = initializeList(frame_table); + + while(i < number_of_frames){ + address = (int*) (i * FRAME_SIZE); + frame_table = addToList(frame_table, (int) address); + print((int*) "Frame number"); + println(); + print(itoa(i, Buffer, 10, 0, 0)); + println(); + print((int*) "Frame address"); + println(); + print(itoa((int)address, Buffer, 10, 0, 0)); + println(); + i = i + 1; + } +} + +// Virtual address space is organised in 4KB pages +// ------------------------ Page Table ---------------------------------------- +int* create_page_table(int* page_table){ + + int number_of_pages; + + number_of_pages = virtual_memory_size / PAGE_SIZE; + + page_table = initializeList(page_table); + + return page_table; } + // ------------------------ DATA STRUCTURE FOR A PROCESS ----------------------- -// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), +// Creating a new Process with Process ID (new_pid), Programm Counter (new_pc), // Address to the Register (new_reg), Address to the Memory (new_mem), // hi register for multiplication/division (new_reg_hi) and // lo register for multiplication/division (new_reg_lo) and -int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo, int segment_number){ - //initialization of the process +int* create_process(int new_pid, int* new_reg, int new_reg_hi, int new_reg_lo){ + //initialization of the process int* process; - int start_n_segment; - int* segment; int* start; - - //memory allocation - process = malloc (7 * 4); + int* page_table; + int* virtual_memory; + int* Buffer; + Buffer = (int*)malloc(4*10); if(new_pid == 0){ - //initalization of the argments of the process + process = malloc (6 * 4); + + //initalization of the arugments of the process *process = new_pid; *(process+1) = 0; *(process+2) = (int) new_reg; - *(process+3) = (int) memory; + *(process+3) = * memory; *(process+4) = new_reg_hi; *(process+5) = new_reg_lo; - *(process+6) = segment_number; - + return process; } else{ - start_n_segment = segment_number * segment_size; - start = (int*) (*(memory) + start_n_segment); - segment = (int*) create_segment(start); + process = malloc (7 * 4); + virtual_memory = malloc(virtual_memory_size); + + print((int*) "Virtual Memory"); + println(); + print(itoa((int)virtual_memory, Buffer, 10, 0, 0)); + println(); + print((int*) "Virtual Memory Size"); + println(); + print(itoa(virtual_memory_size, Buffer, 10, 0, 0)); + println(); + + page_table = create_page_table(page_table); - //initalization of the argments of the process + //initalization of the argments of the process *process = new_pid; *(process+1) = 0; *(process+2) = (int) new_reg; - *(process+3) = *segment; + //each process gets a 4MB virtual address space. + *(process+3) = * virtual_memory; *(process+4) = new_reg_hi; *(process+5) = new_reg_lo; - *(process+6) = segment_number; - + *(process+6) = (int) page_table; + return process; } } @@ -6124,7 +6125,7 @@ void schedule_and_switch(){ print((int*) "empty---------"); println(); return; - } + } //else the processes have to be switched so that the next process from the ready queue is allowed to run else{ // 1. Saving the states of the running process in the ready queue @@ -6134,7 +6135,7 @@ void schedule_and_switch(){ running_process = (int*) *(node+1); // 3. Delete the first Process from ready queue because it is the running process - ready_queue = deleteFirstNodeFromList(ready_queue); + ready_queue = deleteFirstNodeFromList(ready_queue); } } @@ -6144,20 +6145,17 @@ void create_ready_queue(int n, int m){ int *new_process; int pid; int *new_reg; - int segment_number; - + numb_of_instr = m; pid = 1; - segment_number = 1; ready_queue = initializeList(ready_queue); running_process_id = 0; while(pid < n){ new_reg = malloc(4*32); - new_process = create_process(pid, new_reg, reg_hi, reg_lo, segment_number); + new_process = create_process(pid, new_reg, reg_hi, reg_lo); ready_queue = addToList(ready_queue, (int) new_process); pid = pid + 1; - segment_number = segment_number + 1; } } @@ -6184,7 +6182,8 @@ void emulate(int argc, int *argv) { up_copyArguments(argc, argv); - run(argc, (int*) argv); + //run(argc, (int*) argv); + kOS(argc, (int*) argv); print(selfieName); print((int*) ": this is selfie's mipster terminating "); @@ -6225,7 +6224,7 @@ int selfie(int argc, int* argv) { if (binaryLength > 0) emit(); - else { + else { print(selfieName); print((int*) ": nothing to emit to output file "); print(binaryName); @@ -6265,6 +6264,7 @@ int selfie(int argc, int* argv) { if (binaryLength > 0) { debug = 0; + booting = 1; emulate(argc, argv); } else { @@ -6299,6 +6299,7 @@ int selfie(int argc, int* argv) { return 0; } else if (stringCompare((int*) *argv, (int*) "-k")) { + initMemory(atoi((int*) *(argv+1)) * MEGABYTE); argc = argc - 1; argv = argv + 1; @@ -6322,17 +6323,17 @@ int selfie(int argc, int* argv) { } int main(int argc, int *argv) { - + initLibrary(); initScanner(); initRegister(); initDecoder(); - + initInterpreter(); - ticks = 10000000; - number_of_processes = 10; + ticks = 1000000000; + number_of_processes = 16; selfieName = (int*) *argv;