tccasm: Implement compare expressions

I.e. implement < > <= >= == !=.  Comparisons are signed and result
is -1 if true, 0 if false.
This commit is contained in:
Michael Matz 2016-06-30 15:47:58 +02:00
parent ff5561ff7d
commit 1a5eacb445
2 changed files with 51 additions and 1 deletions

View File

@ -259,9 +259,51 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
} }
} }
static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
{
int op;
ExprValue e2;
asm_expr_sum(s1, pe);
for(;;) {
op = tok;
if (op != TOK_EQ && op != TOK_NE
&& (op > TOK_GT || op < TOK_ULE))
break;
next();
asm_expr_sum(s1, &e2);
if (pe->sym || e2.sym)
tcc_error("invalid operation with label");
switch(op) {
case TOK_EQ:
pe->v = pe->v == e2.v;
break;
case TOK_NE:
pe->v = pe->v != e2.v;
break;
case TOK_LT:
pe->v = (int64_t)pe->v < (int64_t)e2.v;
break;
case TOK_GE:
pe->v = (int64_t)pe->v >= (int64_t)e2.v;
break;
case TOK_LE:
pe->v = (int64_t)pe->v <= (int64_t)e2.v;
break;
case TOK_GT:
pe->v = (int64_t)pe->v > (int64_t)e2.v;
break;
default:
break;
}
/* GAS compare results are -1/0 not 1/0. */
pe->v = -(int64_t)pe->v;
}
}
ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe) ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
{ {
asm_expr_sum(s1, pe); asm_expr_cmp(s1, pe);
} }
ST_FUNC int asm_int_expr(TCCState *s1) ST_FUNC int asm_int_expr(TCCState *s1)
@ -391,6 +433,8 @@ static void asm_parse_directive(TCCState *s1)
if (sec->sh_addralign < n) if (sec->sh_addralign < n)
sec->sh_addralign = n; sec->sh_addralign = n;
} else { } else {
if (n < 0)
n = 0;
size = n; size = n;
} }
v = 0; v = 0;

View File

@ -740,6 +740,12 @@ nop
.word 164, 0 .word 164, 0
.org 2b+32 .org 2b+32
.quad 1b .quad 1b
.popsection
3: mov %eax,%ecx
4:
.pushsection .text.three, "ax"
nop
.skip (-((4b-3b) > 0) * 2) , 0x90
.popsection .popsection
movd %esi, %mm1 movd %esi, %mm1