aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-05-04 23:06:10 +0900
committernsfisis <nsfisis@gmail.com>2025-05-05 00:22:18 +0900
commit992fc93278710bb41117d93531d9ed18db49e119 (patch)
tree1c8944cb951d2c830a278d8ea4b7ad8b15add142
parentaa750653fe6c03c6144142d233bd032e4e9070c0 (diff)
downloadP4Dcc-992fc93278710bb41117d93531d9ed18db49e119.tar.gz
P4Dcc-992fc93278710bb41117d93531d9ed18db49e119.tar.zst
P4Dcc-992fc93278710bb41117d93531d9ed18db49e119.zip
fix load/store
-rw-r--r--main.c28
-rw-r--r--tests/test_diff.sh5
2 files changed, 27 insertions, 6 deletions
diff --git a/main.c b/main.c
index e17c7d9..acc4c38 100644
--- a/main.c
+++ b/main.c
@@ -1455,6 +1455,20 @@ void gen_ref_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
gen_expr(g, ast->expr1, GEN_LVAL);
}
+void gen_lval2rval(struct Type* ty) {
+ int size = type_sizeof(ty);
+
+ printf(" pop rax\n");
+ if (size == 1) {
+ printf(" movsx rax, BYTE PTR [rax]\n");
+ } else if (size == 4) {
+ printf(" movsxd rax, DWORD PTR [rax]\n");
+ } else {
+ printf(" mov rax, [rax]\n");
+ }
+ printf(" push rax\n");
+}
+
void gen_deref_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
assert_ast_kind(ast, AST_DEREF_EXPR);
printf(" # gen_deref_expr\n");
@@ -1463,8 +1477,7 @@ void gen_deref_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
gen_expr(g, ast->expr1, GEN_RVAL);
} else {
gen_expr(g, ast->expr1, GEN_RVAL);
- printf(" pop rax\n");
- printf(" push [rax]\n");
+ gen_lval2rval(ast->expr1->ty);
}
}
@@ -1575,7 +1588,13 @@ void gen_assign_expr(struct CodeGen* g, struct AstNode* ast) {
printf(" pop rdi\n");
printf(" pop rax\n");
if (ast->op == TK_ASSIGN) {
- printf(" mov [rax], rdi\n");
+ if (type_sizeof(ast->expr1->ty) == 1) {
+ printf(" mov BYTE PTR [rax], dil\n");
+ } else if (type_sizeof(ast->expr1->ty) == 4) {
+ printf(" mov DWORD PTR [rax], edi\n");
+ } else {
+ printf(" mov [rax], rdi\n");
+ }
printf(" push rdi\n");
} else {
fatal_error("gen_assign_expr: unknown assign op");
@@ -1627,8 +1646,7 @@ void gen_lvar(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
printf(" sub rax, %d\n", offset);
printf(" push rax\n");
if (gen_mode == GEN_RVAL) {
- printf(" pop rax\n");
- printf(" push [rax]\n");
+ gen_lval2rval(ast->ty);
}
}
diff --git a/tests/test_diff.sh b/tests/test_diff.sh
index a66639e..44e00d0 100644
--- a/tests/test_diff.sh
+++ b/tests/test_diff.sh
@@ -6,7 +6,10 @@ if [[ $? -ne 0 ]]; then
exit 1
fi
gcc -Wl,-z,noexecstack -o a.out main.s
-./a.out > output
+if [[ ! -f input ]]; then
+ touch input
+fi
+./a.out < input > output
exit_code=$?
if [[ $exit_code -ne 0 ]]; then