aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/nasm.c
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-03 03:36:06 +0200
committerhachem <im@hachem.wtf>2026-09-03 03:36:06 +0200
commit56ba8b2a373dd1386950592bda9c68ff9f25c203 (patch)
treee33d46037b8a0cb25f5c9052d1f2ee3b143dff22 /src/codegen/nasm.c
parent9956f626110a5b55fc58049bbe5841a98e941614 (diff)
fix: i JUST started using a static analyzer for ts
Diffstat (limited to 'src/codegen/nasm.c')
-rw-r--r--src/codegen/nasm.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/codegen/nasm.c b/src/codegen/nasm.c
index 31bcee0..6df22a4 100644
--- a/src/codegen/nasm.c
+++ b/src/codegen/nasm.c
@@ -93,7 +93,7 @@ static bool is_float_register(struct Token token)
return true;
}
-static size_t float_index(struct FloatTable* floats, struct Token literal)
+static size_t float_index(const struct FloatTable* floats, struct Token literal)
{
for (size_t i = 0; i < floats->count; i += 1)
if (floats->items[i].length == literal.length
@@ -310,7 +310,7 @@ static bool fold_member(struct Program* program, struct Expr* object, struct Tok
return false;
struct Token name = object->primary.token;
- struct EnumDecl* enumeration = find_enum(program, name);
+ const struct EnumDecl* enumeration = find_enum(program, name);
if (enumeration != NULL)
{
for (size_t i = 0; i < enumeration->member_count; i += 1)
@@ -322,7 +322,7 @@ static bool fold_member(struct Program* program, struct Expr* object, struct Tok
return false;
}
- struct StructDecl* layout = find_struct(program, name);
+ const struct StructDecl* layout = find_struct(program, name);
if (layout != NULL)
{
uint64_t offset = 0;
@@ -400,7 +400,7 @@ static bool fold_const(struct Program* program, struct Expr* expr, uint64_t* out
// offset (or the total size for `.size`)
static bool emit_named_member(struct Emitter* emitter, struct Token object, struct Token member)
{
- struct EnumDecl* enumeration = find_enum(emitter->program, object);
+ const struct EnumDecl* enumeration = find_enum(emitter->program, object);
if (enumeration != NULL)
{
for (size_t i = 0; i < enumeration->member_count; i += 1)
@@ -411,7 +411,7 @@ static bool emit_named_member(struct Emitter* emitter, struct Token object, stru
}
}
- struct StructDecl* layout = find_struct(emitter->program, object);
+ const struct StructDecl* layout = find_struct(emitter->program, object);
if (layout != NULL)
{
uint64_t offset = 0;
@@ -494,6 +494,19 @@ static void emit_division(struct Emitter* emitter, const char* dst, struct Expr*
fprintf(emitter->out, "\tmov %s, rax\n", dst);
}
+// idiv leaves the remainder in rdx, so a modulo takes its result from there
+static void emit_modulo(struct Emitter* emitter, const char* dst, struct Expr* divisor)
+{
+ if (strcmp(dst, "rax") != 0)
+ fprintf(emitter->out, "\tmov rax, %s\n", dst);
+ fprintf(emitter->out, "\tcqo\n");
+ fprintf(emitter->out, "\tidiv ");
+ emit_operand(emitter, divisor);
+ fprintf(emitter->out, "\n");
+ if (strcmp(dst, "rdx") != 0)
+ fprintf(emitter->out, "\tmov %s, rdx\n", dst);
+}
+
static void emit_divide(struct Emitter* emitter, struct AssignStatement* assign)
{
if (assign->target_deref)
@@ -505,7 +518,11 @@ static void emit_divide(struct Emitter* emitter, struct AssignStatement* assign)
struct Token target = resolve_register(emitter, assign->target);
char dst[32];
snprintf(dst, sizeof(dst), "%.*s", (int)target.length, target.start);
- emit_division(emitter, dst, assign->value);
+
+ if (assign->op.type == TOKEN_PERCENT_EQUAL)
+ emit_modulo(emitter, dst, assign->value);
+ else
+ emit_division(emitter, dst, assign->value);
}
// an expression can be evaluated into a register when it is a single term
@@ -576,6 +593,11 @@ static void emit_expr_into(struct Emitter* emitter, const char* dst, struct Expr
emit_division(emitter, dst, expr->binary.right);
return;
}
+ if (expr->binary.op.type == TOKEN_PERCENT)
+ {
+ emit_modulo(emitter, dst, expr->binary.right);
+ return;
+ }
const char* mnemonic =
expr->binary.op.type == TOKEN_PLUS ? "add" :
@@ -677,7 +699,7 @@ static const char* float_mnemonic(enum TokenType op)
}
}
-static bool value_is_float(struct Emitter* emitter, struct Expr* expr)
+static bool value_is_float(struct Emitter* emitter, const struct Expr* expr)
{
if (expr->kind != EXPR_PRIMARY)
return false;
@@ -766,7 +788,7 @@ static void emit_assign(struct Emitter* emitter, struct AssignStatement* assign)
return;
}
- if (assign->op.type == TOKEN_SLASH_EQUAL)
+ if (assign->op.type == TOKEN_SLASH_EQUAL || assign->op.type == TOKEN_PERCENT_EQUAL)
{
emit_divide(emitter, assign);
return;
@@ -860,7 +882,7 @@ static struct ProcDecl* find_proc(struct Program* program, struct Token name)
static void emit_call(struct Emitter* emitter, struct CallStatement* call)
{
- struct ProcDecl* callee = find_proc(emitter->program, call->name);
+ const struct ProcDecl* callee = find_proc(emitter->program, call->name);
if (callee == NULL || callee->param_count != call->arg_count)
{
fprintf(emitter->out, "\t; TODO: unsupported call\n");
@@ -902,7 +924,7 @@ static const char* float_jump_if_false(enum TokenType comparison)
}
}
-static void emit_float_operand(struct Emitter* emitter, struct Expr* expr)
+static void emit_float_operand(struct Emitter* emitter, const struct Expr* expr)
{
if (expr->kind == EXPR_PRIMARY && expr->primary.token.type == TOKEN_FLOAT)
{
@@ -1082,7 +1104,7 @@ static struct FloatTable collect_floats(struct Program* program)
return floats;
}
-static void emit_float_data(struct FloatTable* floats, FILE* out)
+static void emit_float_data(const struct FloatTable* floats, FILE* out)
{
for (size_t i = 0; i < floats->count; i += 1)
fprintf(out, "__float%zu: dq %.*s\n", i,