From 1a5eacb445a0116722e88e1a8a3e88e9d4127d2b Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Thu, 30 Jun 2016 15:47:58 +0200 Subject: tccasm: Implement compare expressions I.e. implement < > <= >= == !=. Comparisons are signed and result is -1 if true, 0 if false. --- tccasm.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'tccasm.c') diff --git a/tccasm.c b/tccasm.c index 185f066..569ff81 100644 --- a/tccasm.c +++ b/tccasm.c @@ -259,9 +259,51 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) } } -ST_FUNC void asm_expr(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) +{ + asm_expr_cmp(s1, pe); } ST_FUNC int asm_int_expr(TCCState *s1) @@ -391,6 +433,8 @@ static void asm_parse_directive(TCCState *s1) if (sec->sh_addralign < n) sec->sh_addralign = n; } else { + if (n < 0) + n = 0; size = n; } v = 0; -- cgit v1.3.1