From fd7d82869eb42d086174ec02938b49e4f233c319 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 11 Aug 2025 13:22:02 +0900 Subject: feat: implement '*=', '/=' and '%=' operators --- codegen.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'codegen.c') diff --git a/codegen.c b/codegen.c index 796dd14..f3790d2 100644 --- a/codegen.c +++ b/codegen.c @@ -196,30 +196,43 @@ void codegen_binary_expr(CodeGen* g, AstNode* ast, GenMode gen_mode) { printf(" push rax\n"); } -void codegen_assign_expr(CodeGen* g, AstNode* ast) { - int sizeof_lhs = type_sizeof(ast->node_lhs->ty); - int sizeof_rhs = type_sizeof(ast->node_rhs->ty); - - codegen_expr(g, ast->node_lhs, GenMode_lval); - codegen_expr(g, ast->node_rhs, GenMode_rval); +void codegen_assign_expr_helper(CodeGen* g, AstNode* ast) { if (ast->node_op == TokenKind_assign) { - } else if (ast->node_op == TokenKind_assign_add) { - printf(" pop rdi\n"); - printf(" push [rsp]\n"); - codegen_lval2rval(ast->node_lhs->ty); - printf(" pop rax\n"); + return; + } + + printf(" pop rdi\n"); + printf(" push [rsp]\n"); + codegen_lval2rval(ast->node_lhs->ty); + printf(" pop rax\n"); + + if (ast->node_op == TokenKind_assign_add) { printf(" add rax, rdi\n"); - printf(" push rax\n"); } else if (ast->node_op == TokenKind_assign_sub) { - printf(" pop rdi\n"); - printf(" push [rsp]\n"); - codegen_lval2rval(ast->node_lhs->ty); - printf(" pop rax\n"); printf(" sub rax, rdi\n"); - printf(" push rax\n"); + } else if (ast->node_op == TokenKind_assign_mul) { + printf(" imul rax, rdi\n"); + } else if (ast->node_op == TokenKind_assign_div) { + printf(" cqo\n"); + printf(" idiv rdi\n"); + } else if (ast->node_op == TokenKind_assign_mod) { + printf(" cqo\n"); + printf(" idiv rdi\n"); + printf(" mov rax, rdx\n"); } else { unreachable(); } + + printf(" push rax\n"); +} + +void codegen_assign_expr(CodeGen* g, AstNode* ast) { + int sizeof_lhs = type_sizeof(ast->node_lhs->ty); + int sizeof_rhs = type_sizeof(ast->node_rhs->ty); + + codegen_expr(g, ast->node_lhs, GenMode_lval); + codegen_expr(g, ast->node_rhs, GenMode_rval); + codegen_assign_expr_helper(g, ast); if (sizeof_lhs == 1) { printf(" pop rdi\n"); printf(" pop rax\n"); -- cgit v1.2.3-70-g09d2