From b1c26eb74ed82550708926f27b01ba3512b9580d Mon Sep 17 00:00:00 2001 From: Andrea Shepard <andrea@persephoneslair.org> Date: Wed, 23 Nov 2016 06:27:21 +0000 Subject: [PATCH] Make h_llvm_make_tt_suint support variable bit lengths and signed/unsigned distinction --- src/backends/llvm/llvm.h | 1 + src/backends/llvm/llvm_suint.c | 29 ++++++++++++++++++----------- src/parsers/ch.c | 2 +- src/parsers/charset.c | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/backends/llvm/llvm.h b/src/backends/llvm/llvm.h index 900f53ff..0721c373 100644 --- a/src/backends/llvm/llvm.h +++ b/src/backends/llvm/llvm.h @@ -37,6 +37,7 @@ bool h_llvm_make_charset_membership_test(HLLVMParserCompileContext *ctxt, LLVMValueRef r, HCharset cs, LLVMBasicBlockRef yes, LLVMBasicBlockRef no); void h_llvm_make_tt_suint(HLLVMParserCompileContext *ctxt, + uint8_t length, uint8_t signedp, LLVMValueRef r, LLVMValueRef *mr_out); #endif // #ifndef HAMMER_LLVM__H diff --git a/src/backends/llvm/llvm_suint.c b/src/backends/llvm/llvm_suint.c index 0cce9a3e..571d6b00 100644 --- a/src/backends/llvm/llvm_suint.c +++ b/src/backends/llvm/llvm_suint.c @@ -24,6 +24,7 @@ */ void h_llvm_make_tt_suint(HLLVMParserCompileContext *ctxt, + uint8_t length, uint8_t signedp, LLVMValueRef r, LLVMValueRef *mr_out) { /* Set up call to h_arena_malloc() for a new HParsedToken */ LLVMValueRef tok_size = LLVMConstInt(LLVMInt32Type(), sizeof(HParsedToken), 0); @@ -36,29 +37,36 @@ void h_llvm_make_tt_suint(HLLVMParserCompileContext *ctxt, LLVMValueRef tok = LLVMBuildBitCast(ctxt->builder, amalloc, ctxt->llvm_parsedtokenptr, "tok"); /* - * tok->token_type = TT_UINT; + * tok->token_type = signedp ? TT_SINT : 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(ctxt->builder, tok, 0, "token_type"); /* store i32 8, i32* %token_type */ - LLVMBuildStore(ctxt->builder, LLVMConstInt(LLVMInt32Type(), 8, 0), toktype); + LLVMBuildStore(ctxt->builder, LLVMConstInt(LLVMInt32Type(), + signedp ? TT_SINT : TT_UINT, 0), toktype); /* + * tok->sint = r; + * or * tok->uint = r; * * %token_data = getelementptr inbounds %struct.HParsedToken_.2, %struct.HParsedToken_.2* %3, i32 0, i32 1 */ LLVMValueRef tokdata = LLVMBuildStructGEP(ctxt->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 + * the token_data field is a union, but either an int64_t or a uint64_t in the + * cases we can be called for. */ - LLVMBuildStore(ctxt->builder, LLVMBuildZExt(ctxt->builder, r, LLVMInt64Type(), "r"), tokdata); + if (length < 64) { + /* Extend needed */ + LLVMValueRef r_ext; + if (signedp) r_ext = LLVMBuildSExt(ctxt->builder, r, LLVMInt64Type(), "r_sext"); + else r_ext = LLVMBuildZExt(ctxt->builder, r, LLVMInt64Type(), "r_zext"); + LLVMBuildStore(ctxt->builder, r_ext, tokdata); + } else { + LLVMBuildStore(ctxt->builder, r, tokdata); + } /* * Store the index from the stream into the token */ @@ -71,8 +79,7 @@ void h_llvm_make_tt_suint(HLLVMParserCompileContext *ctxt, LLVMBuildStore(ctxt->builder, LLVMBuildLoad(ctxt->builder, streamindex, ""), tokindex); /* Store the bit length into the token */ LLVMValueRef tokbitlen = LLVMBuildStructGEP(ctxt->builder, tok, 3, "bit_length"); - /* TODO handle multiple bit lengths */ - LLVMBuildStore(ctxt->builder, LLVMConstInt(LLVMInt64Type(), 8, 0), tokbitlen); + LLVMBuildStore(ctxt->builder, LLVMConstInt(LLVMInt64Type(), length, 0), tokbitlen); /* * Now call make_result() diff --git a/src/parsers/ch.c b/src/parsers/ch.c index 2a46ae16..e22ed8c1 100644 --- a/src/parsers/ch.c +++ b/src/parsers/ch.c @@ -91,7 +91,7 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt, void* env) { /* Make a token */ LLVMValueRef mr; - h_llvm_make_tt_suint(ctxt, r, &mr); + h_llvm_make_tt_suint(ctxt, 8, 0, r, &mr); // br label %ch_end LLVMBuildBr(ctxt->builder, end); diff --git a/src/parsers/charset.c b/src/parsers/charset.c index 08b45f28..907fe927 100644 --- a/src/parsers/charset.c +++ b/src/parsers/charset.c @@ -116,7 +116,7 @@ static bool cs_llvm(HLLVMParserCompileContext *ctxt, void* env) { LLVMPositionBuilderAtEnd(ctxt->builder, success); LLVMValueRef mr; - h_llvm_make_tt_suint(ctxt, r, &mr); + h_llvm_make_tt_suint(ctxt, 8, 0, r, &mr); /* br label %ch_end */ LLVMBuildBr(ctxt->builder, end); -- GitLab