SymbolicValue SymbolicValue::getInteger(const APInt &value, ASTContext &astContext) { // In the common case, we can form an inline representation. unsigned numWords = value.getNumWords(); if (numWords == 1) return getInteger(value.getRawData()[0], value.getBitWidth()); // Copy the integers from the APInt into the bump pointer. auto *words = astContext.Allocate<uint64_t>(numWords).data(); std::uninitialized_copy(value.getRawData(), value.getRawData() + numWords, words); SymbolicValue result; result.representationKind = RK_Integer; result.value.integer = words; result.auxInfo.integerBitwidth = value.getBitWidth(); return result; }
void MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { OutMI.setOpcode(MI->getOpcode()); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); MCOperand MCOp; switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) continue; MCOp = MCOperand::CreateReg(MO.getReg()); break; case MachineOperand::MO_Immediate: MCOp = MCOperand::CreateImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( MO.getMBB()->getSymbol(), Ctx)); break; case MachineOperand::MO_GlobalAddress: MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); break; case MachineOperand::MO_ExternalSymbol: MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); break; case MachineOperand::MO_JumpTableIndex: MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); break; case MachineOperand::MO_ConstantPoolIndex: MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); break; case MachineOperand::MO_BlockAddress: MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); break; case MachineOperand::MO_FPImmediate: { bool ignored; APFloat FVal = MO.getFPImm()->getValueAPF(); FVal.convert(APFloat::IEEEsingle, APFloat::rmTowardZero, &ignored); APInt IVal = FVal.bitcastToAPInt(); uint64_t Val = *IVal.getRawData(); MCOp = MCOperand::CreateImm(Val); break; } case MachineOperand::MO_RegisterMask: continue; } OutMI.addOperand(MCOp); } }
void DwarfExpression::addUnsignedConstant(const APInt &Value) { unsigned Size = Value.getBitWidth(); const uint64_t *Data = Value.getRawData(); // Chop it up into 64-bit pieces, because that's the maximum that // addUnsignedConstant takes. unsigned Offset = 0; while (Offset < Size) { addUnsignedConstant(*Data++); if (Offset == 0 && Size <= 64) break; addOpPiece(std::min(Size-Offset, 64u), Offset); Offset += 64; } }
void APNumericStorage::setIntValue(ASTContext &C, const APInt &Val) { if (hasAllocation()) C.Deallocate(pVal); BitWidth = Val.getBitWidth(); unsigned NumWords = Val.getNumWords(); const uint64_t* Words = Val.getRawData(); if (NumWords > 1) { pVal = new (C) uint64_t[NumWords]; std::copy(Words, Words + NumWords, pVal); } else if (NumWords == 1) VAL = Words[0]; else VAL = 0; }
/** Converts v to mpz_class. Assumes that v is signed */ inline mpz_class toMpz (const APInt &v) { // Based on: // https://llvm.org/svn/llvm-project/polly/trunk/lib/Support/GICHelper.cpp // return v.getSExtValue (); APInt abs; abs = v.isNegative () ? v.abs () : v; const uint64_t *rawdata = abs.getRawData (); unsigned numWords = abs.getNumWords (); // TODO: Check if this is true for all platforms. mpz_class res; mpz_import(res.get_mpz_t (), numWords, 1, sizeof (uint64_t), 0, 0, rawdata); return v.isNegative () ? mpz_class(-res) : res; }
/// addConstantValue - Add constant value entry in variable DIE. bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI, bool Unsigned) { unsigned CIBitWidth = CI->getBitWidth(); if (CIBitWidth <= 64) { unsigned form = 0; switch (CIBitWidth) { case 8: form = dwarf::DW_FORM_data1; break; case 16: form = dwarf::DW_FORM_data2; break; case 32: form = dwarf::DW_FORM_data4; break; case 64: form = dwarf::DW_FORM_data8; break; default: form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata; } if (Unsigned) addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue()); else addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue()); return true; } DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); // Get the raw data form of the large APInt. const APInt Val = CI->getValue(); const char *Ptr = (const char*)Val.getRawData(); int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. bool LittleEndian = Asm->getTargetData().isLittleEndian(); int Incr = (LittleEndian ? 1 : -1); int Start = (LittleEndian ? 0 : NumBytes - 1); int Stop = (LittleEndian ? NumBytes : -1); // Output the constant to DWARF one byte at a time. for (; Start != Stop; Start += Incr) addUInt(Block, 0, dwarf::DW_FORM_data1, (unsigned char)0xFF & Ptr[Start]); addBlock(Die, dwarf::DW_AT_const_value, 0, Block); return true; }
/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting /// from Src into IntVal, which is assumed to be wide enough and to hold zero. static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) { assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!"); uint8_t *Dst = (uint8_t *)IntVal.getRawData(); if (sys::isLittleEndianHost()) // Little-endian host - the destination must be ordered from LSB to MSB. // The source is ordered from LSB to MSB: Do a straight copy. memcpy(Dst, Src, LoadBytes); else { // Big-endian - the destination is an array of 64 bit words ordered from // LSW to MSW. Each word must be ordered from MSB to LSB. The source is // ordered from MSB to LSB: Reverse the word order, but not the bytes in // a word. while (LoadBytes > sizeof(uint64_t)) { LoadBytes -= sizeof(uint64_t); // May not be aligned so use memcpy. memcpy(Dst, Src + LoadBytes, sizeof(uint64_t)); Dst += sizeof(uint64_t); } memcpy(Dst + sizeof(uint64_t) - LoadBytes, Src, LoadBytes); } }
/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst /// with the integer held in IntVal. static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes) { assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!"); uint8_t *Src = (uint8_t *)IntVal.getRawData(); if (sys::isLittleEndianHost()) // Little-endian host - the source is ordered from LSB to MSB. Order the // destination from LSB to MSB: Do a straight copy. memcpy(Dst, Src, StoreBytes); else { // Big-endian host - the source is an array of 64 bit words ordered from // LSW to MSW. Each word is ordered from MSB to LSB. Order the destination // from MSB to LSB: Reverse the word order, but not the bytes in a word. while (StoreBytes > sizeof(uint64_t)) { StoreBytes -= sizeof(uint64_t); // May not be aligned so use memcpy. memcpy(Dst + StoreBytes, Src, sizeof(uint64_t)); Src += sizeof(uint64_t); } memcpy(Dst, Src + sizeof(uint64_t) - StoreBytes, StoreBytes); } }
/// addConstantFPValue - Add constant value entry in variable DIE. bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) { assert (MO.isFPImm() && "Invalid machine operand!"); DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); APFloat FPImm = MO.getFPImm()->getValueAPF(); // Get the raw data form of the floating point. const APInt FltVal = FPImm.bitcastToAPInt(); const char *FltPtr = (const char*)FltVal.getRawData(); int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte. bool LittleEndian = Asm->getTargetData().isLittleEndian(); int Incr = (LittleEndian ? 1 : -1); int Start = (LittleEndian ? 0 : NumBytes - 1); int Stop = (LittleEndian ? NumBytes : -1); // Output the constant to DWARF one byte at a time. for (; Start != Stop; Start += Incr) addUInt(Block, 0, dwarf::DW_FORM_data1, (unsigned char)0xFF & FltPtr[Start]); addBlock(Die, dwarf::DW_AT_const_value, 0, Block); return true; }
void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) { const TargetData *TD = TM.getTargetData(); unsigned Size = TD->getTypeAllocSize(CV->getType()); if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) EmitGlobalConstant(CVA->getOperand(i), GblS); return; } else if (isa<ConstantAggregateZero>(CV)) { GblS.emitZeros(Size); return; } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { EmitGlobalConstantStruct(CVS, GblS); return; } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { APInt Val = CFP->getValueAPF().bitcastToAPInt(); if (CFP->getType()->isDoubleTy()) GblS.emitWord64(Val.getZExtValue()); else if (CFP->getType()->isFloatTy()) GblS.emitWord32(Val.getZExtValue()); else if (CFP->getType()->isX86_FP80Ty()) { unsigned PadSize = TD->getTypeAllocSize(CFP->getType())- TD->getTypeStoreSize(CFP->getType()); GblS.emitWordFP80(Val.getRawData(), PadSize); } else if (CFP->getType()->isPPC_FP128Ty()) llvm_unreachable("PPC_FP128Ty global emission not implemented"); return; } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { if (Size == 1) GblS.emitByte(CI->getZExtValue()); else if (Size == 2) GblS.emitWord16(CI->getZExtValue()); else if (Size == 4) GblS.emitWord32(CI->getZExtValue()); else EmitGlobalConstantLargeInt(CI, GblS); return; } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { const VectorType *PTy = CP->getType(); for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) EmitGlobalConstant(CP->getOperand(I), GblS); return; } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { // Resolve a constant expression which returns a (Constant, Offset) // pair. If 'Res.first' is a GlobalValue, emit a relocation with // the offset 'Res.second', otherwise emit a global constant like // it is always done for not contant expression types. CstExprResTy Res = ResolveConstantExpr(CE); const Constant *Op = Res.first; if (isa<GlobalValue>(Op)) EmitGlobalDataRelocation(cast<const GlobalValue>(Op), TD->getTypeAllocSize(Op->getType()), GblS, Res.second); else EmitGlobalConstant(Op, GblS); return; } else if (CV->getType()->getTypeID() == Type::PointerTyID) { // Fill the data entry with zeros or emit a relocation entry if (isa<ConstantPointerNull>(CV)) GblS.emitZeros(Size); else EmitGlobalDataRelocation(cast<const GlobalValue>(CV), Size, GblS); return; } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { // This is a constant address for a global variable or function and // therefore must be referenced using a relocation entry. EmitGlobalDataRelocation(GV, Size, GblS); return; } std::string msg; raw_string_ostream ErrorMsg(msg); ErrorMsg << "Constant unimp for type: " << *CV->getType(); report_fatal_error(ErrorMsg.str()); }
void LLVM_General_GetConstantFloatWords(LLVMValueRef v, uint64_t *bits) { APInt a = unwrap<ConstantFP>(v)->getValueAPF().bitcastToAPInt(); for(unsigned i=0; i != a.getNumWords(); ++i) bits[i] = a.getRawData()[i]; }