From af301180802a5c9ae23a5fef2f87c7f4f226ce04 Mon Sep 17 00:00:00 2001 From: Andrea Shepard <andrea@persephoneslair.org> Date: Sat, 12 Nov 2016 02:35:37 +0000 Subject: [PATCH] Move TT_UINT token construction LLVM into reusable function from ch_llvm() --- src/backends/llvm.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/llvm.h | 4 +++ src/parsers/ch.c | 39 ++--------------------- 3 files changed, 84 insertions(+), 36 deletions(-) diff --git a/src/backends/llvm.c b/src/backends/llvm.c index 1c422591..edbe3ebb 100644 --- a/src/backends/llvm.c +++ b/src/backends/llvm.c @@ -145,6 +145,83 @@ void h_llvm_free(HParser *parser) { llvm_parser->mod = NULL; } +/* + * Construct LLVM IR to allocate a token of type TT_SINT or TT_UINT + * + * Parameters: + * - mod [in]: an LLVMModuleRef + * - builder [in]: an LLVMBuilderRef, positioned appropriately + * - stream [in]: a value ref to an llvm_inputstreamptr, for the input stream + * - arena [in]: a value ref to an llvm_arenaptr to be used for the malloc + * - r [in]: a value ref to the value to be used to this token + * - mr_out [out]: the return value from make_result() + * + * TODO actually support TT_SINT, inputs other than 8 bit + */ + +void h_llvm_make_tt_suint(LLVMModuleRef mod, LLVMBuilderRef builder, + LLVMValueRef stream, LLVMValueRef arena, + LLVMValueRef r, LLVMValueRef *mr_out) { + /* Set up call to h_arena_malloc() for a new HParsedToken */ + LLVMValueRef tok_size = LLVMConstInt(LLVMInt32Type(), sizeof(HParsedToken), 0); + LLVMValueRef amalloc_args[] = { arena, tok_size }; + /* %h_arena_malloc = call void* @h_arena_malloc(%struct.HArena_.1* %1, i32 48) */ + LLVMValueRef amalloc = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "h_arena_malloc"), + amalloc_args, 2, "h_arena_malloc"); + /* %tok = bitcast void* %h_arena_malloc to %struct.HParsedToken_.2* */ + LLVMValueRef tok = LLVMBuildBitCast(builder, amalloc, llvm_parsedtokenptr, "tok"); + + /* + * tok->token_type = TT_UINT; + * + * %token_type = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 0 + * + * TODO if we handle TT_SINT too, adjust here and the zero-ext below + */ + LLVMValueRef toktype = LLVMBuildStructGEP(builder, tok, 0, "token_type"); + /* store i32 8, i32* %token_type */ + LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 8, 0), toktype); + + /* + * tok->uint = r; + * + * %token_data = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 1 + */ + LLVMValueRef tokdata = LLVMBuildStructGEP(builder, tok, 1, "token_data"); + /* + * TODO + * + * This is where we'll need to adjust to handle other types (sign vs. zero extend, omit extend if + * r is 64-bit already + */ + LLVMBuildStore(builder, LLVMBuildZExt(builder, r, LLVMInt64Type(), "r"), tokdata); + /* + * Store the index from the stream into the token + */ + /* %t_index = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 2 */ + LLVMValueRef tokindex = LLVMBuildStructGEP(builder, tok, 2, "t_index"); + /* %s_index = getelementptr inbounds %struct.HInputStream_.0, %struct.HInputStream_.0* %0, i32 0, i32 2 */ + LLVMValueRef streamindex = LLVMBuildStructGEP(builder, stream, 2, "s_index"); + /* %4 = load i64, i64* %s_index */ + /* store i64 %4, i64* %t_index */ + LLVMBuildStore(builder, LLVMBuildLoad(builder, streamindex, ""), tokindex); + /* Store the bit length into the token */ + LLVMValueRef tokbitlen = LLVMBuildStructGEP(builder, tok, 3, "bit_length"); + /* TODO handle multiple bit lengths */ + LLVMBuildStore(builder, LLVMConstInt(LLVMInt64Type(), 8, 0), tokbitlen); + + /* + * Now call make_result() + * + * %make_result = call %struct.HParseResult_.3* @make_result(%struct.HArena_.1* %1, %struct.HParsedToken_.2* %3) + */ + LLVMValueRef result_args[] = { arena, tok }; + LLVMValueRef mr = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "make_result"), + result_args, 2, "make_result"); + + *mr_out = mr; +} + HParseResult *h_llvm_parse(HAllocator* mm__, const HParser* parser, HInputStream *input_stream) { const HLLVMParser *llvm_parser = parser->backend_data; HArena *arena = h_new_arena(mm__, 0); diff --git a/src/llvm.h b/src/llvm.h index 3b6c7ed5..927241f7 100644 --- a/src/llvm.h +++ b/src/llvm.h @@ -9,4 +9,8 @@ LLVMTypeRef llvm_inputstream, llvm_inputstreamptr, llvm_arena, llvm_arenaptr; LLVMTypeRef llvm_parsedtoken, llvm_parsedtokenptr, llvm_parseresult, llvm_parseresultptr; +void h_llvm_make_tt_suint(LLVMModuleRef mod, LLVMBuilderRef builder, + LLVMValueRef stream, LLVMValueRef arena, + LLVMValueRef r, LLVMValueRef *mr_out); + #endif // #ifndef HAMMER_LLVM__H diff --git a/src/parsers/ch.c b/src/parsers/ch.c index a7ac9bec..1c396a2f 100644 --- a/src/parsers/ch.c +++ b/src/parsers/ch.c @@ -85,42 +85,9 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMValueRef func, LLVMModuleRef mod // Basic block: success LLVMPositionBuilderAtEnd(builder, success); - // Set up call to h_arena_malloc() for a new HParsedToken - LLVMValueRef tok_size = LLVMConstInt(LLVMInt32Type(), sizeof(HParsedToken), 0); - LLVMValueRef amalloc_args[] = { arena, tok_size }; - // %h_arena_malloc = call void* @h_arena_malloc(%struct.HArena_.1* %1, i32 48) - LLVMValueRef amalloc = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "h_arena_malloc"), amalloc_args, 2, "h_arena_malloc"); - // %3 = bitcast void* %h_arena_malloc to %struct.HParsedToken_.2* - LLVMValueRef tok = LLVMBuildBitCast(builder, amalloc, llvm_parsedtokenptr, ""); - - // tok->token_type = TT_UINT; - // - // %token_type = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 0 - LLVMValueRef toktype = LLVMBuildStructGEP(builder, tok, 0, "token_type"); - // store i32 8, i32* %token_type - LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 8, 0), toktype); - - // tok->uint = r; - // - // %token_data = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 1 - LLVMValueRef tokdata = LLVMBuildStructGEP(builder, tok, 1, "token_data"); - // %r = zext i8 %2 to i64 - // store i64 %r, i64* %token_data - LLVMBuildStore(builder, LLVMBuildZExt(builder, r, LLVMInt64Type(), "r"), tokdata); - // %t_index = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 2 - LLVMValueRef tokindex = LLVMBuildStructGEP(builder, tok, 2, "t_index"); - // %s_index = getelementptr inbounds %struct.HInputStream_.0, %struct.HInputStream_.0* %0, i32 0, i32 2 - LLVMValueRef streamindex = LLVMBuildStructGEP(builder, stream, 2, "s_index"); - // %4 = load i64, i64* %s_index - // store i64 %4, i64* %t_index - LLVMBuildStore(builder, LLVMBuildLoad(builder, streamindex, ""), tokindex); - LLVMValueRef tokbitlen = LLVMBuildStructGEP(builder, tok, 3, "bit_length"); - LLVMBuildStore(builder, LLVMConstInt(LLVMInt64Type(), 8, 0), tokbitlen); - - // Now call make_result() - // %make_result = call %struct.HParseResult_.3* @make_result(%struct.HArena_.1* %1, %struct.HParsedToken_.2* %3) - LLVMValueRef result_args[] = { arena, tok }; - LLVMValueRef mr = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "make_result"), result_args, 2, "make_result"); + /* Make a token */ + LLVMValueRef mr; + h_llvm_make_tt_suint(mod, builder, stream, arena, r, &mr); // br label %ch_end LLVMBuildBr(builder, end); -- GitLab