void ass_fctCallEnd() { PRINT_DEBUG(); printInst("6 %d %d\n", ADDR_R1, nbCurrentParams); // R3 = nbCurrentParams printInst("3 %d %d %d\n", ADDR_SP, ADDR_SP, ADDR_R1); // SP = SP - nbCurrentParams nbCurrentParams = 0; }
void ass_ref(char* varName, int reg) { PRINT_DEBUG(); int addr = symboleT_seekAddressByName(varName); printInst("6 %d %d\n", ADDR_R0+reg, addr); // reg = addr printInst("1 %d %d %d\n", ADDR_R0+reg, ADDR_R0+reg, ADDR_CONTEXT); // addr += CONTEXT }
void ass_or() { PRINT_DEBUG(); printInst("8 %d %d\n", ADDR_R0, instructionNumber+1); // if(!R0) goto testR1; printInst("7 %d\n", instructionNumber+2); // goto end; printInst("8 %d %d\n", ADDR_R1, instructionNumber+1); // if(!R1) goto end; printInst("6 %d %d\n", ADDR_R0, 1); // R0 = 1 }
void ass_and() { PRINT_DEBUG(); printInst("8 %d %d\n", ADDR_R0, instructionNumber+2); // if(!R0) goto false; printInst("8 %d %d\n", ADDR_R1, instructionNumber+1); // if(!R1) goto false; printInst("7 %d\n", instructionNumber+1); // true: goto end; printInst("6 %d %d\n", ADDR_R0, 0); // false: R0 = 0 }
void ass_progBegin() { PRINT_DEBUG(); instructionNumber = 1; printInst("6 %d 0\n", ADDR_STACK); // STACK[0] = 0 printInst("6 %d %d\n", ADDR_SP, ADDR_STACK+1); // SP = ADDR_STACK + 1 printInst("7 .main \n"); // goto main }
void ass_fctCallJmp(char* fctName) { PRINT_DEBUG(); printInst("6 %d %d\n", ADDR_R1, 5); printInst("10 %d\n", ADDR_R0); // R1 = adresse de retour printInst("1 %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); empiler(ADDR_R0); printInst("7 .%s \n", fctName); }
void ass_fctEnd(char* fctName) { PRINT_DEBUG(); printInst("5 %d %d\n", ADDR_SP, ADDR_CONTEXT); depiler(ADDR_CONTEXT); depiler(ADDR_R1); // depiler adresse de retour printInst("F %d\n", ADDR_R1); // goto R2 symboleT_endBloc(); // parameters }
void ass_declVar(char* varName, int arraySize) { PRINT_DEBUG(); int addr = symboleT_getSymboleNumber(); symboleT_pushTable(varName, addr); if(arraySize <= 1) empiler(ADDR_R0); // empiler varName else { // traiter les tableaux for(int i = 1; i < arraySize; i++) symboleT_pushTable("", addr); printInst("6 %d %d\n", ADDR_R0, arraySize); // R0 = arraySize printInst("1 %d %d %d\n", ADDR_SP, ADDR_SP, ADDR_R0); // SP += arraySize } }
void ass_ifThen(int numLabel) { PRINT_DEBUG(); char label[15]; sprintf(label, "%delse",numLabel); labelT_pushTableName(label); printInst("8 %d .%s\n", ADDR_R0, label); // if(!R0) goto else }
void ass_whileDo(int numLabel) { PRINT_DEBUG(); char label[15]; sprintf(label, "%dewhl",numLabel); labelT_pushTableComplet(label, instructionNumber); printInst("8 %d .%s\n", ADDR_R0, label); // if(!R0) goto whileEnd }
static void translateBlock(std::deque<llvm::MCInst>& block) { typedef std::map<std::string, LLVMValueRef>::const_iterator ValRef; std::map<std::string, LLVMValueRef> locals; std::map<std::string, LLVMValueRef> regs; for (InstIter it = block.begin(); it != block.end(); ++it) { llvm::MCInst& inst = *it; const llvm::MCInstrDesc& id = MII->get(inst.getOpcode()); llvm::StringRef iname = MII->getName(inst.getOpcode()); if (iname.startswith("MOV")) { LLVMValueRef lhs; unsigned iop = 0; if (id.OpInfo[0].OperandType == llvm::MCOI::OPERAND_MEMORY) { std::string localName = getLocalName(inst, 0); ValRef pval = locals.find(localName); if (pval == locals.end()) { lhs = LLVMBuildAlloca(llvmBuilder, LLVMInt32Type(), localName.c_str()); locals[localName] = lhs; } else { lhs = pval->second; } if (id.OpInfo[5].OperandType == llvm::MCOI::OPERAND_IMMEDIATE) { const llvm::MCOperand& op = inst.getOperand(5); LLVMBuildStore(llvmBuilder, lhs, LLVMConstInt(LLVMInt32Type(), op.getImm(), 0)); } if (id.OpInfo[5].OperandType == llvm::MCOI::OPERAND_REGISTER) { LLVMBuildStore(llvmBuilder, lhs, regs[getRegName(inst, 5)]); } } else if (id.OpInfo[0].OperandType == llvm::MCOI::OPERAND_REGISTER) { LLVMValueRef rhs; printInst(inst); if (id.OpInfo[1].OperandType == llvm::MCOI::OPERAND_IMMEDIATE) { rhs = LLVMConstInt(LLVMInt32Type(), inst.getOperand(1).getImm(), 0); } else if (id.OpInfo[1].OperandType == llvm::MCOI::OPERAND_MEMORY) { ValRef pval = locals.find(getLocalName(inst, 1)); if (pval == locals.end()) { llvm::outs() << "No such local " << getLocalName(inst, 1) << "\n"; break; } rhs = LLVMBuildLoad(llvmBuilder, pval->second, getRegName(inst, 0)); } else { continue; } regs[getRegName(inst, 0)] = rhs; } } } }
void ass_whileEnd(int numLabel) { PRINT_DEBUG(); char label[15]; sprintf(label, "%dbwhl",numLabel); printInst("7 .%s\n", label); // goto whileBegin sprintf(label, "%dewhl",numLabel); labelT_addAddressToLabel(label, instructionNumber); }
void ass_ifElse(int numLabel) { PRINT_DEBUG(); char label[15]; sprintf(label, "%deif",numLabel); labelT_pushTableName(label); printInst("7 .%s\n", label); // goto ifEnd sprintf(label, "%delse",numLabel); labelT_addAddressToLabel(label, instructionNumber); }
void ass_fctBegin(char* fctName, int nbParams) { PRINT_DEBUG(); labelT_pushTableComplet(fctName, instructionNumber); empiler(ADDR_CONTEXT); // sauver le contexte printInst("5 %d %d\n", ADDR_CONTEXT, ADDR_SP); // CONTEXT = SP symboleT_newBloc(); // parameters char** tabParams = funT_getParamsByFunName(fctName); for(int i=0; i<nbParams; i++) { symboleT_pushTable(tabParams[i], (-2-nbParams) + i ); } symboleT_setSymboleNumber(0); }
void ass_not() { PRINT_DEBUG(); printInst("11 %d %d\n", ADDR_R0, ADDR_R0); }
void depiler(int reg) { printInst("6 %d 1\n", reg); // reg = 1 printInst("3 %d %d %d\n", ADDR_SP, ADDR_SP, reg); // SP-- printInst("D %d %d\n", reg, ADDR_SP); // reg = *SP }
void ass_str() { PRINT_DEBUG(); printInst("E %d %d\n", ADDR_R0, ADDR_R1); // *R0 = R1 }
void ass_print() { PRINT_DEBUG(); depiler(ADDR_R0); printInst("C %d\n", ADDR_R0); }
void empiler(int reg) { printInst("E %d %d\n", ADDR_SP, reg); // *SP = reg printInst("6 %d 1\n", reg); // reg = 1 printInst("1 %d %d %d\n", ADDR_SP, ADDR_SP, reg); // SP++ }
void ass_mov(int reg1, int reg2) { PRINT_DEBUG(); printInst("5 %d %d\n", ADDR_R0 + reg1, ADDR_R0 + reg2); }
void ass_ld(int value, int reg) { PRINT_DEBUG(); printInst("6 %d %d\n", ADDR_R0 + reg, value); }
void ass_mul() { PRINT_DEBUG(); printInst("2 %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); }
void ass_add() { PRINT_DEBUG(); printInst("1 %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); }
void ass_div() { PRINT_DEBUG(); printInst("4 %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); }
void ass_inf() { PRINT_DEBUG(); printInst("9 %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); }
void ass_deref() { PRINT_DEBUG(); printInst("D %d %d\n", ADDR_R0, ADDR_R0); // R0 = *R0 }
void ass_sup() { PRINT_DEBUG(); printInst("A %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); }
void ass_equ() { PRINT_DEBUG(); printInst("B %d %d %d\n", ADDR_R0, ADDR_R0, ADDR_R1); }