mirror of https://github.com/rui314/chibicc
Add flonum ==, !=, < and <=
This commit is contained in:
parent
29de46aed4
commit
cf9ceecb2f
49
codegen.c
49
codegen.c
|
@ -34,6 +34,18 @@ static void pop(char *arg) {
|
|||
depth--;
|
||||
}
|
||||
|
||||
static void pushf(void) {
|
||||
println(" sub $8, %%rsp");
|
||||
println(" movsd %%xmm0, (%%rsp)");
|
||||
depth++;
|
||||
}
|
||||
|
||||
static void popf(char *arg) {
|
||||
println(" movsd (%%rsp), %s", arg);
|
||||
println(" add $8, %%rsp");
|
||||
depth--;
|
||||
}
|
||||
|
||||
// Round up `n` to the nearest multiple of `align`. For instance,
|
||||
// align_to(5, 8) returns 8 and align_to(11, 8) returns 16.
|
||||
int align_to(int n, int align) {
|
||||
|
@ -403,6 +415,43 @@ static void gen_expr(Node *node) {
|
|||
}
|
||||
}
|
||||
|
||||
if (is_flonum(node->lhs->ty)) {
|
||||
gen_expr(node->rhs);
|
||||
pushf();
|
||||
gen_expr(node->lhs);
|
||||
popf("%xmm1");
|
||||
|
||||
char *sz = (node->lhs->ty->kind == TY_FLOAT) ? "ss" : "sd";
|
||||
|
||||
switch (node->kind) {
|
||||
case ND_EQ:
|
||||
case ND_NE:
|
||||
case ND_LT:
|
||||
case ND_LE:
|
||||
println(" ucomi%s %%xmm0, %%xmm1", sz);
|
||||
|
||||
if (node->kind == ND_EQ) {
|
||||
println(" sete %%al");
|
||||
println(" setnp %%dl");
|
||||
println(" and %%dl, %%al");
|
||||
} else if (node->kind == ND_NE) {
|
||||
println(" setne %%al");
|
||||
println(" setp %%dl");
|
||||
println(" or %%dl, %%al");
|
||||
} else if (node->kind == ND_LT) {
|
||||
println(" seta %%al");
|
||||
} else {
|
||||
println(" setae %%al");
|
||||
}
|
||||
|
||||
println(" and $1, %%al");
|
||||
println(" movzb %%al, %%rax");
|
||||
return;
|
||||
}
|
||||
|
||||
error_tok(node->tok, "invalid expression");
|
||||
}
|
||||
|
||||
gen_expr(node->rhs);
|
||||
push();
|
||||
gen_expr(node->lhs);
|
||||
|
|
20
test/float.c
20
test/float.c
|
@ -39,6 +39,26 @@ int main() {
|
|||
|
||||
ASSERT(-2147483648, (double)(unsigned long)(long)-1);
|
||||
|
||||
ASSERT(1, 2e3==2e3);
|
||||
ASSERT(0, 2e3==2e5);
|
||||
ASSERT(1, 2.0==2);
|
||||
ASSERT(0, 5.1<5);
|
||||
ASSERT(0, 5.0<5);
|
||||
ASSERT(1, 4.9<5);
|
||||
ASSERT(0, 5.1<=5);
|
||||
ASSERT(1, 5.0<=5);
|
||||
ASSERT(1, 4.9<=5);
|
||||
|
||||
ASSERT(1, 2e3f==2e3);
|
||||
ASSERT(0, 2e3f==2e5);
|
||||
ASSERT(1, 2.0f==2);
|
||||
ASSERT(0, 5.1f<5);
|
||||
ASSERT(0, 5.0f<5);
|
||||
ASSERT(1, 4.9f<5);
|
||||
ASSERT(0, 5.1f<=5);
|
||||
ASSERT(1, 5.0f<=5);
|
||||
ASSERT(1, 4.9f<=5);
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
5
type.c
5
type.c
|
@ -73,6 +73,11 @@ static Type *get_common_type(Type *ty1, Type *ty2) {
|
|||
if (ty1->base)
|
||||
return pointer_to(ty1->base);
|
||||
|
||||
if (ty1->kind == TY_DOUBLE || ty2->kind == TY_DOUBLE)
|
||||
return ty_double;
|
||||
if (ty1->kind == TY_FLOAT || ty2->kind == TY_FLOAT)
|
||||
return ty_float;
|
||||
|
||||
if (ty1->size < 4)
|
||||
ty1 = ty_int;
|
||||
if (ty2->size < 4)
|
||||
|
|
Loading…
Reference in New Issue