From fade39d85ea72009048b5777365ff61e0790ee07 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 13 Sep 2020 15:58:36 +0900 Subject: [PATCH] Handle flonum for if, while, do, !, ?:, || and && --- codegen.c | 29 ++++++++++++++++++++--------- test/control.c | 15 +++++++++++++++ test/float.c | 8 ++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/codegen.c b/codegen.c index f64b676..e8d5aac 100644 --- a/codegen.c +++ b/codegen.c @@ -149,6 +149,17 @@ static void store(Type *ty) { } static void cmp_zero(Type *ty) { + switch (ty->kind) { + case TY_FLOAT: + println(" xorps %%xmm1, %%xmm1"); + println(" ucomiss %%xmm1, %%xmm0"); + return; + case TY_DOUBLE: + println(" xorpd %%xmm1, %%xmm1"); + println(" ucomisd %%xmm1, %%xmm0"); + return; + } + if (is_integer(ty) && ty->size <= 4) println(" cmp $0, %%eax"); else @@ -316,7 +327,7 @@ static void gen_expr(Node *node) { case ND_COND: { int c = count(); gen_expr(node->cond); - println(" cmp $0, %%rax"); + cmp_zero(node->cond->ty); println(" je .L.else.%d", c); gen_expr(node->then); println(" jmp .L.end.%d", c); @@ -327,7 +338,7 @@ static void gen_expr(Node *node) { } case ND_NOT: gen_expr(node->lhs); - println(" cmp $0, %%rax"); + cmp_zero(node->lhs->ty); println(" sete %%al"); println(" movzx %%al, %%rax"); return; @@ -338,10 +349,10 @@ static void gen_expr(Node *node) { case ND_LOGAND: { int c = count(); gen_expr(node->lhs); - println(" cmp $0, %%rax"); + cmp_zero(node->lhs->ty); println(" je .L.false.%d", c); gen_expr(node->rhs); - println(" cmp $0, %%rax"); + cmp_zero(node->rhs->ty); println(" je .L.false.%d", c); println(" mov $1, %%rax"); println(" jmp .L.end.%d", c); @@ -353,10 +364,10 @@ static void gen_expr(Node *node) { case ND_LOGOR: { int c = count(); gen_expr(node->lhs); - println(" cmp $0, %%rax"); + cmp_zero(node->lhs->ty); println(" jne .L.true.%d", c); gen_expr(node->rhs); - println(" cmp $0, %%rax"); + cmp_zero(node->rhs->ty); println(" jne .L.true.%d", c); println(" mov $0, %%rax"); println(" jmp .L.end.%d", c); @@ -558,7 +569,7 @@ static void gen_stmt(Node *node) { case ND_IF: { int c = count(); gen_expr(node->cond); - println(" cmp $0, %%rax"); + cmp_zero(node->cond->ty); println(" je .L.else.%d", c); gen_stmt(node->then); println(" jmp .L.end.%d", c); @@ -575,7 +586,7 @@ static void gen_stmt(Node *node) { println(".L.begin.%d:", c); if (node->cond) { gen_expr(node->cond); - println(" cmp $0, %%rax"); + cmp_zero(node->cond->ty); println(" je %s", node->brk_label); } gen_stmt(node->then); @@ -592,7 +603,7 @@ static void gen_stmt(Node *node) { gen_stmt(node->then); println("%s:", node->cont_label); gen_expr(node->cond); - println(" cmp $0, %%rax"); + cmp_zero(node->cond->ty); println(" jne .L.begin.%d", c); println("%s:", node->brk_label); return; diff --git a/test/control.c b/test/control.c index d700352..2e77884 100644 --- a/test/control.c +++ b/test/control.c @@ -68,6 +68,21 @@ int main() { ASSERT(7, ({ int i=0; int j=0; do { j++; } while (i++ < 6); j; })); ASSERT(4, ({ int i=0; int j=0; int k=0; do { if (++j > 3) break; continue; k++; } while (1); j; })); + ASSERT(0, 0.0 && 0.0); + ASSERT(0, 0.0 && 0.1); + ASSERT(0, 0.3 && 0.0); + ASSERT(1, 0.3 && 0.5); + ASSERT(0, 0.0 || 0.0); + ASSERT(1, 0.0 || 0.1); + ASSERT(1, 0.3 || 0.0); + ASSERT(1, 0.3 || 0.5); + ASSERT(5, ({ int x; if (0.0) x=3; else x=5; x; })); + ASSERT(3, ({ int x; if (0.1) x=3; else x=5; x; })); + ASSERT(5, ({ int x=5; if (0.0) x=3; x; })); + ASSERT(3, ({ int x=5; if (0.1) x=3; x; })); + ASSERT(10, ({ double i=10.0; int j=0; for (; i; i--, j++); j; })); + ASSERT(10, ({ double i=10.0; int j=0; do j++; while(--i); j; })); + printf("OK\n"); return 0; } diff --git a/test/float.c b/test/float.c index 2ad0853..1ee2725 100644 --- a/test/float.c +++ b/test/float.c @@ -80,6 +80,14 @@ int main() { ASSERT(0, 0.0/0.0 > 0); ASSERT(0, 0.0/0.0 >= 0); + ASSERT(0, !3.); + ASSERT(1, !0.); + ASSERT(0, !3.f); + ASSERT(1, !0.f); + + ASSERT(5, 0.0 ? 3 : 5); + ASSERT(3, 1.2 ? 3 : 5); + printf("OK\n"); return 0; } -- GitLab