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 createEchoFunction(CodeGenContext& context, llvm::Function* printfFn) { std::vector<llvm::Type*> echo_arg_types; echo_arg_types.push_back(llvm::Type::getInt64Ty(getGlobalContext())); llvm::FunctionType* echo_type = llvm::FunctionType::get( llvm::Type::getVoidTy(getGlobalContext()), echo_arg_types, false); llvm::Function *func = llvm::Function::Create( echo_type, llvm::Function::InternalLinkage, llvm::Twine("echo"), context.module ); llvm::BasicBlock *bblock = llvm::BasicBlock::Create(getGlobalContext(), "entry", func, 0); context.pushBlock(bblock); const char *constValue = "%d\n"; llvm::Constant *format_const = llvm::ConstantDataArray::getString(getGlobalContext(), constValue); llvm::GlobalVariable *var = new llvm::GlobalVariable( *context.module, llvm::ArrayType::get(llvm::IntegerType::get(getGlobalContext(), 8), strlen(constValue)+1), true, llvm::GlobalValue::PrivateLinkage, format_const, ".str"); llvm::Constant *zero = llvm::Constant::getNullValue(llvm::IntegerType::getInt32Ty(getGlobalContext())); std::vector<llvm::Constant*> indices; indices.push_back(zero); indices.push_back(zero); llvm::Constant *var_ref = llvm::ConstantExpr::getGetElementPtr( llvm::ArrayType::get(llvm::IntegerType::get(getGlobalContext(), 8), strlen(constValue+1)), var, indices); std::vector<Value*> args; args.push_back(var_ref); Function::arg_iterator argsValues = func->arg_begin(); Value* toPrint = argsValues++; toPrint->setName("toPrint"); args.push_back(toPrint); CallInst *call = CallInst::Create(printfFn, makeArrayRef(args), "", bblock); ReturnInst::Create(getGlobalContext(), bblock); context.popBlock(); }
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(); }