⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhdl.cpp

📁 一种将c高级语言转化给VHDL的编译器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 + -