diff options
| author | grischka <grischka> | 2016-10-16 19:04:40 +0200 |
|---|---|---|
| committer | grischka <grischka> | 2016-10-16 19:04:40 +0200 |
| commit | d9b7f018ce08bdd6b0e35608dbe75ba933622d92 (patch) | |
| tree | c2e5f22444a9cf1785ab6a551ce729c0254dd4ee /tccgen.c | |
| parent | 6245db9fca4046e568da41c6a1f8c51ee9e2f56c (diff) | |
| download | tinycc-d9b7f018ce08bdd6b0e35608dbe75ba933622d92.tar.gz tinycc-d9b7f018ce08bdd6b0e35608dbe75ba933622d92.tar.bz2 | |
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.
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 26 |
1 files changed, 16 insertions, 10 deletions
@@ -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 |
