From 28402f534aadfee50436e0cdf62044aa924c9300 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 22 Apr 2021 10:27:39 -0700 Subject: [PATCH] emitting linkable object code --- compiler.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/compiler.c b/compiler.c index 6c482ae..9c02612 100644 --- a/compiler.c +++ b/compiler.c @@ -11,6 +11,7 @@ #include #include #include +#include #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);