aboutsummaryrefslogtreecommitdiffhomepage
path: root/codegen.c
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-07-21 20:48:01 +0900
committernsfisis <nsfisis@gmail.com>2025-08-15 10:04:32 +0900
commit0c9dc7318361c93e837c8f4bc5c29869076c36cd (patch)
treea0998f947324fb42885338d0bd729d02d4309f40 /codegen.c
parent1c48d0fe728c263bbe946a5d3adebaa29323ddff (diff)
downloadducc-0c9dc7318361c93e837c8f4bc5c29869076c36cd.tar.gz
ducc-0c9dc7318361c93e837c8f4bc5c29869076c36cd.tar.zst
ducc-0c9dc7318361c93e837c8f4bc5c29869076c36cd.zip
feat: implement va_*() functions
Diffstat (limited to 'codegen.c')
-rw-r--r--codegen.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/codegen.c b/codegen.c
index 26e7604..c8d6e5b 100644
--- a/codegen.c
+++ b/codegen.c
@@ -209,8 +209,31 @@ void codegen_assign_expr(CodeGen* g, AstNode* ast) {
void codegen_func_call(CodeGen* g, AstNode* ast) {
String* func_name = &ast->name;
- AstNode* args = ast->node_args;
int i;
+
+ if (string_equals_cstr(func_name, "va_start")) {
+ printf(" # va_start BEGIN\n");
+ for (i = 0; i < 6; ++i) {
+ printf(" mov rax, %s\n", param_reg(i));
+ printf(" mov [rbp-%d], rax\n", 8 + (LVAR_MAX - 4 - i) * 8);
+ }
+ AstNode* va_list_args = ast->node_args->node_items;
+ codegen_expr(g, va_list_args, GenMode_lval);
+ printf(" pop rdi\n");
+ printf(" mov rax, rbp\n");
+ printf(" sub rax, %d\n", 8 + (LVAR_MAX - 1) * 8);
+ printf(" mov [rdi], rax\n");
+ printf(" mov DWORD PTR [rax], 8\n");
+ printf(" mov DWORD PTR [rax+4], 0\n");
+ printf(" mov QWORD PTR [rax+8], 0\n");
+ printf(" mov rdi, rbp\n");
+ printf(" sub rdi, %d\n", 8 + (LVAR_MAX - 4) * 8);
+ printf(" mov QWORD PTR [rax+16], rdi\n");
+ printf(" # va_start END\n");
+ return;
+ }
+
+ AstNode* args = ast->node_args;
for (i = 0; i < args->node_len; ++i) {
AstNode* arg = args->node_items + i;
codegen_expr(g, arg, GenMode_rval);