Build raw function

This commit is contained in:
Rafał Grodziński
2025-07-13 15:06:52 +09:00
parent 26c566f4f6
commit 228dd80423
4 changed files with 35 additions and 20 deletions

View File

@@ -131,8 +131,11 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> state
}
void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> statement) {
llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), nullptr, false);
llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "", false, false, llvm::InlineAsm::AsmDialect::AD_Intel);
// get argument types
vector<llvm::Type *> types;
llvm::FunctionType *funType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), types, false);
llvm::InlineAsm *rawFun = llvm::InlineAsm::get(funType, statement->getRawSource(), "~{ebx}", false, false, llvm::InlineAsm::AsmDialect::AD_Intel);
if (!setRawFun(statement->getName(), rawFun))
return;
@@ -508,15 +511,24 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expressio
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
llvm::Function *fun = getFun(expression->getName());
if (fun == nullptr)
return nullptr;
llvm::FunctionType *funType = fun->getFunctionType();
vector<llvm::Value*> argValues;
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
llvm::Value *argValue = valueForExpression(argumentExpression);
argValues.push_back(argValue);
if (fun != nullptr) {
llvm::FunctionType *funType = fun->getFunctionType();
vector<llvm::Value*> argValues;
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
llvm::Value *argValue = valueForExpression(argumentExpression);
argValues.push_back(argValue);
}
return builder->CreateCall(funType, fun, llvm::ArrayRef(argValues));
}
return builder->CreateCall(funType, fun, llvm::ArrayRef(argValues));
llvm::InlineAsm *rawFun = getRawFun(expression->getName());
if (rawFun != nullptr) {
vector<llvm::Value *>argValues;
return builder->CreateCall(rawFun, llvm::ArrayRef(argValues));
}
markError(0, 0, format("Function \"{}\" not defined in scope", expression->getName()));
return nullptr;
}
bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) {
@@ -563,11 +575,10 @@ llvm::Function* ModuleBuilder::getFun(string name) {
scopes.pop();
}
markError(0, 0, format("Function \"{}\" not defined in scope", name));
return nullptr;
}
bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) {
bool ModuleBuilder::setRawFun(string name, llvm::InlineAsm *rawFun) {
if (scopes.top().rawFunMap[name] != nullptr) {
markError(0, 0, format("Raw function \"{}\" already defined in scope", name));
return false;
@@ -577,17 +588,16 @@ bool ModuleBuilder::setRawFun(string name, llvm::Value *rawFun) {
return true;
}
llvm::Value *ModuleBuilder::getRawFun(string name) {
llvm::InlineAsm *ModuleBuilder::getRawFun(string name) {
stack<Scope> scopes = this->scopes;
while (!scopes.empty()) {
llvm::Value *rawFun = scopes.top().rawFunMap[name];
llvm::InlineAsm *rawFun = scopes.top().rawFunMap[name];
if (rawFun != nullptr)
return rawFun;
scopes.pop();
}
markError(0, 0, format("Raw function \"{}\" not defined in scope", name));
return nullptr;
}