예제 #1
0
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();
}
예제 #2
0
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();
}