aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.c')
-rw-r--r--src/codegen.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/codegen.c b/src/codegen.c
index eb26036..71a8e1d 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -145,7 +145,8 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv)
{
/* If true, implies numeric constant */
if (MPQ_IS_INIT(ctx.folds[i]) && !type.isfloat) {
- /* TODO: Move this kind of range checking to the constant folding stage? */
+ /* TODO: Move this kind of range checking to the
+ constant folding stage? */
if (!type.issigned && mpq_sgn(ctx.folds[i]) == -1)
err("Cannot convert negative value to unsigned type");
@@ -189,11 +190,20 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv)
/* TODO: Is this even correct? */
switch (type.size) {
- case 2: prec = 5; break;
- case 4: prec = 8; break;
- case 8: prec = 11; break;
- case 16: prec = 16; break;
- default: __builtin_unreachable();
+ case 2:
+ prec = 5;
+ break;
+ case 4:
+ prec = 8;
+ break;
+ case 8:
+ prec = 11;
+ break;
+ case 16:
+ prec = 16;
+ break;
+ default:
+ __builtin_unreachable();
}
mpf_init2(x, prec);
@@ -219,7 +229,8 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv)
case ASTIDENT: {
strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]];
LLVMTypeRef t = type2llvm(ctx, ctx.types[i]);
- LLVMValueRef ptrval = symtab_insert(&ctx.scps[ctx.scpi].map, sv, NULL)->v;
+ LLVMValueRef ptrval =
+ symtab_insert(&ctx.scps[ctx.scpi].map, sv, NULL)->v;
*outv = LLVMBuildLoad2(ctx.bob, t, ptrval, "loadtmp");
return fwdnode(ctx.ast, i);
}
@@ -231,21 +242,28 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv)
}
case ASTBINADD:
case ASTBINSUB:
- case ASTBINMUL: {
- typedef LLVMValueRef llbfn(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, const char *);
+ case ASTBINMUL:
+ case ASTBINDIV: {
+ typedef LLVMValueRef llbfn(LLVMBuilderRef, LLVMValueRef, LLVMValueRef,
+ const char *);
static const struct binop {
- llbfn *fn;
+ llbfn *fn[2];
const char *name;
- } binoptbl[_AST_LAST_ENT] = {
- ['+'] = { LLVMBuildAdd, "addtmp" },
- ['-'] = { LLVMBuildSub, "subtmp" },
- ['*'] = { LLVMBuildMul, "multmp" },
+ } binoptbl[UINT8_MAX] = {
+ ['+'] = {{LLVMBuildAdd, LLVMBuildAdd}, "addtmp"},
+ ['-'] = {{LLVMBuildSub, LLVMBuildSub}, "subtmp"},
+ ['*'] = {{LLVMBuildMul, LLVMBuildMul}, "multmp"},
+ ['/'] = {{LLVMBuildUDiv, LLVMBuildSDiv}, "divtmp"},
+ ['%'] = {{LLVMBuildURem, LLVMBuildSRem}, "remtmp"},
};
+
LLVMValueRef vl, vr;
- (void)codegentypedexpr(ctx, ctx.ast.kids[i].lhs, ctx.types[i], &vl);
- idx_t ni = codegentypedexpr(ctx, ctx.ast.kids[i].rhs, ctx.types[i], &vr);
+ (void)codegentypedexpr(ctx, ctx.ast.kids[i].lhs, ctx.types[i], &vl);
+ idx_t ni = codegentypedexpr(ctx, ctx.ast.kids[i].rhs,
+ ctx.types[i], &vr);
+
struct binop bo = binoptbl[ctx.ast.kinds[i]];
- *outv = bo.fn(ctx.bob, vl, vr, bo.name);
+ *outv = bo.fn[ctx.types[i].issigned](ctx.bob, vl, vr, bo.name);
return ni;
}
default: