emitting linkable object code

pull/1/head
cosmonaut 2021-04-22 10:27:39 -07:00
parent c2efcbd7d2
commit 28402f534a
1 changed files with 69 additions and 8 deletions

View File

@ -11,6 +11,7 @@
#include <llvm-c/Transforms/Scalar.h>
#include <llvm-c/Transforms/Utils.h>
#include <llvm-c/TargetMachine.h>
#include <llvm-c/Target.h>
#include "y.tab.h"
#include "ast.h"
@ -480,6 +481,7 @@ static uint8_t CompileStatement(LLVMBuilderRef builder, LLVMValueRef function, N
static void CompileFunction(
LLVMModuleRef module,
char *parentStructName,
LLVMTypeRef wStructPointerType,
Node **fieldDeclarations,
uint32_t fieldDeclarationCount,
@ -522,7 +524,12 @@ static void CompileFunction(
LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type);
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0);
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
char *functionName = strdup(parentStructName);
strcat(functionName, "_");
strcat(functionName, functionSignature->children[0]->value.string);
LLVMValueRef function = LLVMAddFunction(module, functionName, functionType);
free(functionName);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
@ -560,6 +567,8 @@ static void CompileFunction(
}
PopScopeFrame(scope);
LLVMDisposeBuilder(builder);
}
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
@ -571,10 +580,11 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
LLVMTypeRef types[declarationCount];
Node *currentDeclarationNode;
Node *fieldDeclarations[declarationCount];
char *structName = node->children[0]->value.string;
PushScopeFrame(scope);
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string);
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, structName);
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
/* first, build the structure definition */
@ -604,7 +614,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
switch (currentDeclarationNode->syntaxKind)
{
case FunctionDeclaration:
CompileFunction(module, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode);
CompileFunction(module, structName, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode);
break;
}
}
@ -659,13 +669,46 @@ int main(int argc, char *argv[])
Compile(module, context, rootNode);
/* add main call */
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMTypeRef mainFunctionType = LLVMFunctionType(LLVMInt64Type(), NULL, 0, 0);
LLVMValueRef mainFunction = LLVMAddFunction(module, "main", mainFunctionType);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(mainFunction, "entry");
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef wraithMainFunction = LLVMGetNamedFunction(module, "Program_Main");
LLVMValueRef mainResult = LLVMBuildCall(builder, wraithMainFunction, NULL, 0, "result");
LLVMBuildRet(builder, mainResult);
LLVMDisposeBuilder(builder);
/* verify */
char *error = NULL;
LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
/* prepare to emit assembly */
LLVMInitializeNativeTarget();
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargets();
LLVMInitializeAllTargetMCs();
LLVMInitializeAllAsmParsers();
LLVMInitializeAllAsmPrinters();
LLVMSetTarget(module, LLVM_DEFAULT_TARGET_TRIPLE);
LLVMTargetRef target;
if (LLVMGetTargetFromTriple(LLVM_DEFAULT_TARGET_TRIPLE, &target, &error) != 0)
{
fprintf(stderr, "Failed to get target!\n");
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
return 1;
}
LLVMPassManagerRef passManager = LLVMCreatePassManager();
LLVMAddInstructionCombiningPass(passManager);
//LLVMAddInstructionCombiningPass(passManager);
LLVMAddCFGSimplificationPass(passManager);
LLVMAddReassociatePass(passManager);
LLVMAddPromoteMemoryToRegisterPass(passManager);
@ -680,11 +723,29 @@ int main(int argc, char *argv[])
fprintf(stderr, "error writing bitcode to file\n");
}
LLVMMemoryBufferRef memoryBuffer = LLVMWriteBitcodeToMemoryBuffer(module);
LLVMCreateBinary(memoryBuffer, context, &error);
LLVMDisposeMessage(error);
LLVMDisposeMemoryBuffer(memoryBuffer);
char *cpu = "generic";
char *features = "";
LLVMTargetMachineRef targetMachine = LLVMCreateTargetMachine(
target,
LLVM_DEFAULT_TARGET_TRIPLE,
cpu,
features,
LLVMCodeGenLevelDefault,
LLVMRelocDefault,
LLVMCodeModelDefault
);
if (LLVMTargetMachineEmitToFile(targetMachine, module, "test.o", LLVMObjectFile, &error) != 0)
{
fprintf(stderr, "Failed to emit machine code!\n");
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
return 1;
}
LLVMDisposeMessage(error);
LLVMDisposeTargetMachine(targetMachine);
LLVMPassManagerBuilderDispose(passManagerBuilder);
LLVMDisposePassManager(passManager);
LLVMDisposeModule(module);