| 1767 | |
| 1768 | |
| 1769 | llvm::Value* BfIRCodeGen::DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm) |
| 1770 | { |
| 1771 | if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64)) |
| 1772 | useAsm = false; |
| 1773 | |
| 1774 | CmdParamVec<llvm::Type*> useParams; |
| 1775 | useParams.push_back(lhs->getType()); |
| 1776 | auto func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrin, useParams); |
| 1777 | |
| 1778 | CmdParamVec<llvm::Value*> args; |
| 1779 | args.push_back(lhs); |
| 1780 | args.push_back(rhs); |
| 1781 | llvm::FunctionType* funcType = func->getFunctionType(); |
| 1782 | |
| 1783 | auto aggResult = mIRBuilder->CreateCall(funcType, func, args); |
| 1784 | auto valResult = mIRBuilder->CreateExtractValue(aggResult, 0); |
| 1785 | auto failResult = mIRBuilder->CreateExtractValue(aggResult, 1); |
| 1786 | |
| 1787 | if (!useAsm) |
| 1788 | { |
| 1789 | mLockedBlocks.Add(mIRBuilder->GetInsertBlock()); |
| 1790 | |
| 1791 | auto failBB = llvm::BasicBlock::Create(*mLLVMContext, "access.fail"); |
| 1792 | auto passBB = llvm::BasicBlock::Create(*mLLVMContext, "access.pass"); |
| 1793 | |
| 1794 | mIRBuilder->CreateCondBr(failResult, failBB, passBB); |
| 1795 | |
| 1796 | mActiveFunction->insert(mActiveFunction->end(), failBB); |
| 1797 | mIRBuilder->SetInsertPoint(failBB); |
| 1798 | |
| 1799 | auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap); |
| 1800 | auto callInst = mIRBuilder->CreateCall(trapDecl); |
| 1801 | callInst->addFnAttr(llvm::Attribute::NoReturn); |
| 1802 | mIRBuilder->CreateBr(passBB); |
| 1803 | |
| 1804 | mActiveFunction->insert(mActiveFunction->end(), passBB); |
| 1805 | mIRBuilder->SetInsertPoint(passBB); |
| 1806 | } |
| 1807 | else |
| 1808 | { |
| 1809 | if (mOverflowCheckAsm == NULL) |
| 1810 | { |
| 1811 | std::vector<llvm::Type*> paramTypes; |
| 1812 | paramTypes.push_back(llvm::Type::getInt8Ty(*mLLVMContext)); |
| 1813 | auto funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false); |
| 1814 | |
| 1815 | String asmStr = |
| 1816 | "testb $$1, $0\n" |
| 1817 | "jz 1f\n" |
| 1818 | "int $$3\n" |
| 1819 | "1:"; |
| 1820 | |
| 1821 | mOverflowCheckAsm = llvm::InlineAsm::get(funcType, |
| 1822 | asmStr.c_str(), "r,~{dirflag},~{fpsr},~{flags}", true, |
| 1823 | false, llvm::InlineAsm::AD_ATT); |
| 1824 | } |
| 1825 | |
| 1826 | llvm::SmallVector<llvm::Value*, 1> llvmArgs; |
nothing calls this directly
no test coverage detected