void emitASSIGN(char op, GeneralType a, GeneralType b, GeneralType c) // {{{ { if(!isNoError) return; const char *prefixV=(b.t==INT)?"I":"F"; const char *prefixF=(b.t==INT)?"":"F"; const char *zero=(a.t==INT)?"0":"0.0"; switch(op){ case '+': case '-': case '*': case '/': case '%': fprintf(cmmOut, "/* a = b %c c */\n", op); loadAddr(b, 1); loadAddr(c, 2); fprintf(cmmOut, "%s__1 = %s__1 %c %s__2;\n", prefixV, prefixV, op, prefixV); saveAddr(a, 1); break; case 'r': fprintf(cmmOut, "/* a = b[c] */\n"); loadAddr(b, c, 1); saveAddr(a, 1); break; case 'l': fprintf(cmmOut, "/* a[b] = c */\n"); loadAddr(c, 1); saveAddr(a, b, 1); break; } } // }}}
void emitIFHEAD(GeneralType a, int labelFalse) // {{{ { if(!isNoError) return; loadAddr(a, 1); // fprintf(cmmOut, "printf(\"I__1 = %%d\\n\", I__1);\n"); fprintf(cmmOut, "if ( I__1 == 0 ) "); emitJUMP(labelFalse); } // }}}
void emitCOND(char op, GeneralType a, GeneralType b, GeneralType c) // {{{ { if(!isNoError) return; const char *prefixV=(b.t==INT)?"I":"F"; const char *prefixF=(b.t==INT)?"":"F"; const char *zero=(a.t==INT)?"0":"0.0"; int labelTrue=newLabel(); // true int labelEnd=newLabel(); // end switch(op){ case '<': case '>': case '=': case 'G': case 'L': case 'N': GeneralType constGt; constGt.t = INT; constGt.s = _CONST; fprintf(cmmOut, "/* a = b %c c */\n", op); loadAddr(b, 1); loadAddr(c, 2); fprintf(cmmOut, "%s__1 = %s__1 - %s__2;\n", prefixV, prefixV, prefixV); if(op == 'G') fprintf(cmmOut, "if ( %s__1 >= %s ) ", prefixV, zero); else if(op == 'L') fprintf(cmmOut, "if ( %s__1 <= %s ) ", prefixV, zero); else if(op == 'N' || op == '=') fprintf(cmmOut, "if ( %s__1 == %s ) ", prefixV, zero); else fprintf(cmmOut, "if ( %s__1 %c %s ) ", prefixV, op, zero); emitJUMP(labelTrue); constGt.ival = (op=='N')?1:0; emitASSIGN('=', a, constGt); emitJUMP(labelEnd); emitLABEL(labelTrue); constGt.ival = (op=='N')?0:1; emitASSIGN('=', a, constGt); emitLABEL(labelEnd); break; } } // }}}
void emitWRITE(GeneralType a) // {{{ { if(!isNoError) return; const char *prefixA=(a.t==INT)?"d":"f"; const char *prefixV=(a.t==INT)?"I":"F"; loadAddr(a, 1); fprintf(cmmOut, "printf(\"%%%s\", %s__1);\n", prefixA, prefixV); } // }}}
void saveAddr(GeneralType a, GeneralType b, int regNum) // {{{ { if(!isNoError) return; const char *prefixV=(a.t==INT)?"I":"F"; const char *prefixF=(a.t==INT)?"":"F"; switch(a.s){ case LOCAL: loadAddr(b, 8); fprintf(cmmOut, "I__9 = I__0+%d;\n", procInfo.lstart); fprintf(cmmOut, "I__9 = I__9+I__8;\n"); fprintf(cmmOut, "%sASSET__S(I__9, %s__%d);\n", prefixF, prefixV, regNum); break; case TEMP: loadAddr(b, 1); fprintf(cmmOut, "I__9 = I__0+%d;\n", procInfo.tstart); fprintf(cmmOut, "I__9 = I__9+I__8;\n", regNum); fprintf(cmmOut, "%sASSET__S(I__9, %s__%d);\n", prefixF, prefixV, regNum); break; } } // }}}
void emitASSIGN(char op, GeneralType a, GeneralType b) // {{{ { if(!isNoError) return; const char *prefixV=(b.t==INT)?"I":"F"; const char *prefixF=(b.t==INT)?"":"F"; switch(op){ case '=': fprintf(cmmOut, "/* a %c b */\n", op); loadAddr(b, 1); saveAddr(a, 1); break; case 'm': fprintf(cmmOut, "/* a = -b */\n"); loadAddr(b, 1); fprintf(cmmOut, "%s__1 = %s__1 * -1;\n", prefixV, prefixV); saveAddr(a, 1); break; case '+': case '-': case '*': case '/': case '%': case '&': case '|': case '^': fprintf(cmmOut, "/* a %c= b */\n", op); loadAddr(a, 1); loadAddr(b, 2); fprintf(cmmOut, "%s__1 = %s__1 %c %s__2;\n", prefixV, prefixV, op, prefixV); saveAddr(a, 1); break; } } // }}}
void emitASSIGN(char op, GeneralType a) // {{{ { if(!isNoError) return; const char *prefixV=(a.t==INT)?"I":"F"; const char *prefixF=(a.t==INT)?"":"F"; switch(op){ case '!': fprintf(cmmOut, "/* a = -a */\n"); loadAddr(a, 1); fprintf(cmmOut, "I__1 = I__1+1;\n"); fprintf(cmmOut, "I__1 = I__1&1;\n"); saveAddr(a, 1); break; } } // }}}
unsigned int get_memw(unsigned int addr) { loadAddr(addr); return (readMemByteInc() << 8) + readMemByteInc(); }
unsigned char get_memb(unsigned int addr) { loadAddr(addr); return readMemByteInc(); }
void Quads_to_Assembly(qnode **head, FILE *f) { fp = f; qnode *temp; temp = *head; quad *x ; quad *y ; quad *z ; char *MainName; MainName = (char *)malloc(246); snprintf(MainName, 256, "_%s", main_program->id); fprintf(fp, "xseg\tsegment public 'code'\n" "\tassume\tcs:xseg, ds:xseg, ss:xseg\n" "\torg\t100h\n" "main\tproc near\n" "\tcall\tnear ptr %s\n" "\tmov\tax, 4C00h\n" "\tint\t21h\n" "main\tendp\n\n", MainName); free(MainName); if (temp == NULL) fprintf(stdout, "\nThe list is empty!\n"); else { while (temp != NULL) { fprintf(fp, "@%d:\n", temp->n); x = temp->x; y = temp->y; z = temp->z; switch(temp->op) { case OP_UNIT: { char *nm = name(x); fprintf(fp, "%s proc near\n" "\tpush\tbp\n" "\tmov\tbp, sp\n" "\tsub\tsp, %d\n", nm, -temp->negOffset); free(nm); break; } case OP_ENDU: { char *end = endof(x->value.se, temp->nestingLevel); fprintf(fp, "\tjmp\t%s\n", end); char *nm = name(x); fprintf(fp, "%s:\n" "\tmov\tsp, bp\n" "\tpop\tbp\n" "\tret\n" "%s\tendp\n", end, nm); free(nm); free(end); break; } case OP_JUMP: { char *lbl = label(z); fprintf(fp, "\tjmp\t%s\n", lbl); free(lbl); break; } case OP_JUMPL: { char *lbl = label(z); fprintf(fp, "\tjmp\t%s\n", lbl); free(lbl); break; } case OP_LABEL: { char *lbl = label(z); free(lbl); break; } case OP_IFB: { load("al", x, temp); char *lbl = label(z); fprintf(fp, "\tor\tal, al\n" "\tjnz\t%s\n", lbl); free(lbl); break; } case OP_CALL: { /*If z is procedure*/ if (equalType(z->value.se->u.eFunction.resultType, typeVoid)) fprintf(fp, "\tsub\tsp, 2\n"); fprintf(fp, "\tsub\tsp, 2\n"); /*updateAL(temp, z->value.se); */ char *nm = name(z); fprintf(fp, "\tcall\tnear ptr %s\n" "\tadd\tsp, %d\n", nm, size + 4); free(nm); size = 0; break; } case OP_PAR: { if (x->type == QUAD_SE) size += sizeOfType(x->value.se->u.eParameter.type); else if (x->type == QUAD_POINTER) size += sizeOfType(x->value.se->u.eParameter.type->refType); else size += (x->type == QUAD_INTEGER) ? (sizeOfType(typeInteger)) : (sizeOfType(typeChar)); if (y->mode == PASS_BY_VALUE) { if (x->type == QUAD_INTEGER || (x->type == QUAD_SE && equalType(x->value.se->u.eParameter.type, typeInteger))) { load("ax", x, temp); fprintf(fp, "\tpush ax\n"); } else if (x->type == QUAD_CHAR || x->type == QUAD_BOOL || (x->type == QUAD_SE && (equalType(x->value.se->u.eParameter.type, typeChar) || equalType(x->value.se->u.eParameter.type, typeBoolean)))) { load("al", x, temp); fprintf(fp, "\tsub\tsp, 1\n" "\tmov\tsi, sp\n" "\tmov\tbyte ptr [si], al\n"); } else fprintf(fp, "Error 1"); } else if (y->mode == PASS_BY_REFERENCE || y->mode == RET) { loadAddr("si", x, temp); fprintf(fp, "\tpush\tsi\n"); } else { fprintf(fp, "Error 2\n"); return; } break; } case OP_RET: { char *end = endof(temp->inFunction, temp->nestingLevel); fprintf(fp, "\tjmp %s\n", end); free(end); break; } case OP_RETV: { if (x->type == QUAD_INTEGER || (x->type == QUAD_SE && equalType(x->value.se->u.eVariable.type, typeInteger))) { fprintf(fp, "\tmov\tsi, word ptr [bp+6]\n"); // Address of result load("ax", x, temp); fprintf(fp, "\tmov\tword ptr [si], ax\n"); // store it } else if (x->type == QUAD_CHAR || x->type == QUAD_BOOL || (x->type == QUAD_SE && (equalType(x->value.se->u.eVariable.type, typeChar) || equalType(x->value.se->u.eVariable.type, typeBoolean)))) { fprintf(fp, "\tmov\tsi, byte ptr [bp+6]\n"); // Address of result load("al", x, temp); fprintf(fp, "\tmov\tbyte ptr [si], al\n"); // store it } break; } case OP_eq: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "cmp\tax, dx\n"); fprintf(fp, "\tje\t"); char *lbl = label(z); fprintf(fp, "%s\n", lbl); free(lbl); break; } case OP_neq: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tcmp\tax, dx\n"); fprintf(fp, "\tjne\t"); char *lbl = label(z); fprintf(fp, "%s\n", lbl); free(lbl); break; } case OP_less: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tcmp\tax, dx\n"); fprintf(fp, "\tjl\t"); char *lbl = label(z); fprintf(fp, "%s\n", lbl); free(lbl); break; } case OP_greater: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tcmp\tax, dx\n"); fprintf(fp, "\tjg\t"); char *lbl = label(z); fprintf(fp, "%s\n", lbl); free(lbl); break; } case OP_leq: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tcmp\tax, dx\n"); fprintf(fp, "\tjle\t"); char *lbl = label(z); fprintf(fp, "%s\n", lbl); free(lbl); break; } case OP_geq: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tcmp\tax, dx\n"); fprintf(fp, "\tjge\t"); char *lbl = label(z); fprintf(fp, "%s\n", lbl); free(lbl); break; } case OP_PLUS: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tadd\tax, dx\n"); store("ax", z, temp); break; } case OP_MINUS: { load("ax", x, temp); load("dx", y, temp); fprintf(fp, "\tsub\tax, dx\n"); store("ax", z, temp); break; } case OP_bmul: { load("ax", x, temp); load("cx", y, temp); fprintf(fp, "\timul\tcx\n"); store("ax", z, temp); break; } case OP_bdiv: { load("ax", x, temp); fprintf(fp, "\tcwd\n"); load("cx", y, temp); fprintf(fp, "\tidiv\tcx\n"); store("ax", z, temp); break; } case OP_bmod: { load("ax", x, temp); fprintf(fp, "cwd\n"); load("cx", y, temp); fprintf(fp, "\tidiv\tcx\n"); store("dx", z, temp); break; } case OP_mod: { load("ax", x, temp); fprintf(fp, "\tcwd\n"); load("cx", y, temp); fprintf(fp, "\tidiv\tcx\n"); store("dx", z, temp); break; } case OP_assign: { /*Fix this*/ if (x->type == QUAD_SE || x->type == QUAD_POINTER) { if (equalType(x->value.se->u.eVariable.type, typeInteger) || equalType(x->value.se->u.eVariable.type, typePointer(typeInteger))) { load("ax", x, temp); store("ax", z, temp); } else if (equalType(x->value.se->u.eVariable.type, typeChar) || equalType(x->value.se->u.eVariable.type, typePointer(typeChar)) || equalType(x->value.se->u.eVariable.type, typeBoolean) || equalType(x->value.se->u.eVariable.type, typePointer(typeBoolean))) { load("al", x, temp); store("al", z, temp); } } else if (x->type == QUAD_INTEGER) { load("ax", x, temp); store("ax", z, temp); } else if (x->type == QUAD_CHAR || x->type == QUAD_BOOL) { load("al", x, temp); store("al", z, temp); } break; } case OP_ARRAY: { load("ax", y, temp); fprintf(fp, "\tmov\tcx, %d\n" "\timul cx\n", size); loadAddr("cx", x, temp); fprintf(fp, "\tadd\tax, cx\n"); store("ax", z, temp); break; } default: fprintf(fp, "For debugging\n"); break; } temp = temp->next; } } fprintf(fp, //"extrn\t_putchar:proc\n" //"extrn\t_puts:proc\n" "extrn\t_writeInteger:proc\n" "extrn\t_writeBoolean:proc\n" "extrn\t_writeChar:proc\n" "extrn\t_writeReal:proc\n" "extrn\t_writeString:proc\n" "extrn\t_READ_INT:proc\n" "extrn\t_READ_BOOL:proc\n" "extrn\t_READ_CHAR:proc\n" "extrn\t_READ_REAL:proc\n" "extrn\t_READ_STRING:proc\n" "extrn\t_abs:proc\n" "extrn\t_fabs:proc\n" "extrn\t_sqrt:proc\n" "extrn\t_sin:proc\n" "extrn\t_cos:proc\n" "extrn\t_tan:proc\n" "extrn\t_arctan:proc\n" "extrn\t_exp:proc\n" "extrn\t_ln:proc\n" "extrn\t_pi:proc\n" "extrn\t_trunc:proc\n" "extrn\t_round:proc\n" "extrn\t_TRUNC:proc\n" "extrn\t_ROUND:proc\n" //"extrn\t_strlen:proc\n" //"extrn\t_strcmp:proc\n" //"extrn\t_strcpy:proc\n" //"extrn\t_strcat:proc\n" ); print_strings(fp, head_str); fprintf(fp, "xseg ends\n" "\tend\tmain\n"); }