From d9b7f018ce08bdd6b0e35608dbe75ba933622d92 Mon Sep 17 00:00:00 2001 From: grischka Date: Sun, 16 Oct 2016 19:04:40 +0200 Subject: [PATCH] i386: do not 'lexpand' into registers necessarily Previously, long longs were 'lexpand'ed into two registers always. Now, it expands - constants into two constants (lo-part, hi-part) - variables into two lvalues with offset+4 for the hi-part. This makes long long operations look a bit nicer. Also: don't apply i386 'inc/dec' optimization if carry generation is wanted. --- i386-gen.c | 4 ++-- tccgen.c | 26 ++++++++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/i386-gen.c b/i386-gen.c index b96e4fb..9cc2f8e 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -754,9 +754,9 @@ ST_FUNC void gen_opi(int op) c = vtop->c.i; if (c == (char)c) { /* generate inc and dec for smaller code */ - if (c==1 && opc==0) { + if (c==1 && opc==0 && op != TOK_ADDC1) { o (0x40 | r); // inc - } else if (c==1 && opc==5) { + } else if (c==1 && opc==5 && op != TOK_SUBC1) { o (0x48 | r); // dec } else { o(0x83); diff --git a/tccgen.c b/tccgen.c index f7f4d17..147f01e 100644 --- a/tccgen.c +++ b/tccgen.c @@ -1209,19 +1209,25 @@ static int reg_fret(int t) return REG_FRET; } -/* expand long long on stack in two int registers */ +/* expand long long on stack in two ints */ static void lexpand(void) { - int u; - + int u, v; u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); - gv(RC_INT); - vdup(); - vtop[0].r = vtop[-1].r2; - vtop[0].r2 = VT_CONST; - vtop[-1].r2 = VT_CONST; - vtop[0].type.t = VT_INT | u; - vtop[-1].type.t = VT_INT | u; + v = vtop->r & (VT_VALMASK | VT_LVAL); + if (v == VT_CONST) { + vdup(); + vtop[0].c.i >>= 32; + } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { + vdup(); + vtop[0].c.i += 4; + } else { + gv(RC_INT); + vdup(); + vtop[0].r = vtop[-1].r2; + vtop[0].r2 = vtop[-1].r2 = VT_CONST; + } + vtop[0].type.t = vtop[-1].type.t = VT_INT | u; } #ifdef TCC_TARGET_ARM