summaryrefslogtreecommitdiff
path: root/codegen.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-03-28 17:05:37 -1000
committerCarson Fleming <cflems@cflems.net>2026-03-28 17:05:37 -1000
commitb4d7305730606126d74862ca472a3efed964c2d8 (patch)
tree933ee0e11e30ec03181aba9051795513b94b0421 /codegen.c
parent0dc409ab0967d9973f36c138825067462b9a216f (diff)
downloadccc-b4d7305730606126d74862ca472a3efed964c2d8.tar.gz
rehashing and size tracking corrections
Diffstat (limited to 'codegen.c')
-rw-r--r--codegen.c86
1 files changed, 72 insertions, 14 deletions
diff --git a/codegen.c b/codegen.c
index c8a9933..37dea28 100644
--- a/codegen.c
+++ b/codegen.c
@@ -53,9 +53,14 @@ static void emit_storage_loc(
static void emit_mov(
FILE* outfile,
const struct storage_location* dst,
- const struct storage_location* src,
- unsigned long long sz
+ const struct storage_location* src
) {
+ /* size is only defined for memory locations */
+ unsigned long long sz;
+ if (dst->type == BP_OFFSET) sz = dst->sz;
+ else if (src->type == BP_OFFSET) sz = src->sz;
+ else sz = FULL_REG_SZ;
+
switch (dst->type) {
case REGISTER:
if (src->type == REGISTER && sz < 4) {
@@ -72,12 +77,20 @@ static void emit_mov(
case BP_OFFSET:
if (src->type == BP_OFFSET) {
/* `mov mem, mem` is illegal in x86_64 */
- emit_mov(outfile, &RV_LOC, src, sz);
- emit_mov(outfile, dst, &RV_LOC, sz);
+ emit_mov(outfile, &RV_LOC, src);
+ emit_mov(outfile, dst, &RV_LOC);
return;
}
fprintf(outfile, "\tmov ");
+ if (src->type == IMMEDIATE) {
+ /* must specify size to move immediates into memory*/
+ if (sz > 4) fprintf(outfile, "qword ");
+ else if (sz > 2) fprintf(outfile, "dword ");
+ else if (sz > 1) fprintf(outfile, "word ");
+ else fprintf(outfile, "byte ");
+ }
+
emit_storage_loc(outfile, dst, sz);
fprintf(outfile, ", ");
emit_storage_loc(outfile, src, sz);
@@ -109,8 +122,43 @@ static void emit_int_lit(
&(struct storage_location) {
.type = IMMEDIATE,
.value = node->val,
- },
- FULL_REG_SZ);
+ });
+}
+
+static void emit_float_lit(
+ FILE* outfile,
+ const struct float_lit_node* node,
+ const struct storage_location* storage
+) {
+ if (storage != NULL) {
+ CGEN_PANIC("float literals are not implemented");
+ }
+}
+
+static void emit_char_lit(
+ FILE* outfile,
+ const struct char_lit_node* node,
+ const struct storage_location* storage
+) {
+ if (storage != NULL) {
+ emit_mov(
+ outfile,
+ storage,
+ &(struct storage_location) {
+ .type = IMMEDIATE,
+ .value = (unsigned long long) node->val
+ });
+ }
+}
+
+static void emit_str_lit(
+ FILE* outfile,
+ const struct str_lit_node* node,
+ const struct storage_location* storage
+) {
+ if (storage != NULL) {
+ CGEN_PANIC("string literals are not implemented");
+ }
}
static struct var_def get_var(const char* name) {
@@ -127,7 +175,7 @@ static void emit_var_ref(
) {
if (storage != NULL) {
struct var_def var_def = get_var(node->ident);
- emit_mov(outfile, storage, &var_def.loc, var_def.sz);
+ emit_mov(outfile, storage, &var_def.loc);
}
}
@@ -140,7 +188,7 @@ static unsigned long long get_type_size(const struct type_node* type) {
if (!scope_get_type(scope, &type_def, type->name))
CGEN_PANIC("size of type %s is not known", type->name);
- return type_def.size;
+ return type_def.sz;
}
static struct var_def emit_var_decl(
@@ -157,8 +205,8 @@ static struct var_def emit_var_decl(
.loc = {
.type = BP_OFFSET,
.offset = scope->bp_offset,
+ .sz = type_sz,
},
- .sz = type_sz,
};
scope_define_var(scope, var_def);
return var_def;
@@ -177,10 +225,10 @@ static struct lval_def emit_lval(
switch (node->type) {
case LVAL_VAR_DECL:
var_def = emit_var_decl(outfile, &node->as._var_decl);
- return (struct lval_def) {.loc = var_def.loc, .sz = var_def.sz};
+ return (struct lval_def) {.loc = var_def.loc, .sz = var_def.loc.sz};
case LVAL_VAR_REF:
var_def = get_var(node->as._var_ref.ident);
- return (struct lval_def) {.loc = var_def.loc, .sz = var_def.sz};
+ return (struct lval_def) {.loc = var_def.loc, .sz = var_def.loc.sz};
}
CGEN_PANIC("unknown lval type: %d", node->type);
}
@@ -192,7 +240,7 @@ static void emit_assignment(
) {
const struct lval_def lval_def = emit_lval(outfile, &node->lval);
emit_expr(outfile, node->rval, &lval_def.loc);
- if (storage != NULL) emit_mov(outfile, storage, &lval_def.loc, lval_def.sz);
+ if (storage != NULL) emit_mov(outfile, storage, &lval_def.loc);
}
static void emit_expr(
@@ -204,6 +252,15 @@ static void emit_expr(
case EXPR_INT_LIT:
emit_int_lit(outfile, &node->as._int_lit, storage);
break;
+ case EXPR_FLOAT_LIT:
+ emit_float_lit(outfile, &node->as._float_lit, storage);
+ break;
+ case EXPR_CHAR_LIT:
+ emit_char_lit(outfile, &node->as._char_lit, storage);
+ break;
+ case EXPR_STR_LIT:
+ emit_str_lit(outfile, &node->as._str_lit, storage);
+ break;
case EXPR_VAR_REF:
emit_var_ref(outfile, &node->as._var_ref, storage);
break;
@@ -277,8 +334,8 @@ static void emit_fn_decl(FILE* outfile, const struct fn_decl_node* node) {
.loc = {
.type = BP_OFFSET,
.offset = scope->bp_offset,
+ .sz = type_sz,
},
- .sz = type_sz,
};
scope_define_var(scope, var_def);
@@ -292,10 +349,11 @@ static void emit_fn_decl(FILE* outfile, const struct fn_decl_node* node) {
arg_src = (struct storage_location) {
.type = BP_OFFSET,
.offset = spilled_bp_ofs,
+ .sz = type_sz,
};
spilled_bp_ofs -= type_sz;
}
- emit_mov(outfile, &var_def.loc, &arg_src, type_sz);
+ emit_mov(outfile, &var_def.loc, &arg_src);
args_node = args_node->next;
}