summaryrefslogtreecommitdiff
path: root/codegen.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-08-04 22:51:29 -0400
committerCarson Fleming <cflems@cflems.net>2026-08-04 22:51:29 -0400
commitebe7f44385c4be54afd2993d54ce6352f612f9fa (patch)
tree008ee208ada0d7eb468ba6e74753872fc56d7d33 /codegen.c
parentb1ff7e8bf24b40cf64127a6194d45661db3a4baf (diff)
downloadccc-ebe7f44385c4be54afd2993d54ce6352f612f9fa.tar.gz
add string literals via the data segment
Diffstat (limited to 'codegen.c')
-rw-r--r--codegen.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/codegen.c b/codegen.c
index 3d96d33..d9b2962 100644
--- a/codegen.c
+++ b/codegen.c
@@ -2,6 +2,7 @@
#include "codegen.h"
#include "scope.h"
#include "register.h"
+#include "dseg.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -27,6 +28,7 @@ static struct reg* MULDIV_OVERFLOW_REG = &RDX;
#define FULL_REG_SZ 8
#define WORD_SZ 2
+static struct dseg dseg;
static struct scope* scope;
static const struct fn_decl_node* active_fn;
static integral_t branch_counter = 0;
@@ -95,7 +97,7 @@ static struct lval_def allocate_stack(
const struct type* type
) {
integral_t type_sz = get_effective_data_type(type)->sz;
- fprintf(outfile, "\tsub rsp, %llu\n", type_sz);
+ fprintf(outfile, "\tsub rsp, 0x%llx\n", type_sz);
scope->bp_offset += type_sz;
return (struct lval_def) {
.loc = {
@@ -156,14 +158,14 @@ static void emit_storage_loc(
break;
case STO_STACK:
if (loc->bp_offset < 0)
- fprintf(outfile, "[rbp + %lld]", -loc->bp_offset);
+ fprintf(outfile, "[rbp + 0x%llx]", -loc->bp_offset);
else if (loc->bp_offset > 0)
- fprintf(outfile, "[rbp - %lld]", loc->bp_offset);
+ fprintf(outfile, "[rbp - 0x%llx]", loc->bp_offset);
else
fprintf(outfile, "[rbp]");
break;
case STO_IMM:
- fprintf(outfile, "%llu", loc->value);
+ fprintf(outfile, "0x%llx", loc->value);
break;
case STO_UNRESOLVED:
CGEN_PANIC("can't emit unresolved storage location");
@@ -346,7 +348,14 @@ static void emit_str_lit(
const struct lval_def* dst
) {
if (dst != NULL) {
- CGEN_PANIC("string literals are not implemented");
+ const char* dseg_sym = dseg_put(&dseg, (struct dseg_entry) {
+ .type = ENT_STRING,
+ .key.string = node->val,
+ });
+ emit_mov(outfile, dst, &(struct storage_location) {
+ .type = STO_LABEL,
+ .label = dseg_sym,
+ });
}
}
@@ -370,10 +379,7 @@ static void emit_decl(
allocate_stack(outfile, node->def_ref->type);
node->def_ref->loc = var_dst.loc;
- fprintf(outfile, "\t; %s", node->def_ref->name);
- integral_t dst_sz = get_effective_data_type(var_dst.type)->sz;
- emit_storage_loc(outfile, &var_dst.loc, dst_sz);
- fprintf(outfile, "\n");
+ fprintf(outfile, "\t; %s\n", node->def_ref->name);
if (node->initial_value != NULL)
emit_expr(outfile, node->initial_value, &var_dst);
@@ -833,8 +839,8 @@ void emit_code(struct ast* ast, const char* path) {
FILE* outfile = fopen(path, "w");
if (outfile == NULL) CCC_PANIC;
+ dseg_init(&dseg);
scope = ast->root_scope;
- fprintf(outfile, "section .text\n");
/* output all function declarations in the root scope as globals */
const struct root_node* node = ast->root_node;
@@ -844,7 +850,8 @@ void emit_code(struct ast* ast, const char* path) {
}
fprintf(outfile, "\n");
- /* actual code body */
+ /* text (code) segment */
+ fprintf(outfile, "section .text\n");
node = ast->root_node;
while (node != NULL) {
emit_root_node(outfile, node);
@@ -852,5 +859,10 @@ void emit_code(struct ast* ast, const char* path) {
node = node->next;
}
+ /* data segment */
+ fprintf(outfile, "\n");
+ emit_dseg(outfile, &dseg);
+
+ dseg_destroy(&dseg);
fclose(outfile);
}