diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-06-18 15:17:14 +0200 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-06-18 15:17:14 +0200 |
commit | e8dcd5bbc2c92dd82c6f7c405ab4f95956b35dec (patch) | |
tree | 969fece9de69b101dd3534997a9959401d69cc2f /src | |
parent | c35e4faf918e8076012c881519687b7bbccaf5eb (diff) |
Add 128-bit integers
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen.c | 33 | ||||
-rw-r--r-- | src/primitives.gperf | 2 |
2 files changed, 20 insertions, 15 deletions
diff --git a/src/codegen.c b/src/codegen.c index 4e2a4d3..f8a3f32 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -12,11 +12,11 @@ #include "parser.h" #include "types.h" -static size_t codegenstmt(LLVMBuilderRef, LLVMValueRef *, struct ast, - struct lexemes, size_t) +static size_t codegenstmt(LLVMBuilderRef, LLVMValueRef *, struct type *, + struct ast, struct lexemes, size_t) __attribute__((nonnull)); -static size_t codegenexpr(LLVMBuilderRef, LLVMValueRef *, struct ast, - struct lexemes, size_t, LLVMValueRef *) +static size_t codegenexpr(LLVMBuilderRef, LLVMValueRef *, struct type *, + struct ast, struct lexemes, size_t, LLVMValueRef *) __attribute__((nonnull)); static LLVMTypeRef type2llvm(struct type); @@ -43,7 +43,7 @@ codegen(const char *file, struct type *types, struct ast ast, LLVMTypeRef T = type2llvm(types[i]); LLVMValueRef globl, val; globl = LLVMAddGlobal(mod, T, name); - i = codegenexpr(builder, declvals, ast, toks, ast.kids[i].rhs, &val); + i = codegenexpr(builder, declvals, types, ast, toks, ast.kids[i].rhs, &val); LLVMSetInitializer(globl, LLVMConstTrunc(val, T)); free(name); break; @@ -86,7 +86,7 @@ codegen(const char *file, struct type *types, struct ast ast, free(fnname); for (i = ast.kids[body].lhs; i <= ast.kids[body].rhs;) - i = codegenstmt(builder, declvals, ast, toks, i); + i = codegenstmt(builder, declvals, types, ast, toks, i); break; } default: @@ -106,8 +106,8 @@ codegen(const char *file, struct type *types, struct ast ast, } size_t -codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast, - struct lexemes toks, size_t i) +codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct type *types, + struct ast ast, struct lexemes toks, size_t i) { switch (ast.kinds[i]) { case ASTRET: @@ -116,7 +116,8 @@ codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast, return i + 1; } LLVMValueRef v; - i = codegenexpr(builder, declvals, ast, toks, ast.kids[i].rhs, &v); + i = codegenexpr(builder, declvals, types, ast, toks, ast.kids[i].rhs, + &v); LLVMBuildRet(builder, v); return i; } @@ -126,9 +127,10 @@ codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast, } size_t -codegenexpr(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast, - struct lexemes toks, size_t i, LLVMValueRef *v) +codegenexpr(LLVMBuilderRef builder, LLVMValueRef *declvals, struct type *types, + struct ast ast, struct lexemes toks, size_t i, LLVMValueRef *v) { + (void)declvals; (void)builder; switch (ast.kinds[i]) { case ASTNUMLIT: { @@ -146,10 +148,11 @@ codegenexpr(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast, p[len++] = sv.p[i]; } - *v = LLVMConstIntOfStringAndSize(LLVMInt64Type(), p, len, 10); + *v = LLVMConstIntOfStringAndSize(type2llvm(types[i]), p, len, 10); free(p); } else - *v = LLVMConstIntOfStringAndSize(LLVMInt64Type(), sv.p, sv.len, 10); + *v = LLVMConstIntOfStringAndSize(type2llvm(types[i]), sv.p, sv.len, + 10); return i + 1; } case ASTIDENT: @@ -177,8 +180,8 @@ type2llvm(struct type t) assert(t.issigned); /* TODO: Arbitrary precision */ if (t.size == 0) - t.size = 8; - return LLVMIntType(t.size * 8); + return LLVMInt128Type(); + return LLVMIntType((unsigned)t.size * 8); default: __builtin_unreachable(); } diff --git a/src/primitives.gperf b/src/primitives.gperf index 7594b29..ea7543b 100644 --- a/src/primitives.gperf +++ b/src/primitives.gperf @@ -20,11 +20,13 @@ i8, { TYPE_NUM, 1, true } i16, { TYPE_NUM, 2, true } i32, { TYPE_NUM, 4, true } i64, { TYPE_NUM, 8, true } +i128, { TYPE_NUM, 16, true } int, { TYPE_NUM, 8, true } u8, { TYPE_NUM, 1, false } u16, { TYPE_NUM, 2, false } u32, { TYPE_NUM, 4, false } u64, { TYPE_NUM, 8, false } +u128, { TYPE_NUM, 16, false } uint, { TYPE_NUM, 8, false } rune, { TYPE_RUNE, 4, true } %% |