void CVariableDeclaration::CreateWriteAccessor(CodeGenContext& context, BitVariable& var, const std::string& moduleName, const std::string& name, bool impedance) { std::vector<llvm::Type*> argTypes; argTypes.push_back(context.getIntType(var.size)); llvm::FunctionType *ftype = llvm::FunctionType::get(context.getVoidType(), argTypes, false); llvm::Function* function; if (context.isRoot) { function = context.makeFunction(ftype, llvm::GlobalValue::ExternalLinkage, context.moduleName + context.getSymbolPrefix() + "PinSet" + id.name); } else { function = context.makeFunction(ftype, llvm::GlobalValue::PrivateLinkage, context.moduleName + context.getSymbolPrefix() + "PinSet" + id.name); } function->onlyReadsMemory(); // Mark input read only context.StartFunctionDebugInfo(function, declarationLoc); llvm::BasicBlock *bblock = context.makeBasicBlock("entry", function); context.pushBlock(bblock, declarationLoc); llvm::Function::arg_iterator args = function->arg_begin(); llvm::Value* setVal = &*args; setVal->setName("InputVal"); llvm::LoadInst* load = new llvm::LoadInst(var.value, "", false, bblock); if (impedance) { llvm::LoadInst* loadImp = new llvm::LoadInst(var.impedance, "", false, bblock); llvm::CmpInst* check = llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::ICmpInst::ICMP_NE, loadImp, context.getConstantZero(var.size.getLimitedValue()), "impedance", bblock); setVal = llvm::SelectInst::Create(check, setVal, load, "impOrReal", bblock); } llvm::Value* stor = CAssignment::generateAssignmentActual(var, id/*moduleName, name*/, setVal, context, false); // we shouldn't clear impedance on write via pin (instead should ignore write if impedance is set) var.priorValue = load; var.writeInput = setVal; var.writeAccessor = &writeAccessor; writeAccessor = context.makeReturn(bblock); context.popBlock(declarationLoc); context.EndFunctionDebugInfo(); }
void CVariableDeclaration::CreateReadAccessor(CodeGenContext& context, BitVariable& var, bool impedance) { std::vector<llvm::Type*> argTypes; llvm::FunctionType *ftype = llvm::FunctionType::get(context.getIntType(var.size), argTypes, false); llvm::Function* function; if (context.isRoot) { function = context.makeFunction(ftype, llvm::GlobalValue::ExternalLinkage, context.moduleName + context.getSymbolPrefix() + "PinGet" + id.name); } else { function = context.makeFunction(ftype, llvm::GlobalValue::PrivateLinkage, context.moduleName + context.getSymbolPrefix() + "PinGet" + id.name); } function->setOnlyReadsMemory(); context.StartFunctionDebugInfo(function, declarationLoc); llvm::BasicBlock *bblock = context.makeBasicBlock("entry", function); context.pushBlock(bblock, declarationLoc); llvm::Value* load = new llvm::LoadInst(var.value, "", false, bblock); if (impedance) { llvm::LoadInst* loadImp = new llvm::LoadInst(var.impedance, "", false, bblock); llvm::CmpInst* check = llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::ICmpInst::ICMP_EQ, loadImp, context.getConstantZero(var.size.getLimitedValue()), "impedance", bblock); load = llvm::SelectInst::Create(check, load, loadImp, "impOrReal", bblock); } context.makeReturnValue(load, bblock); context.popBlock(declarationLoc); context.EndFunctionDebugInfo(); }