diff --git a/src/backends/llvm.c b/src/backends/llvm.c index 9915c38b9f41ee6cb3d0a3c4f130adb7f5887942..7d559c07572b231fa507b9452aa8b88af01e04af 100644 --- a/src/backends/llvm.c +++ b/src/backends/llvm.c @@ -17,9 +17,26 @@ typedef struct HLLVMParser_ { void h_llvm_declare_common(LLVMModuleRef mod) { llvm_inputstream = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HInputStream_"), 0); - llvm_arena = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HArena_"), 0); - llvm_parsedtoken = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParsedToken_"), 0); - llvm_parseresult = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParseResult_"), 0); + llvm_arena = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HArena_"); + llvm_arenaptr = LLVMPointerType(llvm_arena, 0); + llvm_parsedtoken = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParsedToken_"); + LLVMTypeRef llvm_parsedtoken_struct_types[] = { + LLVMInt32Type(), // actually an enum value + LLVMInt64Type(), // actually this is a union; the largest thing in it is 64 bits + LLVMInt64Type(), // FIXME sizeof(size_t) will be 32 bits on 32-bit platforms + LLVMInt64Type(), // FIXME ditto + LLVMInt8Type() + }; + LLVMStructSetBody(llvm_parsedtoken, llvm_parsedtoken_struct_types, 5, 0); + llvm_parsedtokenptr = LLVMPointerType(llvm_parsedtoken, 0); + llvm_parseresult = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParseResult_"); + LLVMTypeRef llvm_parseresult_struct_types[] = { + llvm_parsedtokenptr, + LLVMInt64Type(), + llvm_arenaptr + }; + LLVMStructSetBody(llvm_parseresult, llvm_parseresult_struct_types, 3, 0); + llvm_parseresultptr = LLVMPointerType(llvm_parseresult, 0); LLVMTypeRef readbits_pt[] = { llvm_inputstream, LLVMInt32Type(), @@ -37,9 +54,9 @@ void h_llvm_declare_common(LLVMModuleRef mod) { LLVMTypeRef makeresult_pt[] = { llvm_arena, - llvm_parsedtoken + llvm_parsedtokenptr }; - LLVMTypeRef makeresult_ret = LLVMFunctionType(llvm_parseresult, makeresult_pt, 2, 0); + LLVMTypeRef makeresult_ret = LLVMFunctionType(llvm_parseresultptr, makeresult_pt, 2, 0); LLVMAddFunction(mod, "make_result", makeresult_ret); char* dump = LLVMPrintModuleToString(mod); fprintf(stderr, "\n\n%s\n\n", dump); @@ -56,7 +73,7 @@ int h_llvm_compile(HAllocator* mm__, HParser* parser, const void* params) { llvm_inputstream, llvm_arena }; - LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresult, param_types, 2, 0); + LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresultptr, param_types, 2, 0); LLVMValueRef parse_func = LLVMAddFunction(mod, name, ret_type); // Parse function is now declared; time to define itt LLVMBuilderRef builder = LLVMCreateBuilder(); diff --git a/src/llvm.h b/src/llvm.h index b37036df585cb8a2450736d11896b2b5f1e9c786..8d9c2dbd74ef371ef6d16f4fcb3d14c025dab7b9 100644 --- a/src/llvm.h +++ b/src/llvm.h @@ -6,6 +6,7 @@ #include <llvm-c/Core.h> #pragma GCC diagnostic pop -LLVMTypeRef llvm_inputstream, llvm_arena, llvm_parsedtoken, llvm_parseresult; +LLVMTypeRef llvm_inputstream, llvm_arena, llvm_arenaptr, llvm_parsedtoken, llvm_parsedtokenptr; +LLVMTypeRef llvm_parseresult, llvm_parseresultptr; #endif // #ifndef HAMMER_LLVM__H diff --git a/src/parsers/ch.c b/src/parsers/ch.c index e49757911e14a1ad6ba3c0d022e233b571bbffd2..5b9dbdfcd0118a0fda7e38bc9aa20fc5492cd97a 100644 --- a/src/parsers/ch.c +++ b/src/parsers/ch.c @@ -53,7 +53,7 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) { llvm_inputstream, llvm_arena }; - LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresult, param_types, 2, 0); + LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresultptr, param_types, 2, 0); LLVMValueRef ch = LLVMAddFunction(mod, "ch", ret_type); // get the parameter array to use later with h_bits LLVMValueRef bits_args[3]; @@ -67,10 +67,10 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) { LLVMBasicBlockRef end = LLVMAppendBasicBlock(ch, "ch_end"); LLVMPositionBuilderAtEnd(builder, entry); // %1 = alloca %struct.HParseResult_*, align 8 - LLVMValueRef ret = LLVMBuildAlloca(builder, llvm_parseresult, "ret"); + LLVMValueRef ret = LLVMBuildAlloca(builder, llvm_parseresultptr, "ret"); // skip %2 through %c because we have these from arguments, and %r because we'll get it later // %tok = alloca %struct.HParsedToken_*, align 8 - LLVMValueRef tok = LLVMBuildAlloca(builder, llvm_parsedtoken, "tok"); + // LLVMValueRef tok = LLVMBuildAlloca(builder, llvm_parsedtokenptr, "tok"); // skip next instr through %8 // %9 = call i64 @h_read_bits(%struct.HInputStream_* %8, i32 8, i8 signext 0) LLVMValueRef bits = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "h_read_bits"), bits_args, 3, "h_read_bits"); @@ -93,9 +93,11 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) { // %20 = call noalias i8* @h_arena_malloc(%struct.HArena_* %19, i64 48) LLVMValueRef amalloc = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "h_arena_malloc"), amalloc_args, 2, "h_arena_malloc"); // %21 = bitcast i8* %20 to %struct.HParsedToken_* - LLVMValueRef cast1 = LLVMBuildBitCast(builder, amalloc, llvm_parsedtoken, ""); + LLVMValueRef tok = LLVMBuildBitCast(builder, amalloc, llvm_parsedtokenptr, ""); + // store %struct.HParsedToken_* %21, %struct.HParsedToken_** %tok, align 8 - LLVMBuildStore(builder, cast1, tok); + // LLVMBuildStore(builder, cast1, tok); + // %22 = load %struct.HParsedToken_** %tok, align 8 // %23 = getelementptr inbounds %struct.HParsedToken_* %22, i32 0, i32 0 LLVMValueRef bounds1[] = { @@ -123,23 +125,24 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) { // %33 = call %struct.HParseResult_* @make_result(%struct.HArena_* %31, %struct.HParsedToken_* %32) LLVMValueRef result_args[] = { arena, tok }; LLVMValueRef mr = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "make_result"), result_args, 2, "make_result"); - // store %struct.HParseResult_* %33, %struct.HParseResult_** %1 + // store %struct.HParseResult_* %33, %struct.HParseResult_** %ret LLVMBuildStore(builder, mr, ret); // br label %35 LLVMBuildBr(builder, end); // ; <label>:34 - failure case LLVMPositionBuilderAtEnd(builder, fail); - // store %struct.HParseResult* null, %struct.HParseResult_** %1 - LLVMBuildStore(builder, LLVMConstNull(llvm_parseresult), ret); + // store %struct.HParseResult* null, %struct.HParseResult_** %ret + LLVMBuildStore(builder, LLVMConstNull(llvm_parseresultptr), ret); // br label %35 LLVMBuildBr(builder, end); // ; <label>:35 LLVMPositionBuilderAtEnd(builder, end); - // %36 = load %struct.HParseResult_** %1 - // ret %struct.HParseResult_* %36 - LLVMBuildRet(builder, ret); + // %rv = load %struct.HParseResult_** %ret + LLVMValueRef rv = LLVMBuildLoad(builder, ret, "rv"); + // ret %struct.HParseResult_* %rv + LLVMBuildRet(builder, rv); return true; }