diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-09-13 13:17:28 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-09-13 13:17:28 +0900 |
| commit | a7c9c3407582f0d8d66539cf90e86fe3100787c5 (patch) | |
| tree | b8b4132ee0c116fae50f45107f3ae89a9a1911a6 /src/codegen.c | |
| parent | 8de7fa9da5fd8015f4fcc826b9270061b7b89478 (diff) | |
| download | ducc-a7c9c3407582f0d8d66539cf90e86fe3100787c5.tar.gz ducc-a7c9c3407582f0d8d66539cf90e86fe3100787c5.tar.zst ducc-a7c9c3407582f0d8d66539cf90e86fe3100787c5.zip | |
feat: implement cast expression
Diffstat (limited to 'src/codegen.c')
| -rw-r--r-- | src/codegen.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/codegen.c b/src/codegen.c index 000126b..dccabe4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -134,6 +134,46 @@ static void codegen_deref_expr(CodeGen* g, AstNode* ast, GenMode gen_mode) { } } +static void codegen_cast_expr(CodeGen* g, AstNode* ast) { + codegen_expr(g, ast->node_operand, GenMode_rval); + + int src_size = type_sizeof(ast->node_operand->ty); + int dst_size = type_sizeof(ast->ty); + + if (src_size == dst_size) + return; + + fprintf(g->out, " pop rax\n"); + + if (dst_size == 1) { + fprintf(g->out, " movsx rax, al\n"); + } else if (dst_size == 2) { + if (src_size == 1) { + fprintf(g->out, " movsx rax, al\n"); + } else { + fprintf(g->out, " movsx rax, ax\n"); + } + } else if (dst_size == 4) { + if (src_size == 1) { + fprintf(g->out, " movsx rax, al\n"); + } else if (src_size == 2) { + fprintf(g->out, " movsx rax, ax\n"); + } else { + fprintf(g->out, " movsxd rax, eax\n"); + } + } else if (dst_size == 8) { + if (src_size == 1) { + fprintf(g->out, " movsx rax, al\n"); + } else if (src_size == 2) { + fprintf(g->out, " movsx rax, ax\n"); + } else if (src_size == 4) { + fprintf(g->out, " movsxd rax, eax\n"); + } + } + + fprintf(g->out, " push rax\n"); +} + static void codegen_logical_expr(CodeGen* g, AstNode* ast) { int label = codegen_new_label(g); @@ -406,6 +446,8 @@ static void codegen_expr(CodeGen* g, AstNode* ast, GenMode gen_mode) { codegen_ref_expr(g, ast, gen_mode); } else if (ast->kind == AstNodeKind_deref_expr) { codegen_deref_expr(g, ast, gen_mode); + } else if (ast->kind == AstNodeKind_cast_expr) { + codegen_cast_expr(g, ast); } else if (ast->kind == AstNodeKind_binary_expr) { codegen_binary_expr(g, ast, gen_mode); } else if (ast->kind == AstNodeKind_cond_expr) { |
