📄 vhdl.cpp
字号:
BasicBlock *Succ = cast<BasicBlock>(SI.getOperand(i+1)); printBranchToBlock(SI.getParent(), Succ, 2); if (Succ == SI.getParent()->getNext()) Out << " break;\n"; } Out << " }\n";}bool VWriter::isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { // If PHI nodes need copies, we need the copy code... if (isa<PHINode>(To->front()) || From->getNext() != To) // Not directly successor, need goto return true; // Otherwise we don't need the code. return false;}void VWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ, unsigned Indent) { for (BasicBlock::iterator I = Succ->begin(); PHINode *PN = dyn_cast<PHINode>(I); ++I) { // now we have to do the printing Out << std::string(Indent, ' '); Out << " " << Mang->getValueName(I) << "__PHI_TEMPORARY = "; writeOperand(PN->getIncomingValue(PN->getBasicBlockIndex(CurBB))); Out << "; /* for PHI node */\n"; } if (CurBB->getNext() != Succ || isa<InvokeInst>(CurBB->getTerminator()) || isa<SwitchInst>(CurBB->getTerminator())) { Out << std::string(Indent, ' ') << " goto "; writeOperand(Succ); Out << ";\n"; }}// Branch instruction printing - Avoid printing out a branch to a basic block// that immediately succeeds the current one.//void VWriter::visitBranchInst(BranchInst &I) { if (I.isConditional()) { if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(0))) { Out << " if ("; writeOperand(I.getCondition()); Out << ") {\n"; printBranchToBlock(I.getParent(), I.getSuccessor(0), 2); if (isGotoCodeNecessary(I.getParent(), I.getSuccessor(1))) { Out << " } else {\n"; printBranchToBlock(I.getParent(), I.getSuccessor(1), 2); } } else { // First goto not necessary, assume second one is... Out << " if (!"; writeOperand(I.getCondition()); Out << ") {\n"; printBranchToBlock(I.getParent(), I.getSuccessor(1), 2); } Out << " }\n"; } else { printBranchToBlock(I.getParent(), I.getSuccessor(0), 0); } Out << "\n";}// PHI nodes get copied into temporary values at the end of predecessor basic// blocks. We now need to copy these temporary values into the REAL value for// the PHI.void VWriter::visitPHINode(PHINode &I) { writeOperand(&I); Out << "__PHI_TEMPORARY";}void VWriter::visitBinaryOperator(Instruction &I) { // binary instructions, shift instructions, setCond instructions. assert(!isa<PointerType>(I.getType())); // We must cast the results of binary operations which might be promoted. bool needsCast = false; if ((I.getType() == Type::UByteTy) || (I.getType() == Type::SByteTy) || (I.getType() == Type::UShortTy) || (I.getType() == Type::ShortTy) || (I.getType() == Type::FloatTy)) { needsCast = true; Out << "(("; printType(Out, I.getType()); Out << ")("; } writeOperand(I.getOperand(0)); switch (I.getOpcode()) { case Instruction::Add: Out << " + "; break; case Instruction::Sub: Out << " - "; break; case Instruction::Mul: Out << "*"; break; case Instruction::Div: Out << "/"; break; case Instruction::Rem: Out << "%"; break; case Instruction::And: Out << " & "; break; case Instruction::Or: Out << " | "; break; case Instruction::Xor: Out << " ^ "; break; case Instruction::SetEQ: Out << " == "; break; case Instruction::SetNE: Out << " != "; break; case Instruction::SetLE: Out << " <= "; break; case Instruction::SetGE: Out << " >= "; break; case Instruction::SetLT: Out << " < "; break; case Instruction::SetGT: Out << " > "; break; case Instruction::Shl : Out << " << "; break; case Instruction::Shr : Out << " >> "; break; default: std::cerr << "Invalid operator type!" << I; abort(); } writeOperand(I.getOperand(1)); if (needsCast) { Out << "))"; }}void VWriter::visitCastInst(CastInst &I) { if (I.getType() == Type::BoolTy) { Out << "("; writeOperand(I.getOperand(0)); Out << " != 0)"; return; } Out << "("; printType(Out, I.getType()); Out << ")"; if (isa<PointerType>(I.getType())&&I.getOperand(0)->getType()->isIntegral() || isa<PointerType>(I.getOperand(0)->getType())&&I.getType()->isIntegral()) { // Avoid "cast to pointer from integer of different size" warnings Out << "(long)"; } writeOperand(I.getOperand(0));}void VWriter::visitSelectInst(SelectInst &I) { Out << "(("; writeOperand(I.getCondition()); Out << ") ? ("; writeOperand(I.getTrueValue()); Out << ") : ("; writeOperand(I.getFalseValue()); Out << "))"; }void VWriter::lowerIntrinsics(Function &F) { for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) if (CallInst *CI = dyn_cast<CallInst>(I++)) if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { case Intrinsic::not_intrinsic: case Intrinsic::vastart: case Intrinsic::vacopy: case Intrinsic::vaend: case Intrinsic::returnaddress: case Intrinsic::frameaddress: case Intrinsic::setjmp: case Intrinsic::longjmp: // We directly implement these intrinsics break; default: // All other intrinsic calls we must lower. Instruction *Before = CI->getPrev(); IL.LowerIntrinsicCall(CI); if (Before) { // Move iterator to instruction after call I = Before; ++I; } else { I = BB->begin(); } }}void VWriter::visitCallInst(CallInst &I) { // Handle intrinsic function calls first... if (Function *F = I.getCalledFunction()) if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { switch (ID) { default: assert(0 && "Unknown LLVM intrinsic!"); case Intrinsic::vastart: Out << "0; "; Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; // Output the last argument to the enclosing function... if (I.getParent()->getParent()->arg_empty()) { std::cerr << "The C backend does not currently support zero " << "argument varargs functions, such as '" << I.getParent()->getParent()->getName() << "'!\n"; abort(); } writeOperand(--I.getParent()->getParent()->arg_end()); Out << ")"; return; case Intrinsic::vaend: Out << "va_end(*(va_list*)&"; writeOperand(I.getOperand(1)); Out << ")"; return; case Intrinsic::vacopy: Out << "0;"; Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; Out << "*(va_list*)&"; writeOperand(I.getOperand(1)); Out << ")"; return; case Intrinsic::returnaddress: Out << "__builtin_return_address("; writeOperand(I.getOperand(1)); Out << ")"; return; case Intrinsic::frameaddress: Out << "__builtin_frame_address("; writeOperand(I.getOperand(1)); Out << ")"; return; case Intrinsic::setjmp: Out << "setjmp(*(jmp_buf*)"; writeOperand(I.getOperand(1)); Out << ")"; return; case Intrinsic::longjmp: Out << "longjmp(*(jmp_buf*)"; writeOperand(I.getOperand(1)); Out << ", "; writeOperand(I.getOperand(2)); Out << ")"; return; } } visitCallSite(&I);}void VWriter::visitCallSite(CallSite CS) { const PointerType *PTy = cast<PointerType>(CS.getCalledValue()->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); writeOperand(CS.getCalledValue()); Out << "("; if (CS.arg_begin() != CS.arg_end()) { CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); writeOperand(*AI); for (++AI; AI != AE; ++AI) { Out << ", "; writeOperand(*AI); } } Out << ")";} void VWriter::visitMallocInst(MallocInst &I) { assert(0 && "lowerallocations pass didn't work!");}void VWriter::visitAllocaInst(AllocaInst &I) { Out << "("; printType(Out, I.getType()); Out << ") alloca(sizeof("; printType(Out, I.getType()->getElementType()); Out << ")"; if (I.isArrayAllocation()) { Out << " * " ; writeOperand(I.getOperand(0)); } Out << ")";}void VWriter::visitFreeInst(FreeInst &I) { assert(0 && "lowerallocations pass didn't work!");}void VWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I, gep_type_iterator E) { bool HasImplicitAddress = false; // If accessing a global value with no indexing, avoid *(&GV) syndrome if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) { HasImplicitAddress = true; } else if (isDirectAlloca(Ptr)) { HasImplicitAddress = true; } if (I == E) { if (!HasImplicitAddress) Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]' writeOperandInternal(Ptr); return; } const Constant *CI = dyn_cast<Constant>(I.getOperand()); if (HasImplicitAddress && (!CI || !CI->isNullValue())) Out << "(&"; writeOperandInternal(Ptr); if (HasImplicitAddress && (!CI || !CI->isNullValue())) { Out << ")"; HasImplicitAddress = false; // HIA is only true if we haven't addressed yet } assert(!HasImplicitAddress || (CI && CI->isNullValue()) && "Can only have implicit address with direct accessing"); if (HasImplicitAddress) { ++I; } else if (CI && CI->isNullValue()) { gep_type_iterator TmpI = I; ++TmpI; // Print out the -> operator if possible... if (TmpI != E && isa<StructType>(*TmpI)) { Out << (HasImplicitAddress ? "." : "->"); Out << "field" << cast<ConstantUInt>(TmpI.getOperand())->getValue(); I = ++TmpI; } } for (; I != E; ++I) if (isa<StructType>(*I)) { Out << ".field" << cast<ConstantUInt>(I.getOperand())->getValue(); } else { Out << "["; writeOperand(I.getOperand()); Out << "]"; }}void VWriter::visitLoadInst(LoadInst &I) { Out << "*"; writeOperand(I.getOperand(0));}void VWriter::visitStoreInst(StoreInst &I) { Out << "*"; writeOperand(I.getPointerOperand()); Out << " = "; writeOperand(I.getOperand(0));}void VWriter::visitGetElementPtrInst(GetElementPtrInst &I) { Out << "&"; printIndexingExpression(I.getPointerOperand(), gep_type_begin(I), gep_type_end(I));}void VWriter::visitVANextInst(VANextInst &I) { Out << Mang->getValueName(I.getOperand(0)); Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", "; printType(Out, I.getArgType()); Out << ")"; }void VWriter::visitVAArgInst(VAArgInst &I) { Out << "0;\n"; Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&"; writeOperand(I.getOperand(0)); Out << ");\n " << Mang->getValueName(&I) << " = va_arg(Tmp, "; printType(Out, I.getType()); Out << ");\n va_end(Tmp); }";}//===----------------------------------------------------------------------===//// External Interface declaration//===----------------------------------------------------------------------===//bool VTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) { PM.add(createLowerGCPass()); PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); PM.add(new VBackendNameAllUsedStructs()); PM.add(new VWriter(o, getIntrinsicLowering())); return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -