📄 vhdl.cpp
字号:
// As a special case, print the array as a string if it is an array of // ubytes or an array of sbytes with positive values. // const Type *ETy = CPA->getType()->getElementType(); bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy); // Make sure the last character is a null char, as automatically added by C if (isString && (CPA->getNumOperands() == 0 || !cast<Constant>(*(CPA->op_end()-1))->isNullValue())) isString = false; if (isString) { Out << "\""; // Keep track of whether the last number was a hexadecimal escape bool LastWasHex = false; // Do not include the last character, which we know is null for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) { unsigned char C = cast<ConstantInt>(CPA->getOperand(i))->getRawValue(); // Print it out literally if it is a printable character. The only thing // to be careful about is when the last letter output was a hex escape // code, in which case we have to be careful not to print out hex digits // explicitly (the C compiler thinks it is a continuation of the previous // character, sheesh...) // if (isprint(C) && (!LastWasHex || !isxdigit(C))) { LastWasHex = false; if (C == '"' || C == '\\') Out << "\\" << C; else Out << C; } else { LastWasHex = false; switch (C) { case '\n': Out << "\\n"; break; case '\t': Out << "\\t"; break; case '\r': Out << "\\r"; break; case '\v': Out << "\\v"; break; case '\a': Out << "\\a"; break; case '\"': Out << "\\\""; break; case '\'': Out << "\\\'"; break; default: Out << "\\x"; Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')); Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); LastWasHex = true; break; } } } Out << "\""; } else { Out << "{"; if (CPA->getNumOperands()) { Out << " "; printConstant(cast<Constant>(CPA->getOperand(0))); for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) { Out << ", "; printConstant(cast<Constant>(CPA->getOperand(i))); } } Out << " }"; }}// isFPCSafeToPrint - Returns true if we may assume that CFP may be written out// textually as a double (rather than as a reference to a stack-allocated// variable). We decide this by converting CFP to a string and back into a// double, and then checking whether the conversion results in a bit-equal// double to the original value of CFP. This depends on us and the target C// compiler agreeing on the conversion process (which is pretty likely since we// only deal in IEEE FP).//static bool isFPCSafeToPrint(const ConstantFP *CFP) {#if HAVE_PRINTF_A char Buffer[100]; sprintf(Buffer, "%a", CFP->getValue()); if (!strncmp(Buffer, "0x", 2) || !strncmp(Buffer, "-0x", 3) || !strncmp(Buffer, "+0x", 3)) return atof(Buffer) == CFP->getValue(); return false;#else std::string StrVal = ftostr(CFP->getValue()); while (StrVal[0] == ' ') StrVal.erase(StrVal.begin()); // Check to make sure that the stringized number is not some string like "Inf" // or NaN. Check that the string matches the "[-+]?[0-9]" regex. if ((StrVal[0] >= '0' && StrVal[0] <= '9') || ((StrVal[0] == '-' || StrVal[0] == '+') && (StrVal[1] >= '0' && StrVal[1] <= '9'))) // Reparse stringized version! return atof(StrVal.c_str()) == CFP->getValue(); return false;#endif}// printConstant - The LLVM Constant to C Constant converter.void VWriter::printConstant(Constant *CPV) { if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) { switch (CE->getOpcode()) { case Instruction::Cast: Out << "(("; printType(Out, CPV->getType()); Out << ")"; printConstant(CE->getOperand(0)); Out << ")"; return; case Instruction::GetElementPtr: Out << "(&("; printIndexingExpression(CE->getOperand(0), gep_type_begin(CPV), gep_type_end(CPV)); Out << "))"; return; case Instruction::Select: Out << "("; printConstant(CE->getOperand(0)); Out << "?"; printConstant(CE->getOperand(1)); Out << ":"; printConstant(CE->getOperand(2)); Out << ")"; return; case Instruction::Add: case Instruction::Sub: case Instruction::Mul: case Instruction::Div: case Instruction::Rem: case Instruction::SetEQ: case Instruction::SetNE: case Instruction::SetLT: case Instruction::SetLE: case Instruction::SetGT: case Instruction::SetGE: case Instruction::Shl: case Instruction::Shr: Out << "("; printConstant(CE->getOperand(0)); switch (CE->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::SetEQ: Out << " == "; break; case Instruction::SetNE: Out << " != "; break; case Instruction::SetLT: Out << " < "; break; case Instruction::SetLE: Out << " <= "; break; case Instruction::SetGT: Out << " > "; break; case Instruction::SetGE: Out << " >= "; break; case Instruction::Shl: Out << " << "; break; case Instruction::Shr: Out << " >> "; break; default: assert(0 && "Illegal opcode here!"); } printConstant(CE->getOperand(1)); Out << ")"; return; default: std::cerr << "VWriter Error: Unhandled constant expression: " << *CE << "\n"; abort(); } } switch (CPV->getType()->getTypeID()) { case Type::BoolTyID: Out << (CPV == ConstantBool::False ? "0" : "1"); break; case Type::SByteTyID: case Type::ShortTyID: Out << cast<ConstantSInt>(CPV)->getValue(); break; case Type::IntTyID: if ((int)cast<ConstantSInt>(CPV)->getValue() == (int)0x80000000) Out << "((int)0x80000000)"; // Handle MININT specially to avoid warning else Out << cast<ConstantSInt>(CPV)->getValue(); break; case Type::LongTyID: Out << cast<ConstantSInt>(CPV)->getValue() << "ll"; break; case Type::UByteTyID: case Type::UShortTyID: Out << cast<ConstantUInt>(CPV)->getValue(); break; case Type::UIntTyID: Out << cast<ConstantUInt>(CPV)->getValue() << "u"; break; case Type::ULongTyID: Out << cast<ConstantUInt>(CPV)->getValue() << "ull"; break; case Type::FloatTyID: case Type::DoubleTyID: { ConstantFP *FPC = cast<ConstantFP>(CPV); std::map<const ConstantFP*, unsigned>::iterator I = FPConstantMap.find(FPC); if (I != FPConstantMap.end()) { // Because of FP precision problems we must load from a stack allocated // value that holds the value in hex. Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double") << "*)&FPConstant" << I->second << ")"; } else { std::string Num;//#if HAVE_PRINTF_A// Will have to deal with this later. It prints the floats in p style notation.// So, for now, force it to print the floats in decimal.#if HAVE_PRINTF_A_NOT // Print out the constant as a floating point number. char Buffer[100]; sprintf(Buffer, "%a", FPC->getValue()); Num = Buffer;#else Num = ftostr(FPC->getValue());#endif if (IsNAN(FPC->getValue())) { // The value is NaN if (FPC->getType() == Type::FloatTy) Out << "LLVM_NANF(\"0\") /*nan*/ "; else Out << "LLVM_NAN(\"0\") /*nan*/ "; } else if (IsInf(FPC->getValue())) { // The value is Inf if (FPC->getValue() < 0) Out << "-"; if (FPC->getType() == Type::FloatTy) Out << "LLVM_INFF /*inf*/ "; else Out << "LLVM_INF /*inf*/ "; } else { Out << Num; } } break; } case Type::ArrayTyID: if (isa<ConstantAggregateZero>(CPV)) { const ArrayType *AT = cast<ArrayType>(CPV->getType()); Out << "{"; if (AT->getNumElements()) { Out << " "; Constant *CZ = Constant::getNullValue(AT->getElementType()); printConstant(CZ); for (unsigned i = 1, e = AT->getNumElements(); i != e; ++i) { Out << ", "; printConstant(CZ); } } Out << " }"; } else { printConstantArray(cast<ConstantArray>(CPV)); } break; case Type::StructTyID: if (isa<ConstantAggregateZero>(CPV)) { const StructType *ST = cast<StructType>(CPV->getType()); Out << "{"; if (ST->getNumElements()) { Out << " "; printConstant(Constant::getNullValue(ST->getElementType(0))); for (unsigned i = 1, e = ST->getNumElements(); i != e; ++i) { Out << ", "; printConstant(Constant::getNullValue(ST->getElementType(i))); } } Out << " }"; } else { Out << "{"; if (CPV->getNumOperands()) { Out << " "; printConstant(cast<Constant>(CPV->getOperand(0))); for (unsigned i = 1, e = CPV->getNumOperands(); i != e; ++i) { Out << ", "; printConstant(cast<Constant>(CPV->getOperand(i))); } } Out << " }"; } break; case Type::PointerTyID: if (isa<ConstantPointerNull>(CPV)) { Out << "(("; printType(Out, CPV->getType()); Out << ")/*NULL*/0)"; break; } else if (GlobalValue *GV = dyn_cast<GlobalValue>(CPV)) { writeOperand(GV); break; } // FALL THROUGH default: std::cerr << "Unknown constant type: " << *CPV << "\n"; abort(); }}void VWriter::writeOperandInternal(Value *Operand) { if (Instruction *I = dyn_cast<Instruction>(Operand)) if (isInlinableInst(*I) && !isDirectAlloca(I)) { // Should we inline this instruction to build a tree? Out << "("; visit(*I); Out << ")"; return; } Constant* CPV = dyn_cast<Constant>(Operand); if (CPV && !isa<GlobalValue>(CPV)) { printConstant(CPV); } else { Out << Mang->getValueName(Operand); }}void VWriter::writeOperand(Value *Operand) { if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand)) Out << "(&"; // Global variables are references as their addresses by llvm writeOperandInternal(Operand); if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand)) Out << ")";}bool VWriter::doInitialization(Module &M) { // Initialize TheModule = &M; IL.AddPrototypes(M); // ensure that all structure types have names Mang = new Mangler(M); // get declaration for alloca Out << "; Float Compiler Intermediate Format\n"; Out << ";\n"; Out << "; IR Format v0.4\n"; Out << ";\n"; //Out << "\n; Global Declarations ?? Need any ?\n"; // First output all the declarations for the program, because C requires // Functions & globals to be declared before they are used. // //Out << "; Symbol table \n"; // Loop over the symbol table, emitting all named constants... printModuleTypes(M.getSymbolTable()); // Global variable declarations... if (!M.global_empty()) { Out << "\n; External Variables\n"; for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (I->hasExternalLinkage() && I->isExternal()) { // Change to EXT after Christine has change the parser. Out << " EXT VAR "; //Out << " VAR "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); Out << "\n"; } } } // Function declarations //if (!M.empty()) { // Out << "\n/* Function Declarations */\n"; // for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { // // Don't print declarations for intrinsic functions. // if (!I->getIntrinsicID()) { // printFunctionSignature(I, true); // if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; // if (I->hasLinkOnceLinkage()) Out << " __ATTRIBUTE_WEAK__"; // Out << ";\n"; // } // } //} // Output the global variable declarations //if (!M.gempty()) { // Out << "\n\n; Global Variable Declarations \n"; // for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) // if (!I->isExternal()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -