Handle flonum for if, while, do, !, ?:, || and &&

This commit is contained in:
Rui Ueyama 2020-09-13 15:58:36 +09:00
parent 83f76ebb66
commit 0ce1093027
3 changed files with 43 additions and 9 deletions

View File

@ -150,6 +150,17 @@ static void store(Type *ty) {
} }
static void cmp_zero(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) if (is_integer(ty) && ty->size <= 4)
println(" cmp $0, %%eax"); println(" cmp $0, %%eax");
else else
@ -337,7 +348,7 @@ static void gen_expr(Node *node) {
case ND_COND: { case ND_COND: {
int c = count(); int c = count();
gen_expr(node->cond); gen_expr(node->cond);
println(" cmp $0, %%rax"); cmp_zero(node->cond->ty);
println(" je .L.else.%d", c); println(" je .L.else.%d", c);
gen_expr(node->then); gen_expr(node->then);
println(" jmp .L.end.%d", c); println(" jmp .L.end.%d", c);
@ -348,7 +359,7 @@ static void gen_expr(Node *node) {
} }
case ND_NOT: case ND_NOT:
gen_expr(node->lhs); gen_expr(node->lhs);
println(" cmp $0, %%rax"); cmp_zero(node->lhs->ty);
println(" sete %%al"); println(" sete %%al");
println(" movzx %%al, %%rax"); println(" movzx %%al, %%rax");
return; return;
@ -359,10 +370,10 @@ static void gen_expr(Node *node) {
case ND_LOGAND: { case ND_LOGAND: {
int c = count(); int c = count();
gen_expr(node->lhs); gen_expr(node->lhs);
println(" cmp $0, %%rax"); cmp_zero(node->lhs->ty);
println(" je .L.false.%d", c); println(" je .L.false.%d", c);
gen_expr(node->rhs); gen_expr(node->rhs);
println(" cmp $0, %%rax"); cmp_zero(node->rhs->ty);
println(" je .L.false.%d", c); println(" je .L.false.%d", c);
println(" mov $1, %%rax"); println(" mov $1, %%rax");
println(" jmp .L.end.%d", c); println(" jmp .L.end.%d", c);
@ -374,10 +385,10 @@ static void gen_expr(Node *node) {
case ND_LOGOR: { case ND_LOGOR: {
int c = count(); int c = count();
gen_expr(node->lhs); gen_expr(node->lhs);
println(" cmp $0, %%rax"); cmp_zero(node->lhs->ty);
println(" jne .L.true.%d", c); println(" jne .L.true.%d", c);
gen_expr(node->rhs); gen_expr(node->rhs);
println(" cmp $0, %%rax"); cmp_zero(node->rhs->ty);
println(" jne .L.true.%d", c); println(" jne .L.true.%d", c);
println(" mov $0, %%rax"); println(" mov $0, %%rax");
println(" jmp .L.end.%d", c); println(" jmp .L.end.%d", c);
@ -579,7 +590,7 @@ static void gen_stmt(Node *node) {
case ND_IF: { case ND_IF: {
int c = count(); int c = count();
gen_expr(node->cond); gen_expr(node->cond);
println(" cmp $0, %%rax"); cmp_zero(node->cond->ty);
println(" je .L.else.%d", c); println(" je .L.else.%d", c);
gen_stmt(node->then); gen_stmt(node->then);
println(" jmp .L.end.%d", c); println(" jmp .L.end.%d", c);
@ -596,7 +607,7 @@ static void gen_stmt(Node *node) {
println(".L.begin.%d:", c); println(".L.begin.%d:", c);
if (node->cond) { if (node->cond) {
gen_expr(node->cond); gen_expr(node->cond);
println(" cmp $0, %%rax"); cmp_zero(node->cond->ty);
println(" je %s", node->brk_label); println(" je %s", node->brk_label);
} }
gen_stmt(node->then); gen_stmt(node->then);
@ -613,7 +624,7 @@ static void gen_stmt(Node *node) {
gen_stmt(node->then); gen_stmt(node->then);
println("%s:", node->cont_label); println("%s:", node->cont_label);
gen_expr(node->cond); gen_expr(node->cond);
println(" cmp $0, %%rax"); cmp_zero(node->cond->ty);
println(" jne .L.begin.%d", c); println(" jne .L.begin.%d", c);
println("%s:", node->brk_label); println("%s:", node->brk_label);
return; return;

View File

@ -68,6 +68,21 @@ int main() {
ASSERT(7, ({ int i=0; int j=0; do { j++; } while (i++ < 6); j; })); 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(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"); printf("OK\n");
return 0; return 0;
} }

View File

@ -80,6 +80,14 @@ int main() {
ASSERT(0, 0.0/0.0 > 0); ASSERT(0, 0.0/0.0 > 0);
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"); printf("OK\n");
return 0; return 0;
} }