diff --git a/Lab/Code/intercode.c b/Lab/Code/intercode.c index 2bce0ac..30d0d8d 100644 --- a/Lab/Code/intercode.c +++ b/Lab/Code/intercode.c @@ -10,8 +10,8 @@ int temp_var_id = 0; int label_id = 0; int var_id = 0; -InterCode* now = NULL; -InterCode* arg_list = NULL; +static InterCode* now = NULL; +InterCode* interhead = NULL; int isStruct[MAX_DEPTH]; int isFuncParam = FALSE; @@ -19,7 +19,7 @@ int isFuncParam = FALSE; Operand op_true = {.kind = OP_INT, .u.i = TRUE}; Operand op_false = {.kind = OP_INT, .u.i = FALSE}; -FILE* dest_stream = NULL; +static FILE* dest_stream = NULL; static void Program(Node* node); static void ExtDefList(Node* node); @@ -39,7 +39,7 @@ static void Def(Node* node); static void DecList(Type* type, Node* node); static void Dec(Type* type, Node* node); static Operand* Exp(Node* node); -static void Args(Node* node); +static void Args(Node* node, InterCode** arg_list); static void addCode(InterCode* code); static void printOp(Operand* op); @@ -61,10 +61,10 @@ static void copyArr(Operand* l, Operand* r); static void optimize(); -void printInterCode(FILE* stream) +void buildInterCode() { if (TRUE == DEBUG) printf("Start IR ...\n"); - InterCode* interhead = (InterCode*)malloc(sizeof(InterCode)); + interhead = (InterCode*)malloc(sizeof(InterCode)); memset(interhead, 0, sizeof(InterCode)); now = interhead; @@ -73,7 +73,10 @@ void printInterCode(FILE* stream) Program(root); optimize(); +} +void printInterCode(FILE* stream) +{ if (TRUE == DEBUG) printf("Start Print Code ...\n"); InterCode* prt = interhead; dest_stream = stream; @@ -580,11 +583,10 @@ Operand* Exp(Node* node) } else { HashNode* id = findSymbol(id_name); - arg_list = NULL; - Args(node->children[2]); + InterCode* arg_list = NULL; + Args(node->children[2], &arg_list); // 这里addCode是将所有参数都加进去了 addCode(arg_list); - arg_list = NULL; Operand* t = initTempVar(); Operand* func = initOPstr(OP_FUNCTION, id->name); @@ -687,21 +689,21 @@ Args : Exp "," Args Exp */ -void Args(Node* node) +void Args(Node* node, InterCode** arg_list) { if (TRUE == DEBUG) printf("Args\n"); Operand* op = Exp(node->children[0]); if (OP_TEMP_VAR == op->kind && (ARRAY == op->type->kind || STRUCTURE == op->type->kind)) op->isAddress = FALSE; InterCode* arg = initInterCode(FALSE, CODE_ARG, op); - if (NULL == arg_list) { - arg_list = arg; + if (NULL == (*arg_list)) { + *arg_list = arg; } else { - arg->next = arg_list; - arg_list->prev = arg; - arg_list = arg; + arg->next = *arg_list; + (*arg_list)->prev = arg; + *arg_list = arg; } if (0 == node->prod_id) { // Exp "," Args - Args(node->children[2]); + Args(node->children[2], arg_list); } } diff --git a/Lab/Code/intercode.h b/Lab/Code/intercode.h index 8adb85f..b593422 100644 --- a/Lab/Code/intercode.h +++ b/Lab/Code/intercode.h @@ -71,5 +71,6 @@ typedef struct InterCode_ { } InterCode; void printInterCode(FILE *stream); +void buildInterCode(); #endif \ No newline at end of file diff --git a/Lab/Code/main.c b/Lab/Code/main.c index d3db6aa..e0eaaf7 100755 --- a/Lab/Code/main.c +++ b/Lab/Code/main.c @@ -1,6 +1,7 @@ #include #include "intercode.h" +#include "mips.h" #include "semantic.h" #include "tree.h" @@ -35,7 +36,9 @@ int main(int argc, char** argv) // PrintTree(root, 0); // analyseSemantic(root); FILE* fout = fopen(argv[2], "w+"); - printInterCode(fout); + buildInterCode(); + // printInterCode(fout); + printMIPS(fout); fclose(fout); } fclose(fin); diff --git a/Lab/Code/mips.c b/Lab/Code/mips.c new file mode 100644 index 0000000..c94b96e --- /dev/null +++ b/Lab/Code/mips.c @@ -0,0 +1,443 @@ +#include "mips.h" + +#include + +#define DEBUG FALSE +// WHITE_SPACE +#define WS " " +#define MAX_LIST 1000 + +static FILE* dest_stream = NULL; +// 避免冲突还是用两个变量表示 +static int arg_num = 0; +static int param_num = 0; + +static Var var_list[MAX_LIST]; +static Var tem_list[MAX_LIST]; + +static Reg reg_list[32]; +static int lru[32]; + +static int sp_offset = 0; +static Log* log_head = NULL; + +static void initMIPS(); +static void initCode(); +static void translateCode(InterCode* code); +static int getReg(Operand* op); +static void spillReg(int reg_id); +static int findEmptyReg(); +static Var* findVar(Operand* op); +static void moveSP(int dis); +static void saveAllReg(); +static void loadAllReg(); +static void pushFP(); +static void popFP(); + +void printMIPS(FILE* stream) +{ + if (TRUE == DEBUG) printf("Printing MIPS ..."); + dest_stream = stream; + initCode(); + initMIPS(); + + InterCode* prt = interhead; + while (prt->next != NULL) { + prt = prt->next; + if (CODE_ARG == prt->kind) { + saveAllReg(); + InterCode* arg_end = prt; + while (CODE_ARG == prt->next->kind) prt = prt->next; + InterCode* arg_start = prt; + while (arg_start != arg_end) { + translateCode(arg_start); + arg_start = arg_start->prev; + } + translateCode(arg_end); + } else { + translateCode(prt); + } + } +} + +void initCode() +{ + fprintf(dest_stream, ".data\n"); + fprintf(dest_stream, "_prompt: .asciiz \"Enter an integer:\"\n"); + fprintf(dest_stream, "_ret: .asciiz \"\\n\"\n"); + fprintf(dest_stream, ".globl main\n"); + fprintf(dest_stream, ".text\n"); + // read + fprintf(dest_stream, "\nread:\n"); + fprintf(dest_stream, "%sli $v0, 4\n", WS); + fprintf(dest_stream, "%sla $a0, _prompt\n", WS); + fprintf(dest_stream, "%ssyscall\n", WS); + fprintf(dest_stream, "%sli $v0, 5\n", WS); + fprintf(dest_stream, "%ssyscall\n", WS); + fprintf(dest_stream, "%sjr $ra\n", WS); + // write + fprintf(dest_stream, "\nwrite:\n"); + fprintf(dest_stream, "%sli $v0, 1\n", WS); + fprintf(dest_stream, "%ssyscall\n", WS); + fprintf(dest_stream, "%sli $v0, 4\n", WS); + fprintf(dest_stream, "%sla $a0, _ret\n", WS); + fprintf(dest_stream, "%ssyscall\n", WS); + fprintf(dest_stream, "%smove $v0, $0\n", WS); + fprintf(dest_stream, "%sjr $ra\n", WS); +} + +void initMIPS() +{ + memset(var_list, 0, sizeof(var_list)); + memset(tem_list, 0, sizeof(tem_list)); + // for (int i = 0; i < MAX_LIST; i++) { + // tem_list[i].kind = TEMP; + // } + memset(reg_list, 0, sizeof(reg_list)); + memset(lru, 0, sizeof(lru)); +} + +/* +栈帧结构 +| saved regs | +|------------| +| params | +|------------| +| ra | +|------------| +| saved fp | +*/ + +void translateCode(InterCode* code) +{ + if (CODE_LABEL == code->kind) + fprintf(dest_stream, "L%d:\n", code->u.monop.op->u.i); + else if (CODE_GOTO == code->kind) + fprintf(dest_stream, "%sj L%d\n", WS, code->u.monop.op->u.i); + else if (CODE_FUNCTION == code->kind) { + fprintf(dest_stream, "\n%s:\n", code->u.monop.op->u.name); + if (log_head != NULL) { + Log* del = log_head; + sp_offset = log_head->offset; + log_head = log_head->next; + free(del); + } + pushFP(); + } else if (CODE_RETURN == code->kind) { + Operand* rt = code->u.monop.op; + int reg_rt = getReg(rt); + fprintf(dest_stream, "%smove $v0, $%d\n", WS, reg_rt); + popFP(); + fprintf(dest_stream, "%sjr $ra\n", WS); + param_num = 0; + } else if (CODE_ASSIGN == code->kind) { + Operand* l = code->u.assign.left; + Operand* r = code->u.assign.right; + int reg_l = getReg(l); + if (OP_FUNCTION == r->kind) { + moveSP(-4); + fprintf(dest_stream, "%ssw $ra, 0($sp)\n", WS); + + fprintf(dest_stream, "%sjal %s\n", WS, r->u.name); + + fprintf(dest_stream, "%slw $ra, 0($sp)\n", WS); + moveSP(4); + + moveSP(arg_num <= 4 ? 0 : 4 * (arg_num - 4)); + + loadAllReg(); + + fprintf(dest_stream, "%smove $%d, $v0\n", WS, reg_l); + arg_num = 0; + } else { + if (FALSE == l->isAddress && FALSE == r->isAddress) { + // 不考虑OP_FLOAT + if (OP_INT == r->kind) { + fprintf(dest_stream, "%sli $%d, %d\n", WS, reg_l, r->u.i); + } else { + int reg_r = getReg(r); + fprintf(dest_stream, "%smove $%d, $%d\n", WS, reg_l, reg_r); + } + } else { + int reg_r = getReg(r); + if (TRUE == l->isAddress && TRUE == r->isAddress) { + int reg_temp = findEmptyReg(); + fprintf(dest_stream, "%slw $%d, 0($%d)\n", WS, reg_temp, reg_r); + fprintf(dest_stream, "%ssw $%d, 0($%d)\n", WS, reg_r, reg_temp); + spillReg(reg_temp); + } else if (TRUE == l->isAddress) { + fprintf(dest_stream, "%ssw $%d, 0($%d)\n", WS, reg_r, reg_l); + } else if (TRUE == r->isAddress) { + fprintf(dest_stream, "%slw $%d, 0($%d)\n", WS, reg_l, reg_r); + } + } + } + } else if (CODE_ADD == code->kind || CODE_SUB == code->kind) { + Operand* op1 = code->u.binop.op1; + Operand* op2 = code->u.binop.op2; + Operand* result = code->u.binop.result; + int reg_op1 = getReg(op1); + int reg_result = getReg(result); + // 不考虑OP_FLOAT + if (FALSE == op1->isAddress && FALSE == op2->isAddress) { + if (OP_INT == op2->kind) { + int constant = code->kind == CODE_ADD ? op2->u.i : -op2->u.i; + fprintf(dest_stream, "%saddi $%d, $%d, %d\n", WS, reg_result, reg_op1, constant); + } else { + int reg_op2 = getReg(op2); + if (CODE_ADD == code->kind) { + fprintf(dest_stream, "%sadd $%d, $%d, $%d\n", WS, reg_result, reg_op1, reg_op2); + } else if (CODE_SUB == code->kind) { + fprintf(dest_stream, "%ssub $%d, $%d, $%d\n", WS, reg_result, reg_op1, reg_op2); + } + } + } else { + int reg_op2 = getReg(op2); + fprintf(dest_stream, "%ssub $%d, $%d, $%d\n", WS, reg_result, reg_op1, reg_op2); + } + } else if (CODE_MUL == code->kind || CODE_DIV == code->kind) { + Operand* op1 = code->u.binop.op1; + Operand* op2 = code->u.binop.op2; + Operand* result = code->u.binop.result; + int reg_op1 = getReg(op1); + int reg_op2 = getReg(op2); + int reg_result = getReg(result); + if (TRUE == op1->isAddress) fprintf(dest_stream, "%slw $%d, 0($%d)\n", WS, reg_op1, reg_op1); + if (TRUE == op2->isAddress) fprintf(dest_stream, "%slw $%d, 0($%d)\n", WS, reg_op2, reg_op2); + if (CODE_MUL == code->kind) { + fprintf(dest_stream, "%smul $%d, $%d, $%d\n", WS, reg_result, reg_op1, reg_op2); + } else if (CODE_DIV == code->kind) { + fprintf(dest_stream, "%sdiv $%d, $%d\n", WS, reg_op1, reg_op2); + fprintf(dest_stream, "%smflo $%d\n", WS, reg_result); + } + } else if (CODE_IFGOTO == code->kind) { + Operand* dest = code->u.ifgoto.dest; + Operand* op1 = code->u.ifgoto.op1; + Operand* op2 = code->u.ifgoto.op2; + Operand* relop = code->u.ifgoto.relop; + int reg_op1 = getReg(op1); + int reg_op2 = getReg(op2); + if (TRUE == op1->isAddress) fprintf(dest_stream, "%slw $%d, 0($%d)\n", WS, reg_op1, reg_op1); + if (TRUE == op2->isAddress) fprintf(dest_stream, "%slw $%d, 0($%d)\n", WS, reg_op2, reg_op2); + if (EQ == relop->u.i) { + fprintf(dest_stream, "%sbeq $%d, $%d, L%d\n", WS, reg_op1, reg_op2, dest->u.i); + } else if (LT == relop->u.i) { + fprintf(dest_stream, "%sblt $%d, $%d, L%d\n", WS, reg_op1, reg_op2, dest->u.i); + } else if (GT == relop->u.i) { + fprintf(dest_stream, "%sbgt $%d, $%d, L%d\n", WS, reg_op1, reg_op2, dest->u.i); + } else if (NE == relop->u.i) { + fprintf(dest_stream, "%sbne $%d, $%d, L%d\n", WS, reg_op1, reg_op2, dest->u.i); + } else if (GE == relop->u.i) { + fprintf(dest_stream, "%sbge $%d, $%d, L%d\n", WS, reg_op1, reg_op2, dest->u.i); + } else if (LE == relop->u.i) { + fprintf(dest_stream, "%sble $%d, $%d, L%d\n", WS, reg_op1, reg_op2, dest->u.i); + } + } else if (CODE_READ == code->kind) { + Operand* rd = code->u.monop.op; + int reg_rd = getReg(rd); + moveSP(-4); + fprintf(dest_stream, "%ssw $ra, 0($sp)\n", WS); + + fprintf(dest_stream, "%sjal read\n", WS); + + fprintf(dest_stream, "%slw $ra, 0($sp)\n", WS); + moveSP(4); + + fprintf(dest_stream, "%smove $%d, $v0\n", WS, reg_rd); + arg_num = 0; + } else if (CODE_WRITE == code->kind) { + Operand* wt = code->u.monop.op; + int reg_wt = getReg(wt); + fprintf(dest_stream, "%smove $a0, $%d\n", WS, reg_wt); + + moveSP(-4); + fprintf(dest_stream, "%ssw $ra, 0($sp)\n", WS); + + fprintf(dest_stream, "%sjal write\n", WS); + + fprintf(dest_stream, "%slw $ra, 0($sp)\n", WS); + moveSP(4); + + arg_num = 0; + } else if (CODE_ARG == code->kind) { + Operand* arg = code->u.monop.op; + int reg_arg = getReg(arg); + if (arg_num < 4) { + fprintf(dest_stream, "%smove $a%d, $%d\n", WS, arg_num, reg_arg); + } else { + moveSP(-4); + fprintf(dest_stream, "%ssw $%d, 0($sp)\n", WS, reg_arg); + } + arg_num++; + } else if (CODE_DEC == code->kind) { + Operand* op = code->u.decop.op; + Operand* size = code->u.decop.size; + Var* var = findVar(op); + var->mem = sp_offset - 4; + moveSP(-size->u.i); + } else if (CODE_PARAM == code->kind) { + Operand* param = code->u.monop.op; + Var* var = findVar(param); + if (param_num < 4) { + var->reg = 4 + param_num; + } else { + var->mem = log_head->offset + 8 + 4 * (param_num - 4); + } + param_num++; + } +} + +/* +0 : zero, 常数0 +1 : at, 汇编器保留 +2-3 : v0-v1, 表达式求值或函数结果 +4-7 : a0-a3, 函数的首四个参数 +8-15 : t0-t7, 调用者保存寄存器 +16-23 : s0-s7, 被调用者保存寄存器 +24-25 : t8-t9, 调用者保存寄存器 +26-27 : k0-k1, 中断处理保留 +28 : gp, 指向静态数据段64K内存空间的中部 +29 : sp, 栈顶指针 +30 : s8/fp, 普通的s8或者帧指针 +31 : ra, 返回地址 +*/ +// 对8-25随便用 +int getReg(Operand* op) +{ + if (TRUE == op->isAddress && OP_VARIABLE == op->kind) { + Var* var = findVar(op); + int reg_addr = findEmptyReg(); + reg_list[reg_addr].var = var; + fprintf(dest_stream, "%saddi $%d, $fp, %d\n", WS, reg_addr, var->mem - log_head->offset); + return reg_addr; + } else { + if (OP_INT == op->kind) { + int reg_int = findEmptyReg(); + reg_list[reg_int].var = NULL; + fprintf(dest_stream, "%sli $%d, %d\n", WS, reg_int, op->u.i); + return reg_int; + } else if (OP_TEMP_VAR == op->kind || OP_VARIABLE == op->kind) { + Var* var = findVar(op); + if (var->reg != 0) { + lru[var->reg] = 0; + return var->reg; + } else if (var->mem != 0) { + int reg_var = findEmptyReg(); + fprintf(dest_stream, "%slw $%d, %d($fp)\n", WS, reg_var, (var->mem - log_head->offset)); + var->reg = reg_var; + reg_list[reg_var].var = var; + return var->reg; + } else { + var->reg = findEmptyReg(); + reg_list[var->reg].var = var; + return var->reg; + } + } + } +} + +void spillReg(int reg_id) +{ + Var* var = reg_list[reg_id].var; + // TODO 如果不保存临时变量,将可能无法将函数直接写在参数调用的参数中 + if (NULL == var) { // 寄存器中存的是立即数 + } else if (TEMP == var->kind) { // 寄存器中存的是临时变量 + var->reg = 0; + } else if (VAR == var->kind) { + if (0 == var->mem) { + moveSP(-4); + fprintf(dest_stream, "%ssw $%d, 0($sp)\n", WS, reg_id); + var->mem = sp_offset; + } else { + fprintf(dest_stream, "%ssw $%d, %d($fp)\n", WS, var->reg, (var->mem - log_head->offset)); + } + var->reg = 0; + } + reg_list[reg_id].used = FALSE; + reg_list[reg_id].var = NULL; + return; +} + +static int reg_num = 22; + +void saveAllReg() +{ + moveSP(-88); + for (int i = 4; i <= 25; i++) { + fprintf(dest_stream, "%ssw $%d, %d($sp)\n", WS, i, 88 - 4 * (i - 3)); + reg_list[i].used = FALSE; + reg_list[i].var = NULL; + } + memset(lru, 0, sizeof(lru)); +} + +void loadAllReg() +{ + for (int i = 25; i >= 4; i--) { + fprintf(dest_stream, "%slw $%d, %d($sp)\n", WS, i, 88 - 4 * (i - 3)); + } + moveSP(88); + memset(lru, 0, sizeof(lru)); +} + +int findEmptyReg() +{ + for (int id = 8; id <= 25; id++) { + if (FALSE == reg_list[id].used) { + reg_list[id].used = TRUE; + lru[id] = 0; + return id; + } else { + lru[id] += 1; + } + } + int max_lru = 8; + for (int id = 8; id <= 25; id++) { + if (lru[max_lru] < lru[id]) max_lru = id; + } + spillReg(max_lru); + reg_list[max_lru].used = TRUE; + lru[max_lru] = 0; + return max_lru; +} + +Var* findVar(Operand* op) +{ + if (OP_VARIABLE == op->kind) { + return &var_list[op->u.i % MAX_LIST]; + } else if (OP_TEMP_VAR == op->kind) { + return &tem_list[op->u.i % MAX_LIST]; + } else { + if (TRUE == DEBUG) printf("Not a Variable!!\n"); + return NULL; + } +} + +void moveSP(int dis) +{ + sp_offset += dis; + fprintf(dest_stream, "%saddi $sp, $sp, %d\n", WS, dis); +} + +void pushFP() +{ + moveSP(-4); + fprintf(dest_stream, "%ssw $fp, 0($sp)\n", WS); + fprintf(dest_stream, "%smove $fp, $sp\n", WS); + Log* log = (Log*)malloc(sizeof(Log)); + log->next = log_head; + log->offset = sp_offset; + log_head = log; +} + +// 因为一个函数可能有多个return,所以在return处pop不能改现有程序的东西 +void popFP() +{ + fprintf(dest_stream, "%smove $sp, $fp\n", WS); + fprintf(dest_stream, "%slw $fp, 0($sp)\n", WS); + moveSP(4); + // Log* del = log_head; + // sp_offset = log_head->offset; + // log_head = log_head->next; + // free(del); +} \ No newline at end of file diff --git a/Lab/Code/mips.h b/Lab/Code/mips.h new file mode 100644 index 0000000..b09e3e8 --- /dev/null +++ b/Lab/Code/mips.h @@ -0,0 +1,30 @@ +#ifndef MIPS_H +#define MIPS_H + +#include +#include +#include + +#include "intercode.h" + +extern InterCode* interhead; + +typedef struct Var_ { + int mem; + int reg; + enum { VAR, TEMP } kind; +} Var; + +typedef struct Reg_ { + int used; + struct Var_* var; +} Reg; + +typedef struct Log_ { + int offset; + struct Log_* next; +} Log; + +void printMIPS(FILE* stream); + +#endif \ No newline at end of file diff --git a/Lab/Test/test1.cmm b/Lab/Test/test1.cmm index e3c3a48..3dccf18 100644 --- a/Lab/Test/test1.cmm +++ b/Lab/Test/test1.cmm @@ -1,9 +1,14 @@ int main() { - int n; + int a = 0, b = 1, i = 0, n; n = read(); - if (n > 0) write(1); - else if (n < 0) write (-1); - else write(0); + while(i < n) + { + int c = a + b; + write(b); + a = b; + b = c; + i = i + 1; + } return 0; } \ No newline at end of file diff --git a/Lab/report.docx b/Lab/report.docx index 18af555..66daaec 100644 Binary files a/Lab/report.docx and b/Lab/report.docx differ diff --git a/Lab/report.pdf b/Lab/report.pdf new file mode 100644 index 0000000..cf216b2 Binary files /dev/null and b/Lab/report.pdf differ diff --git a/MIPS32_and_SPIM.pdf b/MIPS32_and_SPIM.pdf new file mode 100755 index 0000000..4a3073d Binary files /dev/null and b/MIPS32_and_SPIM.pdf differ diff --git a/Project_4.pdf b/Project_4.pdf new file mode 100644 index 0000000..449659e Binary files /dev/null and b/Project_4.pdf differ diff --git a/Test3/Test/test1.cmm b/Test3/Test/test1.cmm new file mode 100644 index 0000000..e3c3a48 --- /dev/null +++ b/Test3/Test/test1.cmm @@ -0,0 +1,9 @@ +int main() +{ + int n; + n = read(); + if (n > 0) write(1); + else if (n < 0) write (-1); + else write(0); + return 0; +} \ No newline at end of file diff --git a/Test3/Test/test2.cmm b/Test3/Test/test2.cmm new file mode 100644 index 0000000..7b9f87f --- /dev/null +++ b/Test3/Test/test2.cmm @@ -0,0 +1,18 @@ +int fact(int n) +{ + if (n == 1) + return n; + else + return (n * fact(n - 1)); +} +int main() +{ + int m, result; + m = read(); + if (m > 1) + result = fact(m); + else + result = 1; + write(result); + return 0; +} \ No newline at end of file diff --git a/Lab/Test/testc1.cmm b/Test3/Test/testc1.cmm similarity index 100% rename from Lab/Test/testc1.cmm rename to Test3/Test/testc1.cmm diff --git a/Lab/Test/testc2.cmm b/Test3/Test/testc2.cmm similarity index 100% rename from Lab/Test/testc2.cmm rename to Test3/Test/testc2.cmm diff --git a/Test3/Tests (normal)/Tests.pdf b/Test3/Tests (normal)/Tests.pdf new file mode 100755 index 0000000..fb1310b Binary files /dev/null and b/Test3/Tests (normal)/Tests.pdf differ diff --git a/Test3/Tests (normal)/tests/A-1.cmm b/Test3/Tests (normal)/tests/A-1.cmm new file mode 100755 index 0000000..91c41e7 --- /dev/null +++ b/Test3/Tests (normal)/tests/A-1.cmm @@ -0,0 +1,13 @@ +int main() { + int i = 1, j = 11, k = 39; + int result = 0; + i = (-i) + k + (-(17 * i)); + write(i); + j = 11 * j - (k + i * i) * i; + write(j); + k = i * (i / j) + k; + write(k); + result = 4 * i + j / 17 + i * k; + write(result); + return 0; +} diff --git a/Test3/Tests (normal)/tests/A-2.cmm b/Test3/Tests (normal)/tests/A-2.cmm new file mode 100755 index 0000000..adedbd8 --- /dev/null +++ b/Test3/Tests (normal)/tests/A-2.cmm @@ -0,0 +1,53 @@ +int main() { + int x1, y1, x2, y2; + int u1, v1, u2, v2; + int l1, r1, t1, b1; + int l2, r2, t2, b2; + x1 = read(); + y1 = read(); + x2 = read(); + y2 = read(); + u1 = read(); + v1 = read(); + u2 = read(); + v2 = read(); + if (x1 == x2 || y1 == y2 || u1 == u2 || v1 == v2) { + write(-1); + } else { + if (x1 < x2) { + l1 = x1; + r1 = x2; + } else { + l1 = x2; + r1 = x1; + } + if (y1 < y2) { + t1 = y2; + b1 = y1; + } else { + t1 = y1; + b1 = y2; + } + if (u1 < u2) { + l2 = u1; + r2 = u2; + } else { + l2 = u2; + r2 = u1; + } + if (v1 < v2) { + t2 = v2; + b2 = v1; + } else { + t2 = v1; + b2 = v2; + } + + if (l2 >= r1 || r2 <= l1 || b2 >= t1 || t2 <= b1) { + write(0); + } else { + write(1); + } + } + return 0; +} diff --git a/Test3/Tests (normal)/tests/A-3.cmm b/Test3/Tests (normal)/tests/A-3.cmm new file mode 100755 index 0000000..92bdd04 --- /dev/null +++ b/Test3/Tests (normal)/tests/A-3.cmm @@ -0,0 +1,34 @@ +int main() { + int k; + int line = 0, cnt = 0; + int m = 0, n = 0; + int numtor = 1, denomtor = 1; + k = read(); + + if (k <= 0) { + write(-1); + return 0; + } + + while (cnt < k) { + line = line + 1; + cnt = cnt + line; + } + m = k - (cnt - line); + n = line; + write(n); + write(m); + + cnt = 0; + while (cnt < m) { + numtor = numtor * n; + n = n - 1; + cnt = cnt + 1; + } + while(m > 0) { + denomtor = denomtor * m; + m = m - 1; + } + write(numtor / denomtor); + return 0; +} diff --git a/Test3/Tests (normal)/tests/A-4.cmm b/Test3/Tests (normal)/tests/A-4.cmm new file mode 100755 index 0000000..d1f16c9 --- /dev/null +++ b/Test3/Tests (normal)/tests/A-4.cmm @@ -0,0 +1,22 @@ +int main() { + int catalan[11], n = 11; + int i, j; + catalan[0] = 1; + catalan[1] = 1; + i = 2; + while(i < n) { + catalan[i] = 0; + i = i + 1; + } + i = 2; + while (i < n) { + j = 0; + while (j < i) { + catalan[i] = catalan[i] + catalan[j] * catalan[i - j - 1]; + j = j + 1; + } + i = i + 1; + } + write(catalan[n - 1]); + return 0; +} diff --git a/Test3/Tests (normal)/tests/A-5.cmm b/Test3/Tests (normal)/tests/A-5.cmm new file mode 100755 index 0000000..5320c85 --- /dev/null +++ b/Test3/Tests (normal)/tests/A-5.cmm @@ -0,0 +1,22 @@ +int add(int ai, int aj) { + return ai + aj; +} + +int sub(int si, int sj) { + return si - sj; +} + +int mul(int mi, int mj) { + return mi * mj; +} + +int main() { + int i, j, k, l, res; + i = read(); + j = read(); + k = read(); + l = read(); + res = add(mul(sub(i, j), sub(i, j)), add(k, l)); + write(res); + return 0; +} diff --git a/Test3/Tests (normal)/tests/B-1.cmm b/Test3/Tests (normal)/tests/B-1.cmm new file mode 100755 index 0000000..8d92455 --- /dev/null +++ b/Test3/Tests (normal)/tests/B-1.cmm @@ -0,0 +1,30 @@ +int mod(int i, int j) { + return i - i / j * j; +} + +int quick_power_mod(int x, int y, int k) { + int res = 1; + if (x <= 0 || y <= 0 || k <= 0) { + return -1; + } else { + x = mod(x, k); + while (y != 0) { + if (mod(y, 2) == 1) { + res = mod(res * x, k); + } + y = y / 2; + x = mod(x * x, k); + } + return res; + } +} + +int main() { + int input[3], cnt = 0; + while (cnt < 3) { + input[cnt] = read(); + cnt = cnt + 1; + } + write(quick_power_mod(input[0], input[1], input[2])); + return 0; +} diff --git a/Test3/Tests (normal)/tests/B-2.cmm b/Test3/Tests (normal)/tests/B-2.cmm new file mode 100755 index 0000000..dffd0c9 --- /dev/null +++ b/Test3/Tests (normal)/tests/B-2.cmm @@ -0,0 +1,44 @@ +int main() { + int cnum = 3, charges[3]; + int amount = 100, dp[101]; + int valid = 1; + int i = 0, j = 0; + while (i < cnum) { + charges[i] = read(); + if (charges[i] <= 0) { + valid = 0; + } + i = i + 1; + } + if (valid == 0) { + write(-1); + return 0; + } + + dp[0] = 0; + i = 1; + while (i < amount + 1) { + dp[i] = amount + 1; + i = i + 1; + } + + i = 0; + while (i < cnum) { + int chg = charges[i]; + j = chg; + while (j < amount + 1) { + if (dp[j - chg] + 1 < dp[j]) { + dp[j] = dp[j - chg] + 1; + } + j = j + 1; + } + i = i + 1; + } + + if (dp[amount] > amount) { + write(-1); + } else { + write(dp[amount]); + } + return 0; +} diff --git a/Test3/Tests (normal)/tests/B-3.cmm b/Test3/Tests (normal)/tests/B-3.cmm new file mode 100755 index 0000000..ccba82f --- /dev/null +++ b/Test3/Tests (normal)/tests/B-3.cmm @@ -0,0 +1,92 @@ +int main() { + int n = 5, arr[5], tmp[5]; + int i, intv; + int s1, e1, cur1, s2, e2, cur2; + i = 0; + while (i < n) { + arr[i] = read(); + i = i + 1; + } + + intv = 1; + while (intv < n) { + i = 0; + while (i <= n - 2 * intv) { + s1 = i; + e1 = s1 + intv; + cur1 = s1; + s2 = e1; + e2 = s2 + intv; + cur2 = s2; + while (cur1 < e1 && cur2 < e2) { + if (arr[cur1] < arr[cur2]) { + tmp[i] = arr[cur1]; + cur1 = cur1 + 1; + } else { + tmp[i] = arr[cur2]; + cur2 = cur2 + 1; + } + i = i + 1; + } + while (cur1 < e1) { + tmp[i] = arr[cur1]; + cur1 = cur1 + 1; + i = i + 1; + } + while (cur2 < e2) { + tmp[i] = arr[cur2]; + cur2 = cur2 + 1; + i = i + 1; + } + } + + if (i + intv < n) { + s1 = i; + e1 = s1 + intv; + cur1 = s1; + s2 = e1; + e2 = n; + cur2 = s2; + while (cur1 < e1 && cur2 < e2) { + if (arr[cur1] < arr[cur2]) { + tmp[i] = arr[cur1]; + cur1 = cur1 + 1; + i = i + 1; + } else { + tmp[i] = arr[cur2]; + cur2 = cur2 + 1; + i = i + 1; + } + } + while (cur1 < e1) { + tmp[i] = arr[cur1]; + cur1 = cur1 + 1; + i = i + 1; + } + while (cur2 < e2) { + tmp[i] = arr[cur2]; + cur2 = cur2 + 1; + i = i + 1; + } + } else { + while (i < n) { + tmp[i] = arr[i]; + i = i + 1; + } + } + + i = 0; + while (i < n) { + arr[i] = tmp[i]; + i = i + 1; + } + intv = intv * 2; + } + + i = 0; + while (i < n) { + write(arr[i]); + i = i + 1; + } + return 0; +} diff --git a/Test3/Tests (normal)/tests/C-1.cmm b/Test3/Tests (normal)/tests/C-1.cmm new file mode 100755 index 0000000..8f2ddf1 --- /dev/null +++ b/Test3/Tests (normal)/tests/C-1.cmm @@ -0,0 +1,50 @@ +int fact(int m) { + if (m <= 0) { + return 1; + } else { + return fact(m - 1) * m; + } +} + +int isqrt(int n) { + int i = 0; + while (i < n) { + if (i * i <= n && (i + 1) * (i + 1) > n) { + return i; + } + i = i + 1; + } + return -1; +} + +int mod(int k1, int k2) { + if (k1 < 0 || k2 <= 0) { + return -1; + } else { + return k1 - k1 / k2 * k2; + } +} + +int is_prime(int l) { + int j = 2; + int end = isqrt(l); + while (j <= end) { + if (mod(l, j) == 0) { + return 0; + } + j = j + 1; + } + return 1; +} + +int main() { + int c = 2; + int d = read(); + while (c < fact(d)) { + if (is_prime(c)) { + write(c); + } + c = c + 1; + } + return 0; +} diff --git a/Test3/Tests (normal)/tests/C-2.cmm b/Test3/Tests (normal)/tests/C-2.cmm new file mode 100755 index 0000000..90fd169 --- /dev/null +++ b/Test3/Tests (normal)/tests/C-2.cmm @@ -0,0 +1,75 @@ +int bit_and(int aop1, int aop2) { + if (aop1 == 0) { + return 0; + } else { + return aop2; + } +} + +int bit_or(int oop1, int oop2) { + if (oop1 == 0) { + return oop2; + } else { + return 1; + } +} + +int bit_not(int nop) { + if (nop == 0) { + return 1; + } else { + return 0; + } +} + +int mod(int mop1, int mop2) { + return mop1 - mop1 / mop2 * mop2; +} + +int and(int m, int n) { + int isize = 32; + int am[32]; + int an[32]; + int res[32]; + int i = 0; + int mn = 0; + if (m <= 0 || n <= 0) { + return 0; + } + + while (i < isize) { + am[i] = 0; + an[i] = 0; + res[i] = 0; + i = i + 1; + } + + i = 0; + while (i < isize) { + am[i] = mod(m, 2); + an[i] = mod(n, 2); + m = m / 2; + n = n / 2; + i = i + 1; + } + + i = 0; + while (i < isize) { + res[i] = bit_and(am[i], an[i]); + i = i + 1; + } + + i = isize - 1; + while (i >= 0) { + mn = mn * 2 + res[i]; + i = i - 1; + } + return mn; +} + +int main() { + int x = read(); + int y = read(); + write(and(x, y)); + return 0; +} diff --git a/Test3/Tests (normal)/tests/D-1.cmm b/Test3/Tests (normal)/tests/D-1.cmm new file mode 100755 index 0000000..602b5ee --- /dev/null +++ b/Test3/Tests (normal)/tests/D-1.cmm @@ -0,0 +1,68 @@ +int fact(int i1) { + if (i1 <= 0) { + return 1; + } else { + return i1 * fact(i1 - 1); + } +} + +int isqrt(int i2) { + int c1 = 0; + while (c1 < i2) { + if (c1 * c1 <= i2 && (c1 + 1) * (c1 + 1) > i2) { + return c1; + } + c1 = c1 + 1; + } + return -1; +} + +int mod(int i3, int i4) { + return i3 - i3 / i4 * i4; +} + +int main() { + int a = 1331; + int b = 1217; + int c = -22121; + int d = 5; + int i = b * 7 / a + (1990 + 9 * 10) / (b + 23); + int j = (2000 - 1) * 10 / (b + 2 * 10 + 3); + int k = 0; + int l = 0; + int m = 0; + int arr[1000]; + while (k < fact(isqrt(isqrt(b)))) { + arr[k] = fact(mod(k, 4)); + a = k + k / 4 * 4; + a = a + k / 4 * 4; + a = a + k / 4 * 4; + a = a + k / 4 * 4; + while (c < d * d * d) { + c = mod(a, 10) + 10 + c + 1 + i - j; + } + c = c + fact(mod(isqrt(c), 10)); + k = k + 1; + } + + k = 0; + while(k < 10) { + l = 0; + while (l < 10) { + if (k == 0 && l == 0) { + m = 1; + } else { + m = 0; + } + while (m < 10) { + d = d + arr[k * 10 * 10 + l * 10 + m] - arr[k * 10 * 10 + l * 10 + m - 1]; + m = m + 1; + } + l = l + 1; + } + k = k + 1; + } + k = d + c; + write(k); + return 0; +} diff --git a/Test3/Tests (normal)/tests/E1-1.cmm b/Test3/Tests (normal)/tests/E1-1.cmm new file mode 100755 index 0000000..ec2b5f9 --- /dev/null +++ b/Test3/Tests (normal)/tests/E1-1.cmm @@ -0,0 +1,18 @@ +struct Giant { + int id; + int age; + int height; + int weight; +}; + +int main() { + struct Giant g; + int bmi = 0; + g.id = 0; + g.age = 20; + g.height = 2; + g.weight = 90; + bmi = g.weight / (g.height * g.height); + write(bmi); + return 0; +} diff --git a/Test3/Tests (normal)/tests/E1-2.cmm b/Test3/Tests (normal)/tests/E1-2.cmm new file mode 100755 index 0000000..c0ba886 --- /dev/null +++ b/Test3/Tests (normal)/tests/E1-2.cmm @@ -0,0 +1,38 @@ +struct Giant { + int id; + int age; + int height; + int weight; + int bmi; +}; + +int cal_bmi(struct Giant g) { + g.bmi = g.weight / (g.height * g.height); + return 0; +} + +int main() { + int i = 0; + int n = 10; + struct Giant giants[10]; + while (i < n) { + giants[i].id = i; + giants[i].age = 20 + i; + giants[i].height = 2 + i; + giants[i].weight = 90 + i * i * i * i; + i = i + 1; + } + + i = 0; + while (i < n) { + cal_bmi(giants[i]); + i = i + 1; + } + + i = 0; + while (i < n) { + write(giants[i].bmi); + i = i + 1; + } + return 0; +} diff --git a/Test3/Tests (normal)/tests/E1-3.cmm b/Test3/Tests (normal)/tests/E1-3.cmm new file mode 100755 index 0000000..604882c --- /dev/null +++ b/Test3/Tests (normal)/tests/E1-3.cmm @@ -0,0 +1,54 @@ +struct Giant { + int id; + int age; + int height; + int weight; + int bmi; +}; + +struct Family { + struct Giant giants[5]; + int avg_bmi; +}; + +int cal_bmi(struct Giant g) { + g.bmi = g.weight / (g.height * g.height); + return 0; +} + +int cal_avg_bmi(struct Family f) { + int c = 0; + int sum = 0; + while (c < 5) { + cal_bmi(f.giants[c]); + sum = sum + f.giants[c].bmi; + c = c + 1; + } + f.avg_bmi = sum / 5; + return 0; +} + +int main() { + int i, j; + struct Family gf[10]; + i = 0; + while (i < 10) { + j = 0; + while (j < 5) { + gf[i].giants[j].id = i / 2 + j; + gf[i].giants[j].age = i / 2 + 20 + j; + gf[i].giants[j].height = i / 2 + 2 + j; + gf[i].giants[j].weight = i / 2 + 90 + j * j * j * j; + j = j + 1; + } + cal_avg_bmi(gf[i]); + i = i + 1; + } + + i = 0; + while (i < 10) { + write(gf[i].avg_bmi); + i = i + 1; + } + return 0; +} diff --git a/Test3/Tests (normal)/tests/E2-1.cmm b/Test3/Tests (normal)/tests/E2-1.cmm new file mode 100755 index 0000000..4c23cbd --- /dev/null +++ b/Test3/Tests (normal)/tests/E2-1.cmm @@ -0,0 +1,37 @@ +int main() { + int i; + int j; + int n = 5; + int m[5][5]; + int rs[5][5]; + int sum; + + i = 0; + while (i < n) { + j = 0; + while (j < n) { + m[i][j] = i * i + j; + j = j + 1; + } + i = i + 1; + } + + i = 0; + while (i < n) { + j = 0; + while (j < n) { + m[j][i] = m[i][j]; + j = j + 1; + } + i = i + 1; + } + + sum = 0; + i = 0; + while (i < n) { + sum = sum + m[0][i]; + i = i + 1; + } + write(sum); + return 0; +} diff --git a/Test3/Tests (normal)/tests/E2-2.cmm b/Test3/Tests (normal)/tests/E2-2.cmm new file mode 100755 index 0000000..7e6590f --- /dev/null +++ b/Test3/Tests (normal)/tests/E2-2.cmm @@ -0,0 +1,29 @@ +int dot_product(int u[3], int v[3]) { + return u[0] * v[0] + u[1] * v[1] + u[2] * v[2]; +} + +int cross_product(int x[3], int y[3], int z[3]) { + z[0] = x[1] * y[2] - x[2] * y[1]; + z[1] = x[2] * y[0] - x[0] * y[2]; + z[2] = x[0] * y[1] - x[1] * y[0]; + return 0; +} + +int main() { + int i; + int j; + int ops[2][3]; + int res[3]; + i = 0; + while (i < 2) { + j = 0; + while (j < 3) { + ops[i][j] = (i + 1) * (i + 1) + (j + 1) * (j + 1); + j = j + 1; + } + i = i + 1; + } + cross_product(ops[0], ops[1], res); + write(dot_product(res, res)); + return 0; +} diff --git a/Test3/Tests (normal)/tests/E2-3.cmm b/Test3/Tests (normal)/tests/E2-3.cmm new file mode 100755 index 0000000..3132a2b --- /dev/null +++ b/Test3/Tests (normal)/tests/E2-3.cmm @@ -0,0 +1,79 @@ +int merge(int a[6], int l, int m, int r) +{ + int la[10], ra[10]; + int i, j, k; + int n1 = m - (l - 1); + int n2 = r - m; + + i = 0; + while (i < n1) { + la[i] = a[l + i]; + i = i + 1; + } + j = 0; + while (j < n2) { + ra[j] = a[m + 1 + j]; + j = j + 1; + } + + i = 0; + j = 0; + k = l; + + while (i < n1 && j < n2) { + if (la[i] <= ra[j]) { + a[k] = la[i]; + i = i + 1; + } + else { + a[k] = ra[j]; + j = j + 1; + } + k = k + 1; + } + + while (i < n1) { + a[k] = la[i]; + i = i + 1; + k = k + 1; + } + + while (j < n2) { + a[k] = ra[j]; + j = j + 1; + k = k + 1; + } + return 0; +} + +int merge_sort(int arr[6], int start, int end){ + int mid = 0; + if (start >= end) { + return 0; + } + mid = start + (end - start) / 2; + merge_sort(arr, start, mid); + merge_sort(arr, mid + 1, end); + merge(arr, start, mid, end); + return 0; +} + +int main() +{ + int n = 6; + int array[6]; + int c = 0; + while (c < n) { + array[c] = read(); + c = c + 1; + } + + merge_sort(array, 0, n - 1); + + c = 0; + while (c < n) { + write(array[c]); + c = c + 1; + } + return 0; +} diff --git a/Test3/irsim/out.ir b/Test3/irsim/out.ir deleted file mode 100644 index 3f014c8..0000000 --- a/Test3/irsim/out.ir +++ /dev/null @@ -1,45 +0,0 @@ -FUNCTION nonsense : -PARAM v0 -PARAM v1 -t0 := #5 * #56 -t1 := v0 + t0 -t2 := t1 + #16 -t3 := #2 * #8 -t4 := t2 + t3 -t5 := t4 + #0 -t6 := t5 * #56 -t7 := v0 + t6 -t8 := t7 + #16 -t9 := #4 * #8 -t10 := t8 + t9 -t11 := t10 + #0 -t12 := v1 + #0 -t13 := *t12 + #6 -*t11 := t13 -RETURN #0 -FUNCTION main : -DEC v2 5600 -t14 := #5 * #56 -t15 := &v2 + t14 -t16 := t15 + #16 -t17 := #2 * #8 -t18 := t16 + t17 -t19 := t18 + #0 -*t19 := #3 -t20 := #5 * #56 -t21 := &v2 + t20 -t22 := t21 + #16 -t23 := #2 * #8 -t24 := t22 + t23 -ARG t24 -ARG &v2 -t25 := CALL nonsense -t26 := #3 * #56 -t27 := &v2 + t26 -t28 := t27 + #16 -t29 := #4 * #8 -t30 := t28 + t29 -t31 := t30 + #0 -t32 := *t31 -WRITE t32 -RETURN #0