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.
This commit is contained in:
grischka 2016-10-16 19:04:40 +02:00
parent 6245db9fca
commit d9b7f018ce
2 changed files with 18 additions and 12 deletions

View File

@ -754,9 +754,9 @@ ST_FUNC void gen_opi(int op)
c = vtop->c.i; c = vtop->c.i;
if (c == (char)c) { if (c == (char)c) {
/* generate inc and dec for smaller code */ /* generate inc and dec for smaller code */
if (c==1 && opc==0) { if (c==1 && opc==0 && op != TOK_ADDC1) {
o (0x40 | r); // inc o (0x40 | r); // inc
} else if (c==1 && opc==5) { } else if (c==1 && opc==5 && op != TOK_SUBC1) {
o (0x48 | r); // dec o (0x48 | r); // dec
} else { } else {
o(0x83); o(0x83);

View File

@ -1209,19 +1209,25 @@ static int reg_fret(int t)
return REG_FRET; return REG_FRET;
} }
/* expand long long on stack in two int registers */ /* expand long long on stack in two ints */
static void lexpand(void) static void lexpand(void)
{ {
int u; int u, v;
u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED); u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
gv(RC_INT); v = vtop->r & (VT_VALMASK | VT_LVAL);
vdup(); if (v == VT_CONST) {
vtop[0].r = vtop[-1].r2; vdup();
vtop[0].r2 = VT_CONST; vtop[0].c.i >>= 32;
vtop[-1].r2 = VT_CONST; } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
vtop[0].type.t = VT_INT | u; vdup();
vtop[-1].type.t = VT_INT | u; 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 #ifdef TCC_TARGET_ARM